1 1.1 mrg /* Test file for mpfr_exp2m1. 2 1.1 mrg 3 1.1 mrg Copyright 2001-2023 Free Software Foundation, Inc. 4 1.1 mrg Contributed by the AriC and Caramba projects, INRIA. 5 1.1 mrg 6 1.1 mrg This file is part of the GNU MPFR Library. 7 1.1 mrg 8 1.1 mrg The GNU MPFR Library is free software; you can redistribute it and/or modify 9 1.1 mrg it under the terms of the GNU Lesser General Public License as published by 10 1.1 mrg the Free Software Foundation; either version 3 of the License, or (at your 11 1.1 mrg option) any later version. 12 1.1 mrg 13 1.1 mrg The GNU MPFR Library is distributed in the hope that it will be useful, but 14 1.1 mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15 1.1 mrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 16 1.1 mrg License for more details. 17 1.1 mrg 18 1.1 mrg You should have received a copy of the GNU Lesser General Public License 19 1.1 mrg along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see 20 1.1 mrg https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., 21 1.1 mrg 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ 22 1.1 mrg 23 1.1 mrg #include "mpfr-test.h" 24 1.1 mrg 25 1.1 mrg #define TEST_FUNCTION mpfr_exp2m1 26 1.1 mrg #define TEST_RANDOM_EMIN -36 27 1.1 mrg #define TEST_RANDOM_EMAX 36 28 1.1 mrg #include "tgeneric.c" 29 1.1 mrg 30 1.1 mrg static void 31 1.1 mrg special (void) 32 1.1 mrg { 33 1.1 mrg mpfr_t x, y; 34 1.1 mrg int i; 35 1.1 mrg 36 1.1 mrg mpfr_init2 (x, 2); 37 1.1 mrg mpfr_init2 (y, 2); 38 1.1 mrg 39 1.1 mrg mpfr_set_nan (x); 40 1.1 mrg mpfr_exp2m1 (y, x, MPFR_RNDN); 41 1.1 mrg if (!mpfr_nan_p (y)) 42 1.1 mrg { 43 1.1 mrg printf ("Error for exp2m1(NaN)\n"); 44 1.1 mrg exit (1); 45 1.1 mrg } 46 1.1 mrg 47 1.1 mrg mpfr_set_inf (x, 1); 48 1.1 mrg mpfr_exp2m1 (y, x, MPFR_RNDN); 49 1.1 mrg if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) 50 1.1 mrg { 51 1.1 mrg printf ("Error for exp2m1(+Inf)\n"); 52 1.1 mrg exit (1); 53 1.1 mrg } 54 1.1 mrg 55 1.1 mrg mpfr_set_inf (x, -1); 56 1.1 mrg mpfr_exp2m1 (y, x, MPFR_RNDN); 57 1.1 mrg if (mpfr_cmp_si (y, -1) != 0) 58 1.1 mrg { 59 1.1 mrg printf ("Error for exp2m1(-Inf)\n"); 60 1.1 mrg exit (1); 61 1.1 mrg } 62 1.1 mrg 63 1.1 mrg mpfr_set_ui (x, 0, MPFR_RNDN); 64 1.1 mrg mpfr_exp2m1 (y, x, MPFR_RNDN); 65 1.1 mrg if (MPFR_NOTZERO (y) || MPFR_IS_NEG (y)) 66 1.1 mrg { 67 1.1 mrg printf ("Error for exp2m1(+0)\n"); 68 1.1 mrg exit (1); 69 1.1 mrg } 70 1.1 mrg 71 1.1 mrg mpfr_neg (x, x, MPFR_RNDN); 72 1.1 mrg mpfr_exp2m1 (y, x, MPFR_RNDN); 73 1.1 mrg if (MPFR_NOTZERO (y) || MPFR_IS_POS (y)) 74 1.1 mrg { 75 1.1 mrg printf ("Error for exp2m1(-0)\n"); 76 1.1 mrg exit (1); 77 1.1 mrg } 78 1.1 mrg 79 1.1 mrg /* Check overflow of exp2m1(x) */ 80 1.1 mrg mpfr_clear_flags (); 81 1.1 mrg mpfr_set_str_binary (x, "1.1E1000000000"); 82 1.1 mrg i = mpfr_exp2m1 (x, x, MPFR_RNDN); 83 1.1 mrg MPFR_ASSERTN (MPFR_IS_INF (x) && MPFR_IS_POS (x)); 84 1.1 mrg MPFR_ASSERTN (mpfr_overflow_p ()); 85 1.1 mrg MPFR_ASSERTN (i > 0); 86 1.1 mrg 87 1.1 mrg mpfr_clear_flags (); 88 1.1 mrg mpfr_set_str_binary (x, "1.1E1000000000"); 89 1.1 mrg i = mpfr_exp2m1 (x, x, MPFR_RNDU); 90 1.1 mrg MPFR_ASSERTN (MPFR_IS_INF (x) && MPFR_IS_POS (x)); 91 1.1 mrg MPFR_ASSERTN (mpfr_overflow_p ()); 92 1.1 mrg MPFR_ASSERTN (i > 0); 93 1.1 mrg 94 1.1 mrg mpfr_clear_flags (); 95 1.1 mrg mpfr_set_str_binary (x, "1.1E1000000000"); 96 1.1 mrg i = mpfr_exp2m1 (x, x, MPFR_RNDD); 97 1.1 mrg MPFR_ASSERTN (!MPFR_IS_INF (x) && MPFR_IS_POS (x)); 98 1.1 mrg MPFR_ASSERTN (mpfr_overflow_p ()); 99 1.1 mrg MPFR_ASSERTN (i < 0); 100 1.1 mrg 101 1.1 mrg /* Check internal underflow of exp2m1 (x) */ 102 1.1 mrg mpfr_set_prec (x, 2); 103 1.1 mrg mpfr_clear_flags (); 104 1.1 mrg mpfr_set_str_binary (x, "-1.1E1000000000"); 105 1.1 mrg i = mpfr_exp2m1 (x, x, MPFR_RNDN); 106 1.1 mrg MPFR_ASSERTN (mpfr_cmp_si (x, -1) == 0); 107 1.1 mrg MPFR_ASSERTN (!mpfr_overflow_p () && !mpfr_underflow_p ()); 108 1.1 mrg MPFR_ASSERTN (i < 0); 109 1.1 mrg 110 1.1 mrg mpfr_set_str_binary (x, "-1.1E1000000000"); 111 1.1 mrg i = mpfr_exp2m1 (x, x, MPFR_RNDD); 112 1.1 mrg MPFR_ASSERTN (mpfr_cmp_si (x, -1) == 0); 113 1.1 mrg MPFR_ASSERTN (!mpfr_overflow_p () && !mpfr_underflow_p ()); 114 1.1 mrg MPFR_ASSERTN (i < 0); 115 1.1 mrg 116 1.1 mrg mpfr_set_str_binary (x, "-1.1E1000000000"); 117 1.1 mrg i = mpfr_exp2m1 (x, x, MPFR_RNDZ); 118 1.1 mrg MPFR_ASSERTN (mpfr_cmp_str (x, "-0.11", 2, MPFR_RNDN) == 0); 119 1.1 mrg MPFR_ASSERTN (!mpfr_overflow_p () && !mpfr_underflow_p ()); 120 1.1 mrg MPFR_ASSERTN (i > 0); 121 1.1 mrg 122 1.1 mrg mpfr_set_str_binary (x, "-1.1E1000000000"); 123 1.1 mrg i = mpfr_exp2m1 (x, x, MPFR_RNDU); 124 1.1 mrg MPFR_ASSERTN (mpfr_cmp_str (x, "-0.11", 2, MPFR_RNDN) == 0); 125 1.1 mrg MPFR_ASSERTN (!mpfr_overflow_p () && !mpfr_underflow_p ()); 126 1.1 mrg MPFR_ASSERTN (i > 0); 127 1.1 mrg 128 1.1 mrg /* hard-coded test */ 129 1.1 mrg mpfr_set_prec (x, 32); 130 1.1 mrg mpfr_set_prec (y, 32); 131 1.1 mrg mpfr_set_ui_2exp (x, 1686629713UL, -29, MPFR_RNDN); /* approximates Pi */ 132 1.1 mrg i = mpfr_exp2m1 (y, x, MPFR_RNDN); 133 1.1 mrg MPFR_ASSERTN (mpfr_cmp_ui_2exp (y, 2100501491UL, -28) == 0); 134 1.1 mrg MPFR_ASSERTN (i < 0); 135 1.1 mrg 136 1.1 mrg mpfr_clear (x); 137 1.1 mrg mpfr_clear (y); 138 1.1 mrg } 139 1.1 mrg 140 1.1 mrg /* test integer x, -100 <= x <= 100, where 2^x-1 is exact */ 141 1.1 mrg static void 142 1.1 mrg test_exact (void) 143 1.1 mrg { 144 1.1 mrg long k; 145 1.1 mrg mpfr_t x, y, z; 146 1.1 mrg mpz_t n; 147 1.1 mrg mpfr_prec_t p; 148 1.1 mrg int i, j, r; 149 1.1 mrg 150 1.1 mrg mpfr_init2 (x, 7); /* 100 is exact within 7 bits */ 151 1.1 mrg mpfr_init2 (y, MPFR_PREC_MIN); 152 1.1 mrg mpfr_init2 (z, MPFR_PREC_MIN); 153 1.1 mrg mpz_init_set_ui (n, 1); 154 1.1 mrg for (k = 1; k <= 100; k++) 155 1.1 mrg { 156 1.1 mrg /* invariant: n = 2^k-1 */ 157 1.1 mrg for (p = MPFR_PREC_MIN; p <= 100; p++) 158 1.1 mrg { 159 1.1 mrg mpfr_set_prec (y, p); 160 1.1 mrg mpfr_set_prec (z, p); 161 1.1 mrg mpfr_set_si (x, k, MPFR_RNDN); 162 1.1 mrg /* for RNDF, result may differ */ 163 1.1 mrg RND_LOOP_NO_RNDF(r) 164 1.1 mrg { 165 1.1 mrg i = mpfr_exp2m1 (y, x, (mpfr_rnd_t) r); 166 1.1 mrg j = mpfr_set_z (z, n, (mpfr_rnd_t) r); 167 1.1 mrg if (!mpfr_equal_p (y, z)) 168 1.1 mrg { 169 1.1 mrg printf ("Error for mpfr_exp2m1, x=%ld, rnd=%s\n", k, 170 1.1 mrg mpfr_print_rnd_mode ((mpfr_rnd_t) r)); 171 1.1 mrg printf ("expected "); mpfr_dump (z); 172 1.1 mrg printf ("got "); mpfr_dump (y); 173 1.1 mrg exit (1); 174 1.1 mrg } 175 1.1 mrg if ((i == 0 && j != 0) || (i != 0 && j == 0) || (i * j < 0)) 176 1.1 mrg { 177 1.1 mrg printf ("Bar ternary value for mpfr_exp2m1, x=%ld, rnd=%s\n", 178 1.1 mrg k, mpfr_print_rnd_mode ((mpfr_rnd_t) r)); 179 1.1 mrg printf ("expected %d\n", j); 180 1.1 mrg printf ("got %d\n", i); 181 1.1 mrg exit (1); 182 1.1 mrg } 183 1.1 mrg } 184 1.1 mrg mpfr_set_si (x, -k, MPFR_RNDN); 185 1.1 mrg /* 1/2^k-1 = (1-2^k)/2^k = -n/2^k */ 186 1.1 mrg RND_LOOP_NO_RNDF(r) 187 1.1 mrg { 188 1.1 mrg i = mpfr_exp2m1 (y, x, (mpfr_rnd_t) r); 189 1.1 mrg j = mpfr_set_z (z, n, MPFR_INVERT_RND((mpfr_rnd_t) r)); 190 1.1 mrg mpfr_neg (z, z, (mpfr_rnd_t) r); 191 1.1 mrg j = -j; 192 1.1 mrg mpfr_div_2ui (z, z, k, (mpfr_rnd_t) r); 193 1.1 mrg if (!mpfr_equal_p (y, z)) 194 1.1 mrg { 195 1.1 mrg printf ("Error for mpfr_exp2m1, x=%ld, rnd=%s\n", -k, 196 1.1 mrg mpfr_print_rnd_mode ((mpfr_rnd_t) r)); 197 1.1 mrg printf ("expected "); mpfr_dump (z); 198 1.1 mrg printf ("got "); mpfr_dump (y); 199 1.1 mrg exit (1); 200 1.1 mrg } 201 1.1 mrg if ((i == 0 && j != 0) || (i != 0 && j == 0) || (i * j < 0)) 202 1.1 mrg { 203 1.1 mrg printf ("Bar ternary value for mpfr_exp2m1, x=%ld, rnd=%s\n", 204 1.1 mrg -k, mpfr_print_rnd_mode ((mpfr_rnd_t) r)); 205 1.1 mrg printf ("expected %d\n", j); 206 1.1 mrg printf ("got %d\n", i); 207 1.1 mrg exit (1); 208 1.1 mrg } 209 1.1 mrg } 210 1.1 mrg } 211 1.1 mrg mpz_mul_2exp (n, n, 1); 212 1.1 mrg mpz_add_ui (n, n, 1); 213 1.1 mrg } 214 1.1 mrg mpfr_clear (x); 215 1.1 mrg mpfr_clear (y); 216 1.1 mrg mpfr_clear (z); 217 1.1 mrg mpz_clear (n); 218 1.1 mrg } 219 1.1 mrg 220 1.1 mrg int 221 1.1 mrg main (int argc, char *argv[]) 222 1.1 mrg { 223 1.1 mrg tests_start_mpfr (); 224 1.1 mrg 225 1.1 mrg special (); 226 1.1 mrg 227 1.1 mrg test_exact (); 228 1.1 mrg 229 1.1 mrg test_generic (MPFR_PREC_MIN, 100, 100); 230 1.1 mrg 231 1.1 mrg tests_end_mpfr (); 232 1.1 mrg return 0; 233 1.1 mrg } 234