source: trunk/third/gmp/tests/mpz/t-cmp_d.c @ 18191

Revision 18191, 5.6 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18190, which included commits to RCS files with non-trunk default branches.
Line 
1/* Test mpz_cmp_d and mpz_cmpabs_d.
2
3Copyright 2001, 2002 Free Software Foundation, Inc.
4
5This file is part of the GNU MP Library.
6
7The GNU MP Library is free software; you can redistribute it and/or modify
8it under the terms of the GNU Lesser General Public License as published by
9the Free Software Foundation; either version 2.1 of the License, or (at your
10option) any later version.
11
12The GNU MP Library is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15License for more details.
16
17You should have received a copy of the GNU Lesser General Public License
18along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
19the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20MA 02111-1307, USA. */
21
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25
26#include "gmp.h"
27#include "gmp-impl.h"
28#include "tests.h"
29
30
31/* FIXME: Not sure if the tests here are exhaustive.  Ought to try to get
32   each possible exit from mpz_cmp_d (and mpz_cmpabs_d) exercised.  */
33
34
35#define SGN(n)  ((n) > 0 ? 1 : (n) < 0 ? -1 : 0)
36
37
38void
39check_one (const char *name, mpz_srcptr x, double y, int cmp, int cmpabs)
40{
41  int   got;
42
43  got = mpz_cmp_d (x, y);
44  if (SGN(got) != cmp)
45    {
46      int i;
47      printf    ("mpz_cmp_d wrong (from %s)\n", name);
48      printf    ("  got  %d\n", got);
49      printf    ("  want %d\n", cmp);
50    fail:
51      mpz_trace ("  x", x);
52      printf    ("  y %g\n", y);
53      mp_trace_base=-16;
54      mpz_trace ("  x", x);
55      printf    ("  y %A\n", y);
56      printf    ("  y");
57      for (i = 0; i < sizeof(y); i++)
58        printf (" %02X", (unsigned) ((unsigned char *) &y)[i]);
59      printf ("\n");
60      abort ();
61    }
62
63  got = mpz_cmpabs_d (x, y);
64  if (SGN(got) != cmpabs)
65    {
66      printf    ("mpz_cmpabs_d wrong\n");
67      printf    ("  got  %d\n", got);
68      printf    ("  want %d\n", cmpabs);
69      goto fail;
70    }
71}
72
73
74void
75check_data (void)
76{
77  static const struct {
78    const char  *x;
79    double      y;
80    int         cmp, cmpabs;
81
82  } data[] = {
83
84    {  "0",  0.0,  0,  0 },
85
86    {  "1",  0.0,  1,  1 },
87    { "-1",  0.0, -1,  1 },
88
89    {  "0",  1.0, -1, -1 },
90    {  "0", -1.0,  1, -1 },
91
92    {  "0x1000000000000000000000000000000000000000000000000", 0.0,  1, 1 },
93    { "-0x1000000000000000000000000000000000000000000000000", 0.0, -1, 1 },
94
95    {  "0",  1e100, -1, -1 },
96    {  "0", -1e100,  1, -1 },
97
98    {  "2",  1.5,   1,  1 },
99    {  "2", -1.5,   1,  1 },
100    { "-2",  1.5,  -1,  1 },
101    { "-2", -1.5,  -1,  1 },
102  };
103
104  mpz_t  x;
105  int    i;
106
107  mpz_init (x);
108
109  for (i = 0; i < numberof (data); i++)
110    {
111      mpz_set_str_or_abort (x, data[i].x, 0);
112      check_one ("check_data", x, data[i].y, data[i].cmp, data[i].cmpabs);
113    }
114
115  mpz_clear (x);
116}
117
118
119/* Equality of integers with up to 53 bits */
120void
121check_onebits (void)
122{
123  mpz_t   x, x2;
124  double  y;
125  int     i;
126
127  mpz_init_set_ui (x, 0L);
128  mpz_init (x2);
129
130  for (i = 0; i < 512; i++)
131    {
132      mpz_mul_2exp (x, x, 1);
133      mpz_add_ui (x, x, 1L);
134
135      y = mpz_get_d (x);
136      mpz_set_d (x2, y);
137
138      /* stop if any truncation is occurring */
139      if (mpz_cmp (x, x2) != 0)
140        break;
141
142      check_one ("check_onebits", x, y, 0, 0);
143      check_one ("check_onebits", x, -y, 1, 0);
144      mpz_neg (x, x);
145      check_one ("check_onebits", x, y, -1, 0);
146      check_one ("check_onebits", x, -y, 0, 0);
147      mpz_neg (x, x);
148    }
149
150  mpz_clear (x);
151  mpz_clear (x2);
152}
153
154
155/* With the mpz differing by 1, in a limb position possibly below the double */
156void
157check_low_z_one (void)
158{
159  mpz_t          x;
160  double         y;
161  unsigned long  i;
162
163  mpz_init (x);
164
165  /* FIXME: It'd be better to base this on the float format. */
166#ifdef __vax
167#define LIM 127                 /* vax fp numbers have limited range */
168#else
169#define LIM 512
170#endif
171
172  for (i = 1; i < LIM; i++)
173    {
174      mpz_set_ui (x, 1L);
175      mpz_mul_2exp (x, x, i);
176      y = mpz_get_d (x);
177
178      check_one ("check_low_z_one", x, y,   0, 0);
179      check_one ("check_low_z_one", x, -y,  1, 0);
180      mpz_neg (x, x);
181      check_one ("check_low_z_one", x, y,  -1, 0);
182      check_one ("check_low_z_one", x, -y,  0, 0);
183      mpz_neg (x, x);
184
185      mpz_sub_ui (x, x, 1);
186
187      check_one ("check_low_z_one", x, y,  -1, -1);
188      check_one ("check_low_z_one", x, -y,  1, -1);
189      mpz_neg (x, x);
190      check_one ("check_low_z_one", x, y,  -1, -1);
191      check_one ("check_low_z_one", x, -y,  1, -1);
192      mpz_neg (x, x);
193
194      mpz_add_ui (x, x, 2);
195
196      check_one ("check_low_z_one", x, y,   1, 1);
197      check_one ("check_low_z_one", x, -y,  1, 1);
198      mpz_neg (x, x);
199      check_one ("check_low_z_one", x, y,  -1, 1);
200      check_one ("check_low_z_one", x, -y, -1, 1);
201      mpz_neg (x, x);
202    }
203
204  mpz_clear (x);
205}
206
207/* Comparing 1 and 1+2^-n.  "y" is volatile to make gcc store and fetch it,
208   which forces it to a 64-bit double, whereas on x86 it would otherwise
209   remain on the float stack as an 80-bit long double.  */
210void
211check_one_2exp (void)
212{
213  double           e;
214  mpz_t            x;
215  volatile double  y;
216  int              i;
217
218  mpz_init (x);
219
220  e = 1.0;
221  for (i = 0; i < 128; i++)
222    {
223      e /= 2.0;
224      y = 1.0 + e;
225      if (y == 1.0)
226        break;
227
228      mpz_set_ui (x, 1L);
229      check_one ("check_one_2exp", x,  y, -1, -1);
230      check_one ("check_one_2exp", x, -y,  1, -1);
231
232      mpz_set_si (x, -1L);
233      check_one ("check_one_2exp", x,  y, -1, -1);
234      check_one ("check_one_2exp", x, -y,  1, -1);
235    }
236
237  mpz_clear (x);
238}
239
240
241int
242main (int argc, char *argv[])
243{
244  tests_start ();
245
246  check_data ();
247  check_onebits ();
248  check_low_z_one ();
249  check_one_2exp ();
250
251  tests_end ();
252  exit (0);
253}
Note: See TracBrowser for help on using the repository browser.