github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/misc.c (about) 1 /* Miscellaneous test program support routines. 2 3 Copyright 2000-2003, 2005, 2013 Free Software Foundation, Inc. 4 5 This file is part of the GNU MP Library test suite. 6 7 The GNU MP Library test suite is free software; you can redistribute it 8 and/or modify it under the terms of the GNU General Public License as 9 published by the Free Software Foundation; either version 3 of the License, 10 or (at your option) any later version. 11 12 The GNU MP Library test suite is distributed in the hope that it will be 13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 15 Public License for more details. 16 17 You should have received a copy of the GNU General Public License along with 18 the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ 19 20 #include "config.h" 21 22 #include <ctype.h> 23 #include <signal.h> 24 #include <stdio.h> 25 #include <stdlib.h> /* for getenv */ 26 #include <string.h> 27 28 #if HAVE_FLOAT_H 29 #include <float.h> /* for DBL_MANT_DIG */ 30 #endif 31 32 #if TIME_WITH_SYS_TIME 33 # include <sys/time.h> /* for struct timeval */ 34 # include <time.h> 35 #else 36 # if HAVE_SYS_TIME_H 37 # include <sys/time.h> 38 # else 39 # include <time.h> 40 # endif 41 #endif 42 43 #include "gmp.h" 44 #include "gmp-impl.h" 45 #include "tests.h" 46 47 48 /* The various tests setups and final checks, collected up together. */ 49 void 50 tests_start (void) 51 { 52 char version[10]; 53 snprintf (version, 10, "%u.%u.%u", 54 __GNU_MP_VERSION, 55 __GNU_MP_VERSION_MINOR, 56 __GNU_MP_VERSION_PATCHLEVEL); 57 58 if (strcmp (gmp_version, version) != 0) 59 { 60 fprintf (stderr, "tests are not linked to the newly compiled library\n"); 61 fprintf (stderr, " local version is: %s\n", version); 62 fprintf (stderr, " linked version is: %s\n", gmp_version); 63 abort (); 64 } 65 66 /* don't buffer, so output is not lost if a test causes a segv etc */ 67 setbuf (stdout, NULL); 68 setbuf (stderr, NULL); 69 70 tests_memory_start (); 71 tests_rand_start (); 72 } 73 void 74 tests_end (void) 75 { 76 tests_rand_end (); 77 tests_memory_end (); 78 } 79 80 81 void 82 tests_rand_start (void) 83 { 84 gmp_randstate_ptr rands; 85 char *perform_seed; 86 unsigned long seed; 87 88 if (__gmp_rands_initialized) 89 { 90 printf ("Please let tests_start() initialize the global __gmp_rands.\n"); 91 printf ("ie. ensure that function is called before the first use of RANDS.\n"); 92 abort (); 93 } 94 95 gmp_randinit_default (__gmp_rands); 96 __gmp_rands_initialized = 1; 97 rands = __gmp_rands; 98 99 perform_seed = getenv ("GMP_CHECK_RANDOMIZE"); 100 if (perform_seed != NULL) 101 { 102 #ifdef HAVE_STRTOUL 103 seed = strtoul (perform_seed, 0, 0); 104 #else 105 /* This will not work right for seeds >= 2^31 on 64-bit machines. 106 Perhaps use atol unconditionally? Is that ubiquitous? */ 107 seed = atoi (perform_seed); 108 #endif 109 if (! (seed == 0 || seed == 1)) 110 { 111 printf ("Re-seeding with GMP_CHECK_RANDOMIZE=%lu\n", seed); 112 gmp_randseed_ui (rands, seed); 113 } 114 else 115 { 116 #if HAVE_GETTIMEOFDAY 117 struct timeval tv; 118 gettimeofday (&tv, NULL); 119 seed = tv.tv_sec ^ ((unsigned long) tv.tv_usec << 12); 120 seed &= 0xffffffff; 121 #else 122 time_t tv; 123 time (&tv); 124 seed = tv; 125 #endif 126 gmp_randseed_ui (rands, seed); 127 printf ("Seed GMP_CHECK_RANDOMIZE=%lu (include this in bug reports)\n", seed); 128 } 129 fflush (stdout); 130 } 131 } 132 void 133 tests_rand_end (void) 134 { 135 RANDS_CLEAR (); 136 } 137 138 139 /* Only used if CPU calling conventions checking is available. */ 140 mp_limb_t (*calling_conventions_function) (ANYARGS); 141 142 143 /* Return p advanced to the next multiple of "align" bytes. "align" must be 144 a power of 2. Care is taken not to assume sizeof(int)==sizeof(pointer). 145 Using "unsigned long" avoids a warning on hpux. */ 146 void * 147 align_pointer (void *p, size_t align) 148 { 149 gmp_intptr_t d; 150 d = ((gmp_intptr_t) p) & (align-1); 151 d = (d != 0 ? align-d : 0); 152 return (void *) (((char *) p) + d); 153 } 154 155 156 /* Note that memory allocated with this function can never be freed, because 157 the start address of the block allocated is lost. */ 158 void * 159 __gmp_allocate_func_aligned (size_t bytes, size_t align) 160 { 161 return align_pointer ((*__gmp_allocate_func) (bytes + align-1), align); 162 } 163 164 165 void * 166 __gmp_allocate_or_reallocate (void *ptr, size_t oldsize, size_t newsize) 167 { 168 if (ptr == NULL) 169 return (*__gmp_allocate_func) (newsize); 170 else 171 return (*__gmp_reallocate_func) (ptr, oldsize, newsize); 172 } 173 174 char * 175 __gmp_allocate_strdup (const char *s) 176 { 177 size_t len; 178 char *t; 179 len = strlen (s); 180 t = (char *) (*__gmp_allocate_func) (len+1); 181 memcpy (t, s, len+1); 182 return t; 183 } 184 185 186 char * 187 strtoupper (char *s_orig) 188 { 189 char *s; 190 for (s = s_orig; *s != '\0'; s++) 191 if (isascii (*s)) 192 *s = toupper (*s); 193 return s_orig; 194 } 195 196 197 void 198 mpz_set_n (mpz_ptr z, mp_srcptr p, mp_size_t size) 199 { 200 ASSERT (size >= 0); 201 MPN_NORMALIZE (p, size); 202 MPZ_REALLOC (z, size); 203 MPN_COPY (PTR(z), p, size); 204 SIZ(z) = size; 205 } 206 207 void 208 mpz_init_set_n (mpz_ptr z, mp_srcptr p, mp_size_t size) 209 { 210 ASSERT (size >= 0); 211 212 MPN_NORMALIZE (p, size); 213 ALLOC(z) = MAX (size, 1); 214 PTR(z) = __GMP_ALLOCATE_FUNC_LIMBS (ALLOC(z)); 215 SIZ(z) = size; 216 MPN_COPY (PTR(z), p, size); 217 } 218 219 220 /* Find least significant limb position where p1,size and p2,size differ. */ 221 mp_size_t 222 mpn_diff_lowest (mp_srcptr p1, mp_srcptr p2, mp_size_t size) 223 { 224 mp_size_t i; 225 226 for (i = 0; i < size; i++) 227 if (p1[i] != p2[i]) 228 return i; 229 230 /* no differences */ 231 return -1; 232 } 233 234 235 /* Find most significant limb position where p1,size and p2,size differ. */ 236 mp_size_t 237 mpn_diff_highest (mp_srcptr p1, mp_srcptr p2, mp_size_t size) 238 { 239 mp_size_t i; 240 241 for (i = size-1; i >= 0; i--) 242 if (p1[i] != p2[i]) 243 return i; 244 245 /* no differences */ 246 return -1; 247 } 248 249 250 /* Find least significant byte position where p1,size and p2,size differ. */ 251 mp_size_t 252 byte_diff_lowest (const void *p1, const void *p2, mp_size_t size) 253 { 254 mp_size_t i; 255 256 for (i = 0; i < size; i++) 257 if (((const char *) p1)[i] != ((const char *) p2)[i]) 258 return i; 259 260 /* no differences */ 261 return -1; 262 } 263 264 265 /* Find most significant limb position where p1,size and p2,size differ. */ 266 mp_size_t 267 byte_diff_highest (const void *p1, const void *p2, mp_size_t size) 268 { 269 mp_size_t i; 270 271 for (i = size-1; i >= 0; i--) 272 if (((const char *) p1)[i] != ((const char *) p2)[i]) 273 return i; 274 275 /* no differences */ 276 return -1; 277 } 278 279 280 void 281 mpz_set_str_or_abort (mpz_ptr z, const char *str, int base) 282 { 283 if (mpz_set_str (z, str, base) != 0) 284 { 285 fprintf (stderr, "ERROR: mpz_set_str failed\n"); 286 fprintf (stderr, " str = \"%s\"\n", str); 287 fprintf (stderr, " base = %d\n", base); 288 abort(); 289 } 290 } 291 292 void 293 mpq_set_str_or_abort (mpq_ptr q, const char *str, int base) 294 { 295 if (mpq_set_str (q, str, base) != 0) 296 { 297 fprintf (stderr, "ERROR: mpq_set_str failed\n"); 298 fprintf (stderr, " str = \"%s\"\n", str); 299 fprintf (stderr, " base = %d\n", base); 300 abort(); 301 } 302 } 303 304 void 305 mpf_set_str_or_abort (mpf_ptr f, const char *str, int base) 306 { 307 if (mpf_set_str (f, str, base) != 0) 308 { 309 fprintf (stderr, "ERROR mpf_set_str failed\n"); 310 fprintf (stderr, " str = \"%s\"\n", str); 311 fprintf (stderr, " base = %d\n", base); 312 abort(); 313 } 314 } 315 316 317 /* Whether the absolute value of z is a power of 2. */ 318 int 319 mpz_pow2abs_p (mpz_srcptr z) 320 { 321 mp_size_t size, i; 322 mp_srcptr ptr; 323 324 size = SIZ (z); 325 if (size == 0) 326 return 0; /* zero is not a power of 2 */ 327 size = ABS (size); 328 329 ptr = PTR (z); 330 for (i = 0; i < size-1; i++) 331 if (ptr[i] != 0) 332 return 0; /* non-zero low limb means not a power of 2 */ 333 334 return POW2_P (ptr[i]); /* high limb power of 2 */ 335 } 336 337 338 /* Exponentially distributed between 0 and 2^nbits-1, meaning the number of 339 bits in the result is uniformly distributed between 0 and nbits-1. 340 341 FIXME: This is not a proper exponential distribution, since the 342 probability function will have a stepped shape due to using a uniform 343 distribution after choosing how many bits. */ 344 345 void 346 mpz_erandomb (mpz_ptr rop, gmp_randstate_t rstate, unsigned long nbits) 347 { 348 mpz_urandomb (rop, rstate, gmp_urandomm_ui (rstate, nbits)); 349 } 350 351 void 352 mpz_erandomb_nonzero (mpz_ptr rop, gmp_randstate_t rstate, unsigned long nbits) 353 { 354 mpz_erandomb (rop, rstate, nbits); 355 if (mpz_sgn (rop) == 0) 356 mpz_set_ui (rop, 1L); 357 } 358 359 void 360 mpz_errandomb (mpz_ptr rop, gmp_randstate_t rstate, unsigned long nbits) 361 { 362 mpz_rrandomb (rop, rstate, gmp_urandomm_ui (rstate, nbits)); 363 } 364 365 void 366 mpz_errandomb_nonzero (mpz_ptr rop, gmp_randstate_t rstate, unsigned long nbits) 367 { 368 mpz_errandomb (rop, rstate, nbits); 369 if (mpz_sgn (rop) == 0) 370 mpz_set_ui (rop, 1L); 371 } 372 373 void 374 mpz_negrandom (mpz_ptr rop, gmp_randstate_t rstate) 375 { 376 mp_limb_t n; 377 _gmp_rand (&n, rstate, 1); 378 if (n != 0) 379 mpz_neg (rop, rop); 380 } 381 382 mp_limb_t 383 urandom (void) 384 { 385 #if GMP_NAIL_BITS == 0 386 mp_limb_t n; 387 _gmp_rand (&n, RANDS, GMP_LIMB_BITS); 388 return n; 389 #else 390 mp_limb_t n[2]; 391 _gmp_rand (n, RANDS, GMP_LIMB_BITS); 392 return n[0] + (n[1] << GMP_NUMB_BITS); 393 #endif 394 } 395 396 397 /* Call (*func)() with various random number generators. */ 398 void 399 call_rand_algs (void (*func) (const char *, gmp_randstate_ptr)) 400 { 401 gmp_randstate_t rstate; 402 mpz_t a; 403 404 mpz_init (a); 405 406 gmp_randinit_default (rstate); 407 (*func) ("gmp_randinit_default", rstate); 408 gmp_randclear (rstate); 409 410 gmp_randinit_mt (rstate); 411 (*func) ("gmp_randinit_mt", rstate); 412 gmp_randclear (rstate); 413 414 gmp_randinit_lc_2exp_size (rstate, 8L); 415 (*func) ("gmp_randinit_lc_2exp_size 8", rstate); 416 gmp_randclear (rstate); 417 418 gmp_randinit_lc_2exp_size (rstate, 16L); 419 (*func) ("gmp_randinit_lc_2exp_size 16", rstate); 420 gmp_randclear (rstate); 421 422 gmp_randinit_lc_2exp_size (rstate, 128L); 423 (*func) ("gmp_randinit_lc_2exp_size 128", rstate); 424 gmp_randclear (rstate); 425 426 /* degenerate always zeros */ 427 mpz_set_ui (a, 0L); 428 gmp_randinit_lc_2exp (rstate, a, 0L, 8L); 429 (*func) ("gmp_randinit_lc_2exp a=0 c=0 m=8", rstate); 430 gmp_randclear (rstate); 431 432 /* degenerate always FFs */ 433 mpz_set_ui (a, 0L); 434 gmp_randinit_lc_2exp (rstate, a, 0xFFL, 8L); 435 (*func) ("gmp_randinit_lc_2exp a=0 c=0xFF m=8", rstate); 436 gmp_randclear (rstate); 437 438 mpz_clear (a); 439 } 440 441 442 /* Return +infinity if available, or 0 if not. 443 We don't want to use libm, so INFINITY or other system values are not 444 used here. */ 445 double 446 tests_infinity_d (void) 447 { 448 #if _GMP_IEEE_FLOATS 449 union ieee_double_extract x; 450 x.s.exp = 2047; 451 x.s.manl = 0; 452 x.s.manh = 0; 453 x.s.sig = 0; 454 return x.d; 455 #else 456 return 0; 457 #endif 458 } 459 460 461 /* Return non-zero if d is an infinity (either positive or negative). 462 Don't want libm, so don't use isinf() or other system tests. */ 463 int 464 tests_isinf (double d) 465 { 466 #if _GMP_IEEE_FLOATS 467 union ieee_double_extract x; 468 x.d = d; 469 return (x.s.exp == 2047 && x.s.manl == 0 && x.s.manh == 0); 470 #else 471 return 0; 472 #endif 473 } 474 475 476 /* Set the hardware floating point rounding mode. Same mode values as mpfr, 477 namely 0=nearest, 1=tozero, 2=up, 3=down. Return 1 if successful, 0 if 478 not. */ 479 int 480 tests_hardware_setround (int mode) 481 { 482 #if ! defined NO_ASM && HAVE_HOST_CPU_FAMILY_x86 483 int rc; 484 switch (mode) { 485 case 0: rc = 0; break; /* nearest */ 486 case 1: rc = 3; break; /* tozero */ 487 case 2: rc = 2; break; /* up */ 488 case 3: rc = 1; break; /* down */ 489 default: 490 return 0; 491 } 492 x86_fldcw ((x86_fstcw () & ~0xC00) | (rc << 10)); 493 return 1; 494 #endif 495 496 return 0; 497 } 498 499 /* Return the hardware floating point rounding mode, or -1 if unknown. */ 500 int 501 tests_hardware_getround (void) 502 { 503 #if ! defined NO_ASM && HAVE_HOST_CPU_FAMILY_x86 504 switch ((x86_fstcw () & ~0xC00) >> 10) { 505 case 0: return 0; break; /* nearest */ 506 case 1: return 3; break; /* down */ 507 case 2: return 2; break; /* up */ 508 case 3: return 1; break; /* tozero */ 509 } 510 #endif 511 512 return -1; 513 } 514 515 516 /* tests_dbl_mant_bits() determines by experiment the number of bits in the 517 mantissa of a "double". If it's not possible to find a value (perhaps 518 due to the compiler optimizing too aggressively), then return 0. 519 520 This code is used rather than DBL_MANT_DIG from <float.h> since ancient 521 systems like SunOS don't have that file, and since one GNU/Linux ARM 522 system was seen where the float emulation seemed to have only 32 working 523 bits, not the 53 float.h claimed. */ 524 525 int 526 tests_dbl_mant_bits (void) 527 { 528 static int n = -1; 529 volatile double x, y, d; 530 531 if (n != -1) 532 return n; 533 534 n = 1; 535 x = 2.0; 536 for (;;) 537 { 538 /* see if 2^(n+1)+1 can be formed without rounding, if so then 539 continue, if not then "n" is the answer */ 540 y = x + 1.0; 541 d = y - x; 542 if (d != 1.0) 543 { 544 #if defined (DBL_MANT_DIG) && DBL_RADIX == 2 545 if (n != DBL_MANT_DIG) 546 printf ("Warning, tests_dbl_mant_bits got %d but DBL_MANT_DIG says %d\n", n, DBL_MANT_DIG); 547 #endif 548 break; 549 } 550 551 x *= 2; 552 n++; 553 554 if (n > 1000) 555 { 556 printf ("Oops, tests_dbl_mant_bits can't determine mantissa size\n"); 557 n = 0; 558 break; 559 } 560 } 561 return n; 562 } 563 564 565 /* See tests_setjmp_sigfpe in tests.h. */ 566 567 jmp_buf tests_sigfpe_target; 568 569 RETSIGTYPE 570 tests_sigfpe_handler (int sig) 571 { 572 longjmp (tests_sigfpe_target, 1); 573 } 574 575 void 576 tests_sigfpe_done (void) 577 { 578 signal (SIGFPE, SIG_DFL); 579 }