github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/mini-gmp/tests/t-double.c (about) 1 /* 2 3 Copyright 2012, 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 <limits.h> 21 #include <math.h> 22 #include <stdlib.h> 23 #include <stdio.h> 24 #include <string.h> 25 26 #include "testutils.h" 27 28 #define GMP_LIMB_BITS (sizeof(mp_limb_t) * CHAR_BIT) 29 30 #define COUNT 10000 31 32 static const struct 33 { 34 double d; 35 const char *s; 36 } values[] = { 37 { 0.0, "0" }, 38 { 0.3, "0" }, 39 { -0.3, "0" }, 40 { M_PI, "3" }, 41 { M_PI*1e15, "b29430a256d21" }, 42 { -M_PI*1e15, "-b29430a256d21" }, 43 /* 17 * 2^{200} = 44 27317946752402834684213355569799764242877450894307478200123392 */ 45 {0.2731794675240283468421335556979976424288e62, 46 "1100000000000000000000000000000000000000000000000000" }, 47 { 0.0, NULL } 48 }; 49 50 void 51 testmain (int argc, char **argv) 52 { 53 unsigned i; 54 mpz_t x; 55 56 for (i = 0; values[i].s; i++) 57 { 58 char *s; 59 mpz_init_set_d (x, values[i].d); 60 s = mpz_get_str (NULL, 16, x); 61 if (strcmp (s, values[i].s) != 0) 62 { 63 fprintf (stderr, "mpz_set_d failed:\n" 64 "d = %.20g\n" 65 "s = %s\n" 66 "r = %s\n", 67 values[i].d, s, values[i].s); 68 abort (); 69 } 70 testfree (s); 71 mpz_clear (x); 72 } 73 74 mpz_init (x); 75 76 for (i = 0; i < COUNT; i++) 77 { 78 /* Use volatile, to avoid extended precision in floating point 79 registers, e.g., on m68k and 80387. */ 80 volatile double d, f; 81 unsigned long m; 82 int e; 83 84 mini_rrandomb (x, GMP_LIMB_BITS); 85 m = mpz_get_ui (x); 86 mini_urandomb (x, 8); 87 e = mpz_get_ui (x) - 100; 88 89 d = ldexp ((double) m, e); 90 mpz_set_d (x, d); 91 f = mpz_get_d (x); 92 if (f != floor (d)) 93 { 94 fprintf (stderr, "mpz_set_d/mpz_get_d failed:\n"); 95 goto dumperror; 96 } 97 if ((f == d) ? (mpz_cmp_d (x, d) != 0) : (mpz_cmp_d (x, d) >= 0)) 98 { 99 fprintf (stderr, "mpz_cmp_d (x, d) failed:\n"); 100 goto dumperror; 101 } 102 f = d + 1.0; 103 if (f > d && ! (mpz_cmp_d (x, f) < 0)) 104 { 105 fprintf (stderr, "mpz_cmp_d (x, f) failed:\n"); 106 goto dumperror; 107 } 108 109 d = - d; 110 111 mpz_set_d (x, d); 112 f = mpz_get_d (x); 113 if (f != ceil (d)) 114 { 115 fprintf (stderr, "mpz_set_d/mpz_get_d failed:\n"); 116 dumperror: 117 dump ("x", x); 118 fprintf (stderr, "m = %lx, e = %i\n", m, e); 119 fprintf (stderr, "d = %.15g\n", d); 120 fprintf (stderr, "f = %.15g\n", f); 121 fprintf (stderr, "f - d = %.5g\n", f - d); 122 abort (); 123 } 124 if ((f == d) ? (mpz_cmp_d (x, d) != 0) : (mpz_cmp_d (x, d) <= 0)) 125 { 126 fprintf (stderr, "mpz_cmp_d (x, d) failed:\n"); 127 goto dumperror; 128 } 129 f = d - 1.0; 130 if (f < d && ! (mpz_cmp_d (x, f) > 0)) 131 { 132 fprintf (stderr, "mpz_cmp_d (x, f) failed:\n"); 133 goto dumperror; 134 } 135 } 136 137 mpz_clear (x); 138 }