xref: /netbsd-src/external/lgpl3/gmp/dist/mini-gmp/tests/t-double.c (revision fdd524d4ccd2bb0c6f67401e938dabf773eb0372)
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