1/* Check the values of some constants.
2
3Copyright 2000, 2001, 2002, 2003 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 3 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.  If not, see http://www.gnu.org/licenses/.  */
19
20#include <stdio.h>
21#include <stdlib.h>
22#include "gmp.h"
23#include "tests.h"
24
25
26#ifdef ULONG_MAX
27char *ulong_max_def = "defined";
28#else
29char *ulong_max_def = "not defined";
30#endif
31#ifdef LONG_MAX
32char *long_max_def = "defined";
33#else
34char *long_max_def = "not defined";
35#endif
36
37#ifdef UINT_MAX
38char *uint_max_def = "defined";
39#else
40char *uint_max_def = "not defined";
41#endif
42#ifdef INT_MAX
43char *int_max_def = "defined";
44#else
45char *int_max_def = "not defined";
46#endif
47
48#ifdef USHRT_MAX
49char *ushrt_max_def = "defined";
50#else
51char *ushrt_max_def = "not defined";
52#endif
53#ifdef SHRT_MAX
54char *shrt_max_def = "defined";
55#else
56char *shrt_max_def = "not defined";
57#endif
58
59#include "gmp-impl.h"
60#include "longlong.h"
61
62
63#ifdef _LONG_LONG_LIMB
64#define LL(l,ll)  ll
65#else
66#define LL(l,ll)  l
67#endif
68
69#if __GMP_MP_SIZE_T_INT
70#define SS(i,l)   i
71#else
72#define SS(i,l)   l
73#endif
74
75
76#define CHECK_LIMB_S(x, xname, y, yname)                \
77  do {                                                  \
78    if ((x) != (y))                                     \
79      {                                                 \
80        printf (LL("%s == %lx, but %s == %lx\n",        \
81                   "%s == %llx, but %s == %llx\n"),     \
82                xname, x, yname, y);                    \
83        error = 1;                                      \
84      }                                                 \
85  } while (0)
86
87#define CHECK_INT_S(x, xname, y, yname)                                 \
88  do {                                                                  \
89    if ((x) != (y))                                                     \
90      {                                                                 \
91        printf ("%s == %d, but %s == %d\n", xname, x, yname, y);        \
92        error = 1;                                                      \
93      }                                                                 \
94  } while (0)
95
96
97
98#define CHECK_CONDITION_S(x, xname)             \
99  do {                                          \
100    if (!(x))                                   \
101      {                                         \
102        printf ("%s is false\n", xname);        \
103        error = 1;                              \
104      }                                         \
105  } while (0)
106
107
108/* How many bits seem to work in the given type. */
109#define CALC_BITS(result, type) \
110  do {                          \
111    type  n = 1;                \
112    result = 0;                 \
113    while (n != 0)              \
114      {                         \
115        n <<= 1;                \
116        result++;               \
117      }                         \
118  } while (0)
119
120#define CHECK_BITS_S(constant, constant_name, type)     \
121  do {                                                  \
122    int   calculated;                                   \
123    CALC_BITS (calculated, type);                       \
124    if (calculated != constant)                         \
125      {                                                 \
126        printf ("%s == %d, but calculated %d\n",        \
127                constant_name, constant, calculated);   \
128        error = 1;                                      \
129      }                                                 \
130  } while (0)
131
132
133#define CHECK_HIGHBIT_S(value, value_name, type, format)        \
134  do {                                                          \
135    type  n = value;                                            \
136    if (n == 0)                                                 \
137      {                                                         \
138        printf ("%s == 0\n", value_name);                       \
139        error = 1;                                              \
140      }                                                         \
141    n <<= 1;                                                    \
142    if (n != 0)                                                 \
143      {                                                         \
144        printf ("%s << 1 = ", value_name);                      \
145        printf (format, n);                                     \
146        printf (" != 0\n");                                     \
147        error = 1;                                              \
148      }                                                         \
149  } while (0)
150
151
152#define CHECK_MAX_S(max_val, max_name, min_val, min_name, type, format) \
153  do {                                                                  \
154    type  maxval = max_val;                                             \
155    type  minval = min_val;                                             \
156    type  n = maxval;                                                   \
157    n++;                                                                \
158    if (n != minval)                                                    \
159      {                                                                 \
160        printf ("%s + 1 = ", max_name);                                 \
161        printf (format, n);                                             \
162        printf (" != %s = ", min_name);                                 \
163        printf (format, minval);                                        \
164        printf ("\n");                                                  \
165        error = 1;                                                      \
166      }                                                                 \
167    if (maxval <= minval)                                               \
168      {                                                                 \
169        printf ("%s = ", max_name);                                     \
170        printf (format, maxval);                                        \
171        printf (" <= %s = ", min_name);                                 \
172        printf (format, minval);                                        \
173        printf ("\n");                                                  \
174        error = 1;                                                      \
175      }                                                                 \
176  } while (0)
177
178
179#if HAVE_STRINGIZE
180#define CHECK_LIMB(x,y)      CHECK_LIMB_S (x, #x, y, #y)
181#define CHECK_INT(x,y)       CHECK_INT_S (x, #x, y, #y)
182#define CHECK_CONDITION(x)   CHECK_CONDITION_S (x, #x)
183#define CHECK_BITS(c,t)      CHECK_BITS_S (c, #c, t)
184#define CHECK_MAX(m,n,t,f)   CHECK_MAX_S (m, #m, n, #n, t, f)
185#define CHECK_HIGHBIT(n,t,f) CHECK_HIGHBIT_S (n, #n, t, f)
186#else
187#define CHECK_LIMB(x,y)      CHECK_LIMB_S (x, "x", y, "y")
188#define CHECK_INT(x,y)       CHECK_INT_S (x, "x", y, "y")
189#define CHECK_CONDITION(x)   CHECK_CONDITION_S (x, "x")
190#define CHECK_BITS(c,t)      CHECK_BITS_S (c, "c", t)
191#define CHECK_MAX(m,n,t,f)   CHECK_MAX_S (m, "m", n, "n", t, f)
192#define CHECK_HIGHBIT(n,t,f) CHECK_HIGHBIT_S (n, "n", t, f)
193#endif
194
195
196/* The tests below marked "Bad!" fail on Cray T90 systems, where int, short
197   and mp_size_t are 48 bits or some such but don't wraparound in a plain
198   twos complement fashion.  In particular,
199
200       INT_HIGHBIT << 1 = 0xFFFFC00000000000 != 0
201       INT_MAX + 1 = 35184372088832 != INT_MIN = -35184372088832
202
203   This is a bit bizarre, but doesn't matter because GMP doesn't rely on any
204   particular overflow behaviour for int or short, only for mp_limb_t.  */
205
206int
207main (int argc, char *argv[])
208{
209  int  error = 0;
210
211  CHECK_INT (BYTES_PER_MP_LIMB, (int) sizeof(mp_limb_t));
212  CHECK_INT (mp_bits_per_limb, GMP_LIMB_BITS);
213
214  CHECK_BITS (GMP_LIMB_BITS, mp_limb_t);
215  CHECK_BITS (BITS_PER_ULONG, unsigned long);
216
217  CHECK_HIGHBIT (GMP_LIMB_HIGHBIT, mp_limb_t,      LL("0x%lX","0x%llX"));
218  CHECK_HIGHBIT (ULONG_HIGHBIT,     unsigned long,  "0x%lX");
219  CHECK_HIGHBIT (UINT_HIGHBIT,      unsigned int,   "0x%X");
220  CHECK_HIGHBIT (USHRT_HIGHBIT,     unsigned short, "0x%hX");
221  CHECK_HIGHBIT (LONG_HIGHBIT,      long,           "0x%lX");
222#if 0 /* Bad! */
223  CHECK_HIGHBIT (INT_HIGHBIT,       int,            "0x%X");
224  CHECK_HIGHBIT (SHRT_HIGHBIT,      short,          "0x%hX");
225#endif
226
227#if 0 /* Bad! */
228  CHECK_MAX (LONG_MAX,      LONG_MIN,      long,           "%ld");
229  CHECK_MAX (INT_MAX,       INT_MIN,       int,            "%d");
230  CHECK_MAX (SHRT_MAX,      SHRT_MIN,      short,          "%hd");
231#endif
232  CHECK_MAX (ULONG_MAX,     0,             unsigned long,  "%lu");
233  CHECK_MAX (UINT_MAX,      0,             unsigned int,   "%u");
234  CHECK_MAX (USHRT_MAX,     0,             unsigned short, "%hu");
235#if 0 /* Bad! */
236  CHECK_MAX (MP_SIZE_T_MAX, MP_SIZE_T_MIN, mp_size_t,      SS("%d","%ld"));
237#endif
238
239  /* UHWtype should have at least enough bits for half a UWtype */
240  {
241    int  bits_per_UWtype, bits_per_UHWtype;
242    CALC_BITS (bits_per_UWtype,  UWtype);
243    CALC_BITS (bits_per_UHWtype, UHWtype);
244    CHECK_CONDITION (2*bits_per_UHWtype >= bits_per_UWtype);
245  }
246
247  ASSERT_ALWAYS_LIMB (MODLIMB_INVERSE_3);
248  {
249    mp_limb_t  modlimb_inverse_3_calc;
250    binvert_limb (modlimb_inverse_3_calc, CNST_LIMB(3));
251    ASSERT_ALWAYS_LIMB (modlimb_inverse_3_calc);
252    CHECK_LIMB (MODLIMB_INVERSE_3, modlimb_inverse_3_calc);
253  }
254  {
255    mp_limb_t  MODLIMB_INVERSE_3_times_3
256      = (MODLIMB_INVERSE_3 * CNST_LIMB(3)) & GMP_NUMB_MASK;
257    CHECK_LIMB (MODLIMB_INVERSE_3_times_3, CNST_LIMB(1));
258  }
259
260  {
261    mp_limb_t  hi, lo;
262    hi = refmpn_umul_ppmm (&lo, GMP_NUMB_CEIL_MAX_DIV3-1,
263                           CNST_LIMB(3) << GMP_NAIL_BITS);
264    if (! (hi < 1))
265      {
266        printf ("GMP_NUMB_CEIL_MAX_DIV3 too big\n");
267        error = 1;
268      }
269    hi = refmpn_umul_ppmm (&lo, GMP_NUMB_CEIL_MAX_DIV3,
270                           CNST_LIMB(3) << GMP_NAIL_BITS);
271    if (! (hi >= 1))
272      {
273        printf ("GMP_NUMB_CEIL_MAX_DIV3 too small\n");
274        error = 1;
275      }
276  }
277
278  {
279    mp_limb_t  hi, lo;
280    hi = refmpn_umul_ppmm (&lo, GMP_NUMB_CEIL_2MAX_DIV3-1,
281                           CNST_LIMB(3) << GMP_NAIL_BITS);
282    if (! (hi < 2))
283      {
284        printf ("GMP_NUMB_CEIL_2MAX_DIV3 too big\n");
285        error = 1;
286      }
287    hi = refmpn_umul_ppmm (&lo, GMP_NUMB_CEIL_2MAX_DIV3,
288                           CNST_LIMB(3) << GMP_NAIL_BITS);
289    if (! (hi >= 2))
290      {
291        printf ("GMP_NUMB_CEIL_2MAX_DIV3 too small\n");
292        error = 1;
293      }
294  }
295
296#ifdef PP_INVERTED
297  {
298    mp_limb_t  pp_inverted_calc;
299    invert_limb (pp_inverted_calc, PP);
300    CHECK_LIMB (PP_INVERTED, pp_inverted_calc);
301  }
302#endif
303
304  if (argc >= 2 || error)
305    {
306      int  bits;
307
308      printf ("\n");
309      printf ("After gmp.h,\n");
310      printf ("  ULONG_MAX  %s\n", ulong_max_def);
311      printf ("  LONG_MAX   %s\n", long_max_def);
312      printf ("  UINT_MAX   %s\n", uint_max_def);
313      printf ("  INT_MAX    %s\n", int_max_def);
314      printf ("  USHRT_MAX  %s\n", ushrt_max_def);
315      printf ("  SHRT_MAX   %s\n", shrt_max_def);
316      printf ("\n");
317
318#ifdef _CRAY
319      printf ("_CRAY is defined, so limits.h is being used\n");
320#endif
321
322      printf ("ULONG_MAX      %lX\n", ULONG_MAX);
323      printf ("ULONG_HIGHBIT  %lX\n", ULONG_HIGHBIT);
324      printf ("LONG_MAX       %lX\n", LONG_MAX);
325      printf ("LONG_MIN       %lX\n", LONG_MIN);
326
327      printf ("UINT_MAX       %X\n", UINT_MAX);
328      printf ("UINT_HIGHBIT   %X\n", UINT_HIGHBIT);
329      printf ("INT_MAX        %X\n", INT_MAX);
330      printf ("INT_MIN        %X\n", INT_MIN);
331
332      printf ("USHRT_MAX      %hX\n", USHRT_MAX);
333      printf ("USHRT_HIGHBIT  %hX\n", USHRT_HIGHBIT);
334      printf ("SHRT_MAX       %hX\n", SHRT_MAX);
335      printf ("SHRT_MIN       %hX\n", SHRT_MIN);
336
337      printf ("\n");
338      printf ("Bits\n");
339      CALC_BITS (bits, long);           printf ("  long           %d\n", bits);
340      CALC_BITS (bits, int);            printf ("  int            %d\n", bits);
341      CALC_BITS (bits, short);          printf ("  short          %d\n", bits);
342      CALC_BITS (bits, unsigned long);  printf ("  unsigned long  %d\n", bits);
343      CALC_BITS (bits, unsigned int);   printf ("  unsigned int   %d\n", bits);
344      CALC_BITS (bits, unsigned short); printf ("  unsigned short %d\n", bits);
345      CALC_BITS (bits, mp_size_t);      printf ("  mp_size_t      %d\n", bits);
346    }
347
348  if (error)
349    abort ();
350
351  exit (0);
352}
353