1 /* Test file for mpfr_custom_* 2 3 Copyright 2005-2018 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 http://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 BUFFER_SIZE 250 26 #define PREC_TESTED 200 27 28 long Buffer[BUFFER_SIZE]; 29 char *stack = (char *) Buffer; 30 long *org = (long *) Buffer; 31 mpfr_prec_t p = PREC_TESTED; 32 33 #define ALIGNED(s) (((s) + sizeof (long) - 1) / sizeof (long) * sizeof (long)) 34 35 static void * 36 new_st (size_t s) 37 { 38 void *p = (void *) stack; 39 40 if (MPFR_UNLIKELY (s > (char *) &Buffer[BUFFER_SIZE] - stack)) 41 { 42 printf ("[INTERNAL TEST ERROR] Stack overflow.\n"); 43 exit (1); 44 } 45 stack += ALIGNED (s); 46 return p; 47 } 48 49 static void 50 reset_stack (void) 51 { 52 stack = (char *) Buffer; 53 } 54 55 /*************************************************************************/ 56 57 /* Alloc a new mpfr_t on the main stack */ 58 static mpfr_ptr 59 new_mpfr (mpfr_prec_t p) 60 { 61 mpfr_ptr x = (mpfr_ptr) new_st (sizeof (mpfr_t)); 62 void *mantissa = new_st (mpfr_custom_get_size (p)); 63 mpfr_custom_init (mantissa, p); 64 mpfr_custom_init_set (x, 0, 0, p, mantissa); 65 return x; 66 } 67 68 /* Alloc a new mpfr_t on the main stack */ 69 static mpfr_ptr 70 new_nan (mpfr_prec_t p) 71 { 72 mpfr_ptr x = (mpfr_ptr) new_st (sizeof (mpfr_t)); 73 void *mantissa = new_st ((mpfr_custom_get_size) (p)); 74 (mpfr_custom_init) (mantissa, p); 75 (mpfr_custom_init_set) (x, MPFR_NAN_KIND, 0, p, mantissa); 76 return x; 77 } 78 79 /* Alloc a new mpfr_t on the main stack */ 80 static mpfr_ptr 81 new_inf (mpfr_prec_t p) 82 { 83 mpfr_ptr x = (mpfr_ptr) new_st (sizeof (mpfr_t)); 84 void *mantissa = new_st ((mpfr_custom_get_size) (p)); 85 (mpfr_custom_init) (mantissa, p); 86 (mpfr_custom_init_set) (x, -MPFR_INF_KIND, 0, p, mantissa); 87 return x; 88 } 89 90 /* Garbage the stack by keeping only x and save it in old_stack */ 91 static mpfr_ptr 92 return_mpfr (mpfr_ptr x, char *old_stack) 93 { 94 void *mantissa = mpfr_custom_get_significand (x); 95 size_t size_mantissa = mpfr_custom_get_size (mpfr_get_prec (x)); 96 mpfr_ptr newx; 97 98 memmove (old_stack, x, sizeof (mpfr_t)); 99 memmove (old_stack + ALIGNED (sizeof (mpfr_t)), mantissa, size_mantissa); 100 newx = (mpfr_ptr) old_stack; 101 mpfr_custom_move (newx, old_stack + ALIGNED (sizeof (mpfr_t))); 102 stack = old_stack + ALIGNED (sizeof (mpfr_t)) + ALIGNED (size_mantissa); 103 return newx; 104 } 105 106 /* Garbage the stack by keeping only x and save it in old_stack */ 107 static mpfr_ptr 108 return_mpfr_func (mpfr_ptr x, char *old_stack) 109 { 110 void *mantissa = (mpfr_custom_get_significand) (x); 111 size_t size_mantissa = (mpfr_custom_get_size) (mpfr_get_prec (x)); 112 mpfr_ptr newx; 113 114 memmove (old_stack, x, sizeof (mpfr_t)); 115 memmove (old_stack + ALIGNED (sizeof (mpfr_t)), mantissa, size_mantissa); 116 newx = (mpfr_ptr) old_stack; 117 (mpfr_custom_move) (newx, old_stack + ALIGNED (sizeof (mpfr_t))); 118 stack = old_stack + ALIGNED (sizeof (mpfr_t)) + ALIGNED (size_mantissa); 119 return newx; 120 } 121 122 /*************************************************************************/ 123 124 static void 125 test1 (void) 126 { 127 mpfr_ptr x, y; 128 129 reset_stack (); 130 org = (long *) stack; 131 132 x = new_mpfr (p); 133 y = new_mpfr (p); 134 mpfr_set_ui (x, 42, MPFR_RNDN); 135 mpfr_set_ui (y, 17, MPFR_RNDN); 136 mpfr_add (y, x, y, MPFR_RNDN); 137 y = return_mpfr (y, (char *) org); 138 if ((long *) y != org || mpfr_cmp_ui (y, 59) != 0) 139 { 140 printf ("Compact (1) failed!\n"); 141 exit (1); 142 } 143 144 x = new_mpfr (p); 145 y = new_mpfr (p); 146 mpfr_set_ui (x, 4217, MPFR_RNDN); 147 mpfr_set_ui (y, 1742, MPFR_RNDN); 148 mpfr_add (y, x, y, MPFR_RNDN); 149 y = return_mpfr_func (y, (char *) org); 150 if ((long *) y != org || mpfr_cmp_ui (y, 5959) != 0) 151 { 152 printf ("Compact (5) failed!\n"); 153 exit (1); 154 } 155 156 reset_stack (); 157 } 158 159 static void 160 test_nan_inf_zero (void) 161 { 162 mpfr_ptr val; 163 int sign; 164 int kind; 165 166 reset_stack (); 167 168 val = new_mpfr (MPFR_PREC_MIN); 169 mpfr_set_nan (val); 170 kind = (mpfr_custom_get_kind) (val); 171 if (kind != MPFR_NAN_KIND) 172 { 173 printf ("mpfr_custom_get_kind error: "); 174 mpfr_dump (val); 175 printf (" is kind %d instead of %d\n", kind, (int) MPFR_NAN_KIND); 176 exit (1); 177 } 178 179 val = new_nan (MPFR_PREC_MIN); 180 if (!mpfr_nan_p(val)) 181 { 182 printf ("Error: mpfr_custom_init_set doesn't set NAN mpfr.\n"); 183 exit (1); 184 } 185 186 val = new_inf (MPFR_PREC_MIN); 187 if (!mpfr_inf_p(val) || mpfr_sgn(val) >= 0) 188 { 189 printf ("Error: mpfr_custom_init_set doesn't set -INF mpfr.\n"); 190 exit (1); 191 } 192 193 sign = 1; 194 mpfr_set_inf (val, sign); 195 kind = (mpfr_custom_get_kind) (val); 196 if ((ABS (kind) != MPFR_INF_KIND) || (VSIGN (kind) != VSIGN (sign))) 197 { 198 printf ("mpfr_custom_get_kind error: "); 199 mpfr_dump (val); 200 printf (" is kind %d instead of %d\n", kind, (int) MPFR_INF_KIND); 201 printf (" have sign %d instead of %d\n", VSIGN (kind), VSIGN (sign)); 202 exit (1); 203 } 204 205 sign = -1; 206 mpfr_set_zero (val, sign); 207 kind = (mpfr_custom_get_kind) (val); 208 if ((ABS (kind) != MPFR_ZERO_KIND) || (VSIGN (kind) != VSIGN (sign))) 209 { 210 printf ("mpfr_custom_get_kind error: "); 211 mpfr_dump (val); 212 printf (" is kind %d instead of %d\n", kind, (int) MPFR_ZERO_KIND); 213 printf (" have sign %d instead of %d\n", VSIGN (kind), VSIGN (sign)); 214 exit (1); 215 } 216 217 reset_stack (); 218 } 219 220 /*************************************************************************/ 221 222 /* We build the MPFR variable each time it is needed */ 223 /* a[0] is the kind, a[1] is the exponent, &a[2] is the mantissa */ 224 static long * 225 dummy_new (void) 226 { 227 long *r; 228 229 r = (long *) new_st (ALIGNED (2 * sizeof (long)) + 230 ALIGNED (mpfr_custom_get_size (p))); 231 (mpfr_custom_init) (&r[2], p); 232 r[0] = (int) MPFR_NAN_KIND; 233 r[1] = 0; 234 return r; 235 } 236 237 static long * 238 dummy_set_si (long si) 239 { 240 mpfr_t x; 241 long * r = dummy_new (); 242 (mpfr_custom_init_set) (x, MPFR_REGULAR_KIND, 0, p, &r[2]); 243 mpfr_set_si (x, si, MPFR_RNDN); 244 r[0] = mpfr_custom_get_kind (x); 245 r[1] = mpfr_custom_get_exp (x); 246 return r; 247 } 248 249 static long * 250 dummy_add (long *a, long *b) 251 { 252 mpfr_t x, y, z; 253 long *r = dummy_new (); 254 mpfr_custom_init_set (x, 0 + MPFR_REGULAR_KIND, 0, p, &r[2]); 255 (mpfr_custom_init_set) (y, a[0], a[1], p, &a[2]); 256 mpfr_custom_init_set (z, 0 + b[0], b[1], p, &b[2]); 257 mpfr_add (x, y, z, MPFR_RNDN); 258 r[0] = (mpfr_custom_get_kind) (x); 259 r[1] = (mpfr_custom_get_exp) (x); 260 return r; 261 } 262 263 static long * 264 dummy_compact (long *r, long *org_stack) 265 { 266 memmove (org_stack, r, 267 ALIGNED (2*sizeof (long)) + ALIGNED ((mpfr_custom_get_size) (p))); 268 return org_stack; 269 } 270 271 /*************************************************************************/ 272 273 static void 274 test2 (void) 275 { 276 mpfr_t x; 277 long *a, *b, *c; 278 279 reset_stack (); 280 org = (long *) stack; 281 282 a = dummy_set_si (42); 283 b = dummy_set_si (17); 284 c = dummy_add (a, b); 285 c = dummy_compact (c, org); 286 (mpfr_custom_init_set) (x, c[0], c[1], p, &c[2]); 287 if (c != org || mpfr_cmp_ui (x, 59) != 0) 288 { 289 printf ("Compact (2) failed! c=%p a=%p\n", (void *) c, (void *) a); 290 mpfr_dump (x); 291 exit (1); 292 } 293 294 a = dummy_set_si (42); 295 b = dummy_set_si (-17); 296 c = dummy_add (a, b); 297 c = dummy_compact (c, org); 298 (mpfr_custom_init_set) (x, c[0], c[1], p, &c[2]); 299 if (c != org || mpfr_cmp_ui (x, 25) != 0) 300 { 301 printf ("Compact (6) failed! c=%p a=%p\n", (void *) c, (void *) a); 302 mpfr_dump (x); 303 exit (1); 304 } 305 306 reset_stack (); 307 } 308 309 310 int 311 main (void) 312 { 313 tests_start_mpfr (); 314 /* We test iff long = mp_limb_t */ 315 if (sizeof (long) == sizeof (mp_limb_t)) 316 { 317 test1 (); 318 test2 (); 319 test_nan_inf_zero (); 320 } 321 tests_end_mpfr (); 322 return 0; 323 } 324