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 http://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 void 33 dump (const char *label, const mpz_t x) 34 { 35 char *buf = mpz_get_str (NULL, 16, x); 36 fprintf (stderr, "%s: %s\n", label, buf); 37 testfree (buf); 38 } 39 40 static const struct 41 { 42 double d; 43 const char *s; 44 } values[] = { 45 { 0.0, "0" }, 46 { 0.3, "0" }, 47 { -0.3, "0" }, 48 { M_PI, "3" }, 49 { M_PI*1e15, "b29430a256d21" }, 50 { -M_PI*1e15, "-b29430a256d21" }, 51 /* 17 * 2^{200} = 52 27317946752402834684213355569799764242877450894307478200123392 */ 53 {0.2731794675240283468421335556979976424288e62, 54 "1100000000000000000000000000000000000000000000000000" }, 55 { 0.0, NULL } 56 }; 57 58 void 59 testmain (int argc, char **argv) 60 { 61 unsigned i; 62 mpz_t x; 63 64 for (i = 0; values[i].s; i++) 65 { 66 char *s; 67 mpz_init_set_d (x, values[i].d); 68 s = mpz_get_str (NULL, 16, x); 69 if (strcmp (s, values[i].s) != 0) 70 { 71 fprintf (stderr, "mpz_set_d failed:\n" 72 "d = %.20g\n" 73 "s = %s\n" 74 "r = %s\n", 75 values[i].d, s, values[i].s); 76 abort (); 77 } 78 testfree (s); 79 mpz_clear (x); 80 } 81 82 mpz_init (x); 83 84 for (i = 0; i < COUNT; i++) 85 { 86 /* Use volatile, to avoid extended precision in floating point 87 registers, e.g., on m68k and 80387. */ 88 volatile double d, f; 89 unsigned long m; 90 int e; 91 92 mini_rrandomb (x, GMP_LIMB_BITS); 93 m = mpz_get_ui (x); 94 mini_urandomb (x, 8); 95 e = mpz_get_ui (x) - 100; 96 97 d = ldexp ((double) m, e); 98 mpz_set_d (x, d); 99 f = mpz_get_d (x); 100 if (f != floor (d)) 101 { 102 fprintf (stderr, "mpz_set_d/mpz_get_d failed:\n"); 103 goto dumperror; 104 } 105 if ((f == d) ? (mpz_cmp_d (x, d) != 0) : (mpz_cmp_d (x, d) >= 0)) 106 { 107 fprintf (stderr, "mpz_cmp_d (x, d) failed:\n"); 108 goto dumperror; 109 } 110 f = d + 1.0; 111 if (f > d && ! (mpz_cmp_d (x, f) < 0)) 112 { 113 fprintf (stderr, "mpz_cmp_d (x, f) failed:\n"); 114 goto dumperror; 115 } 116 117 d = - d; 118 119 mpz_set_d (x, d); 120 f = mpz_get_d (x); 121 if (f != ceil (d)) 122 { 123 fprintf (stderr, "mpz_set_d/mpz_get_d failed:\n"); 124 dumperror: 125 dump ("x", x); 126 fprintf (stderr, "m = %lx, e = %i\n", m, e); 127 fprintf (stderr, "d = %.15g\n", d); 128 fprintf (stderr, "f = %.15g\n", f); 129 fprintf (stderr, "f - d = %.5g\n", f - d); 130 abort (); 131 } 132 if ((f == d) ? (mpz_cmp_d (x, d) != 0) : (mpz_cmp_d (x, d) <= 0)) 133 { 134 fprintf (stderr, "mpz_cmp_d (x, d) failed:\n"); 135 goto dumperror; 136 } 137 f = d - 1.0; 138 if (f < d && ! (mpz_cmp_d (x, f) > 0)) 139 { 140 fprintf (stderr, "mpz_cmp_d (x, f) failed:\n"); 141 goto dumperror; 142 } 143 } 144 145 mpz_clear (x); 146 } 147