Imported Upstream version 6.0.0
[platform/upstream/gmp.git] / mini-gmp / tests / t-double.c
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 }