1 /* Test file for mpfr_compound_si. 2 3 Copyright 2021-2023 Free Software Foundation, Inc. 4 Contributed by the AriC and Caramba projects, INRIA. 5 6 This file is part of the GNU MPFR Library. 7 8 The GNU MPFR Library is free software; you can redistribute it and/or modify 9 it under the terms of the GNU Lesser General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or (at your 11 option) any later version. 12 13 The GNU MPFR Library is distributed in the hope that it will be useful, but 14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 16 License for more details. 17 18 You should have received a copy of the GNU Lesser General Public License 19 along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see 20 https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., 21 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ 22 23 #include "mpfr-test.h" 24 25 #define TEST_FUNCTION mpfr_compound_si 26 #define INTEGER_TYPE long 27 #define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS) 28 #define test_generic_ui test_generic_si 29 #include "tgeneric_ui.c" 30 31 /* Special cases from IEEE 754-2019 */ 32 static void 33 check_ieee754 (void) 34 { 35 mpfr_t x, y; 36 long i; 37 long t[] = { 0, 1, 2, 3, 17, LONG_MAX-1, LONG_MAX }; 38 int j; 39 mpfr_prec_t prec = 2; /* we need at least 2 so that 3/4 is exact */ 40 41 mpfr_init2 (x, prec); 42 mpfr_init2 (y, prec); 43 44 /* compound(x,n) = NaN for x < -1, and set invalid exception */ 45 for (i = 0; i < numberof(t); i++) 46 for (j = 0; j < 2; j++) 47 { 48 const char *s; 49 50 mpfr_clear_nanflag (); 51 if (j == 0) 52 { 53 mpfr_set_si (x, -2, MPFR_RNDN); 54 s = "-2"; 55 } 56 else 57 { 58 mpfr_set_inf (x, -1); 59 s = "-Inf"; 60 } 61 mpfr_compound_si (y, x, t[i], MPFR_RNDN); 62 if (!mpfr_nan_p (y)) 63 { 64 printf ("Error, compound(%s,%ld) should give NaN\n", s, t[i]); 65 printf ("got "); mpfr_dump (y); 66 exit (1); 67 } 68 if (!mpfr_nanflag_p ()) 69 { 70 printf ("Error, compound(%s,%ld) should raise invalid flag\n", 71 s, t[i]); 72 exit (1); 73 } 74 } 75 76 /* compound(x,0) = 1 for x >= -1 or x = NaN */ 77 for (i = -2; i <= 2; i++) 78 { 79 if (i == -2) 80 mpfr_set_nan (x); 81 else if (i == 2) 82 mpfr_set_inf (x, 1); 83 else 84 mpfr_set_si (x, i, MPFR_RNDN); 85 mpfr_compound_si (y, x, 0, MPFR_RNDN); 86 if (mpfr_cmp_ui (y, 1) != 0) 87 { 88 printf ("Error, compound(x,0) should give 1 on\nx = "); 89 mpfr_dump (x); 90 printf ("got "); mpfr_dump (y); 91 exit (1); 92 } 93 } 94 95 /* compound(-1,n) = +Inf for n < 0, and raise divide-by-zero flag */ 96 mpfr_clear_divby0 (); 97 mpfr_set_si (x, -1, MPFR_RNDN); 98 mpfr_compound_si (y, x, -1, MPFR_RNDN); 99 if (!mpfr_inf_p (y) || MPFR_SIGN(y) < 0) 100 { 101 printf ("Error, compound(-1,-1) should give +Inf\n"); 102 printf ("got "); mpfr_dump (y); 103 exit (1); 104 } 105 if (!mpfr_divby0_p ()) 106 { 107 printf ("Error, compound(-1,-1) should raise divide-by-zero flag\n"); 108 exit (1); 109 } 110 111 /* compound(-1,n) = +0 for n > 0 */ 112 mpfr_set_si (x, -1, MPFR_RNDN); 113 mpfr_compound_si (y, x, 1, MPFR_RNDN); 114 if (!mpfr_zero_p (y) || MPFR_SIGN(y) < 0) 115 { 116 printf ("Error, compound(-1,1) should give +0\n"); 117 printf ("got "); mpfr_dump (y); 118 exit (1); 119 } 120 121 /* compound(+/-0,n) = 1 */ 122 for (i = -1; i <= 1; i++) 123 { 124 mpfr_set_zero (x, -1); 125 mpfr_compound_si (y, x, i, MPFR_RNDN); 126 if (mpfr_cmp_ui (y, 1) != 0) 127 { 128 printf ("Error1, compound(x,%ld) should give 1\non x = ", i); 129 mpfr_dump (x); 130 printf ("got "); mpfr_dump (y); 131 exit (1); 132 } 133 mpfr_set_zero (x, +1); 134 mpfr_compound_si (y, x, i, MPFR_RNDN); 135 if (mpfr_cmp_ui (y, 1) != 0) 136 { 137 printf ("Error, compound(x,%ld) should give 1\non x = ", i); 138 mpfr_dump (x); 139 printf ("got "); mpfr_dump (y); 140 exit (1); 141 } 142 } 143 144 /* compound(+Inf,n) = +Inf for n > 0 */ 145 mpfr_set_inf (x, 1); 146 mpfr_compound_si (y, x, 1, MPFR_RNDN); 147 if (!mpfr_inf_p (y) || MPFR_SIGN(y) < 0) 148 { 149 printf ("Error, compound(+Inf,1) should give +Inf\n"); 150 printf ("got "); mpfr_dump (y); 151 exit (1); 152 } 153 154 /* compound(+Inf,n) = +0 for n < 0 */ 155 mpfr_set_inf (x, 1); 156 mpfr_compound_si (y, x, -1, MPFR_RNDN); 157 if (!mpfr_zero_p (y) || MPFR_SIGN(y) < 0) 158 { 159 printf ("Error, compound(+Inf,-1) should give +0\n"); 160 printf ("got "); mpfr_dump (y); 161 exit (1); 162 } 163 164 /* compound(NaN,n) = NaN for n <> 0 */ 165 mpfr_set_nan (x); 166 mpfr_compound_si (y, x, -1, MPFR_RNDN); 167 if (!mpfr_nan_p (y)) 168 { 169 printf ("Error, compound(NaN,-1) should give NaN\n"); 170 printf ("got "); mpfr_dump (y); 171 exit (1); 172 } 173 mpfr_compound_si (y, x, +1, MPFR_RNDN); 174 if (!mpfr_nan_p (y)) 175 { 176 printf ("Error, compound(NaN,+1) should give NaN\n"); 177 printf ("got "); mpfr_dump (y); 178 exit (1); 179 } 180 181 /* hard-coded test: x is the 32-bit nearest approximation of 17/42 */ 182 mpfr_set_prec (x, 32); 183 mpfr_set_prec (y, 32); 184 mpfr_set_ui_2exp (x, 3476878287UL, -33, MPFR_RNDN); 185 mpfr_compound_si (y, x, 12, MPFR_RNDN); 186 mpfr_set_ui_2exp (x, 1981447393UL, -25, MPFR_RNDN); 187 if (!mpfr_equal_p (y, x)) 188 { 189 printf ("Error for compound(3476878287/2^33,12)\n"); 190 printf ("expected "); mpfr_dump (x); 191 printf ("got "); mpfr_dump (y); 192 exit (1); 193 } 194 195 /* test for negative n */ 196 i = -1; 197 while (1) 198 { 199 /* i has the form -(2^k-1) */ 200 mpfr_set_si_2exp (x, -1, -1, MPFR_RNDN); /* x = -0.5 */ 201 mpfr_compound_si (y, x, i, MPFR_RNDN); 202 mpfr_set_ui_2exp (x, 1, -i, MPFR_RNDN); 203 if (!mpfr_equal_p (y, x)) 204 { 205 printf ("Error for compound(-0.5,%ld)\n", i); 206 printf ("expected "); mpfr_dump (x); 207 printf ("got "); mpfr_dump (y); 208 exit (1); 209 } 210 if (i == -2147483647) /* largest possible value on 32-bit machine */ 211 break; 212 i = 2 * i - 1; 213 } 214 215 /* The "#if" makes sure that 64-bit constants are supported, avoiding 216 a compilation failure. The "if" makes sure that the constant is 217 representable in a long (this would not be the case with 32-bit 218 unsigned long and 64-bit limb). */ 219 #if GMP_NUMB_BITS >= 64 || MPFR_PREC_BITS >= 64 220 if (4994322635099777669 <= LONG_MAX) 221 { 222 i = -4994322635099777669; 223 mpfr_set_ui (x, 1, MPFR_RNDN); 224 mpfr_compound_si (y, x, i, MPFR_RNDN); 225 mpfr_set_si (x, 1, MPFR_RNDN); 226 mpfr_mul_2si (x, x, i, MPFR_RNDN); 227 if (!mpfr_equal_p (y, x)) 228 { 229 printf ("Error for compound(1,%ld)\n", i); 230 printf ("expected "); mpfr_dump (x); 231 printf ("got "); mpfr_dump (y); 232 exit (1); 233 } 234 } 235 #endif 236 237 mpfr_clear (x); 238 mpfr_clear (y); 239 } 240 241 static int 242 mpfr_compound2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode) 243 { 244 return mpfr_compound_si (y, x, 2, rnd_mode); 245 } 246 247 static int 248 mpfr_compound3 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode) 249 { 250 return mpfr_compound_si (y, x, 3, rnd_mode); 251 } 252 253 #define TEST_FUNCTION mpfr_compound2 254 #define test_generic test_generic_compound2 255 #include "tgeneric.c" 256 257 #define TEST_FUNCTION mpfr_compound3 258 #define test_generic test_generic_compound3 259 #include "tgeneric.c" 260 261 int 262 main (void) 263 { 264 tests_start_mpfr (); 265 266 check_ieee754 (); 267 268 test_generic_si (MPFR_PREC_MIN, 100, 100); 269 270 test_generic_compound2 (MPFR_PREC_MIN, 100, 100); 271 test_generic_compound3 (MPFR_PREC_MIN, 100, 100); 272 273 tests_end_mpfr (); 274 return 0; 275 } 276