151c586b8Smrg /* Check the values of some constants.
251c586b8Smrg
3ce543368Smrg Copyright 2000-2003, 2014 Free Software Foundation, Inc.
451c586b8Smrg
5dab47db4Smrg This file is part of the GNU MP Library test suite.
651c586b8Smrg
7dab47db4Smrg The GNU MP Library test suite is free software; you can redistribute it
8dab47db4Smrg and/or modify it under the terms of the GNU General Public License as
9dab47db4Smrg published by the Free Software Foundation; either version 3 of the License,
10dab47db4Smrg or (at your option) any later version.
1151c586b8Smrg
12dab47db4Smrg The GNU MP Library test suite is distributed in the hope that it will be
13dab47db4Smrg useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14dab47db4Smrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15dab47db4Smrg Public License for more details.
1651c586b8Smrg
17dab47db4Smrg You should have received a copy of the GNU General Public License along with
18ce543368Smrg the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */
1951c586b8Smrg
2051c586b8Smrg #include <stdio.h>
2151c586b8Smrg #include <stdlib.h>
22*72c7faa4Smrg #include "gmp-impl.h"
2351c586b8Smrg #include "tests.h"
2451c586b8Smrg
2551c586b8Smrg
2651c586b8Smrg #ifdef ULONG_MAX
27dab47db4Smrg const char *ulong_max_def = "defined";
2851c586b8Smrg #else
29dab47db4Smrg const char *ulong_max_def = "not defined";
3051c586b8Smrg #endif
3151c586b8Smrg #ifdef LONG_MAX
32dab47db4Smrg const char *long_max_def = "defined";
3351c586b8Smrg #else
34dab47db4Smrg const char *long_max_def = "not defined";
3551c586b8Smrg #endif
3651c586b8Smrg
3751c586b8Smrg #ifdef UINT_MAX
38dab47db4Smrg const char *uint_max_def = "defined";
3951c586b8Smrg #else
40dab47db4Smrg const char *uint_max_def = "not defined";
4151c586b8Smrg #endif
4251c586b8Smrg #ifdef INT_MAX
43dab47db4Smrg const char *int_max_def = "defined";
4451c586b8Smrg #else
45dab47db4Smrg const char *int_max_def = "not defined";
4651c586b8Smrg #endif
4751c586b8Smrg
4851c586b8Smrg #ifdef USHRT_MAX
49dab47db4Smrg const char *ushrt_max_def = "defined";
5051c586b8Smrg #else
51dab47db4Smrg const char *ushrt_max_def = "not defined";
5251c586b8Smrg #endif
5351c586b8Smrg #ifdef SHRT_MAX
54dab47db4Smrg const char *shrt_max_def = "defined";
5551c586b8Smrg #else
56dab47db4Smrg const char *shrt_max_def = "not defined";
5751c586b8Smrg #endif
5851c586b8Smrg
5951c586b8Smrg #include "gmp-impl.h"
6051c586b8Smrg #include "longlong.h"
6151c586b8Smrg
6251c586b8Smrg
6351c586b8Smrg #ifdef _LONG_LONG_LIMB
6451c586b8Smrg #define LL(l,ll) ll
6551c586b8Smrg #else
6651c586b8Smrg #define LL(l,ll) l
6751c586b8Smrg #endif
6851c586b8Smrg
6951c586b8Smrg #if __GMP_MP_SIZE_T_INT
7051c586b8Smrg #define SS(i,l) i
7151c586b8Smrg #else
7251c586b8Smrg #define SS(i,l) l
7351c586b8Smrg #endif
7451c586b8Smrg
7551c586b8Smrg
7651c586b8Smrg #define CHECK_LIMB_S(x, xname, y, yname) \
7751c586b8Smrg do { \
7851c586b8Smrg if ((x) != (y)) \
7951c586b8Smrg { \
8051c586b8Smrg printf (LL("%s == %lx, but %s == %lx\n", \
8151c586b8Smrg "%s == %llx, but %s == %llx\n"), \
8251c586b8Smrg xname, x, yname, y); \
8351c586b8Smrg error = 1; \
8451c586b8Smrg } \
8551c586b8Smrg } while (0)
8651c586b8Smrg
8751c586b8Smrg #define CHECK_INT_S(x, xname, y, yname) \
8851c586b8Smrg do { \
8951c586b8Smrg if ((x) != (y)) \
9051c586b8Smrg { \
9151c586b8Smrg printf ("%s == %d, but %s == %d\n", xname, x, yname, y); \
9251c586b8Smrg error = 1; \
9351c586b8Smrg } \
9451c586b8Smrg } while (0)
9551c586b8Smrg
9651c586b8Smrg
9751c586b8Smrg
9851c586b8Smrg #define CHECK_CONDITION_S(x, xname) \
9951c586b8Smrg do { \
10051c586b8Smrg if (!(x)) \
10151c586b8Smrg { \
10251c586b8Smrg printf ("%s is false\n", xname); \
10351c586b8Smrg error = 1; \
10451c586b8Smrg } \
10551c586b8Smrg } while (0)
10651c586b8Smrg
10751c586b8Smrg
10851c586b8Smrg /* How many bits seem to work in the given type. */
10951c586b8Smrg #define CALC_BITS(result, type) \
11051c586b8Smrg do { \
11151c586b8Smrg type n = 1; \
11251c586b8Smrg result = 0; \
11351c586b8Smrg while (n != 0) \
11451c586b8Smrg { \
11551c586b8Smrg n <<= 1; \
11651c586b8Smrg result++; \
11751c586b8Smrg } \
11851c586b8Smrg } while (0)
11951c586b8Smrg
12051c586b8Smrg #define CHECK_BITS_S(constant, constant_name, type) \
12151c586b8Smrg do { \
12251c586b8Smrg int calculated; \
12351c586b8Smrg CALC_BITS (calculated, type); \
12451c586b8Smrg if (calculated != constant) \
12551c586b8Smrg { \
12651c586b8Smrg printf ("%s == %d, but calculated %d\n", \
12751c586b8Smrg constant_name, constant, calculated); \
12851c586b8Smrg error = 1; \
12951c586b8Smrg } \
13051c586b8Smrg } while (0)
13151c586b8Smrg
13251c586b8Smrg
13351c586b8Smrg #define CHECK_HIGHBIT_S(value, value_name, type, format) \
13451c586b8Smrg do { \
13551c586b8Smrg type n = value; \
13651c586b8Smrg if (n == 0) \
13751c586b8Smrg { \
13851c586b8Smrg printf ("%s == 0\n", value_name); \
13951c586b8Smrg error = 1; \
14051c586b8Smrg } \
14151c586b8Smrg n <<= 1; \
14251c586b8Smrg if (n != 0) \
14351c586b8Smrg { \
14451c586b8Smrg printf ("%s << 1 = ", value_name); \
14551c586b8Smrg printf (format, n); \
14651c586b8Smrg printf (" != 0\n"); \
14751c586b8Smrg error = 1; \
14851c586b8Smrg } \
14951c586b8Smrg } while (0)
15051c586b8Smrg
15151c586b8Smrg
15251c586b8Smrg #define CHECK_MAX_S(max_val, max_name, min_val, min_name, type, format) \
15351c586b8Smrg do { \
15451c586b8Smrg type maxval = max_val; \
15551c586b8Smrg type minval = min_val; \
15651c586b8Smrg type n = maxval; \
15751c586b8Smrg n++; \
15851c586b8Smrg if (n != minval) \
15951c586b8Smrg { \
16051c586b8Smrg printf ("%s + 1 = ", max_name); \
16151c586b8Smrg printf (format, n); \
16251c586b8Smrg printf (" != %s = ", min_name); \
16351c586b8Smrg printf (format, minval); \
16451c586b8Smrg printf ("\n"); \
16551c586b8Smrg error = 1; \
16651c586b8Smrg } \
16751c586b8Smrg if (maxval <= minval) \
16851c586b8Smrg { \
16951c586b8Smrg printf ("%s = ", max_name); \
17051c586b8Smrg printf (format, maxval); \
17151c586b8Smrg printf (" <= %s = ", min_name); \
17251c586b8Smrg printf (format, minval); \
17351c586b8Smrg printf ("\n"); \
17451c586b8Smrg error = 1; \
17551c586b8Smrg } \
17651c586b8Smrg } while (0)
17751c586b8Smrg
17851c586b8Smrg
17951c586b8Smrg #define CHECK_LIMB(x,y) CHECK_LIMB_S (x, #x, y, #y)
18051c586b8Smrg #define CHECK_INT(x,y) CHECK_INT_S (x, #x, y, #y)
18151c586b8Smrg #define CHECK_CONDITION(x) CHECK_CONDITION_S (x, #x)
18251c586b8Smrg #define CHECK_BITS(c,t) CHECK_BITS_S (c, #c, t)
18351c586b8Smrg #define CHECK_MAX(m,n,t,f) CHECK_MAX_S (m, #m, n, #n, t, f)
18451c586b8Smrg #define CHECK_HIGHBIT(n,t,f) CHECK_HIGHBIT_S (n, #n, t, f)
18551c586b8Smrg
18651c586b8Smrg
18751c586b8Smrg /* The tests below marked "Bad!" fail on Cray T90 systems, where int, short
18851c586b8Smrg and mp_size_t are 48 bits or some such but don't wraparound in a plain
18951c586b8Smrg twos complement fashion. In particular,
19051c586b8Smrg
19151c586b8Smrg INT_HIGHBIT << 1 = 0xFFFFC00000000000 != 0
19251c586b8Smrg INT_MAX + 1 = 35184372088832 != INT_MIN = -35184372088832
19351c586b8Smrg
19451c586b8Smrg This is a bit bizarre, but doesn't matter because GMP doesn't rely on any
19551c586b8Smrg particular overflow behaviour for int or short, only for mp_limb_t. */
19651c586b8Smrg
19751c586b8Smrg int
main(int argc,char * argv[])19851c586b8Smrg main (int argc, char *argv[])
19951c586b8Smrg {
20051c586b8Smrg int error = 0;
20151c586b8Smrg
202ce543368Smrg CHECK_INT (GMP_LIMB_BYTES, (int) sizeof(mp_limb_t));
20351c586b8Smrg CHECK_INT (mp_bits_per_limb, GMP_LIMB_BITS);
20451c586b8Smrg
20551c586b8Smrg CHECK_BITS (GMP_LIMB_BITS, mp_limb_t);
20651c586b8Smrg CHECK_BITS (BITS_PER_ULONG, unsigned long);
20751c586b8Smrg
20851c586b8Smrg CHECK_HIGHBIT (GMP_LIMB_HIGHBIT, mp_limb_t, LL("0x%lX","0x%llX"));
20951c586b8Smrg CHECK_HIGHBIT (ULONG_HIGHBIT, unsigned long, "0x%lX");
21051c586b8Smrg CHECK_HIGHBIT (UINT_HIGHBIT, unsigned int, "0x%X");
21151c586b8Smrg CHECK_HIGHBIT (USHRT_HIGHBIT, unsigned short, "0x%hX");
21251c586b8Smrg #if 0 /* Bad! */
213ce543368Smrg CHECK_HIGHBIT (LONG_HIGHBIT, long, "0x%lX");
21451c586b8Smrg CHECK_HIGHBIT (INT_HIGHBIT, int, "0x%X");
21551c586b8Smrg CHECK_HIGHBIT (SHRT_HIGHBIT, short, "0x%hX");
21651c586b8Smrg #endif
21751c586b8Smrg
21851c586b8Smrg #if 0 /* Bad! */
21951c586b8Smrg CHECK_MAX (LONG_MAX, LONG_MIN, long, "%ld");
22051c586b8Smrg CHECK_MAX (INT_MAX, INT_MIN, int, "%d");
22151c586b8Smrg CHECK_MAX (SHRT_MAX, SHRT_MIN, short, "%hd");
22251c586b8Smrg #endif
22351c586b8Smrg CHECK_MAX (ULONG_MAX, 0, unsigned long, "%lu");
22451c586b8Smrg CHECK_MAX (UINT_MAX, 0, unsigned int, "%u");
22551c586b8Smrg CHECK_MAX (USHRT_MAX, 0, unsigned short, "%hu");
22651c586b8Smrg #if 0 /* Bad! */
22751c586b8Smrg CHECK_MAX (MP_SIZE_T_MAX, MP_SIZE_T_MIN, mp_size_t, SS("%d","%ld"));
22851c586b8Smrg #endif
22951c586b8Smrg
23051c586b8Smrg /* UHWtype should have at least enough bits for half a UWtype */
23151c586b8Smrg {
23251c586b8Smrg int bits_per_UWtype, bits_per_UHWtype;
23351c586b8Smrg CALC_BITS (bits_per_UWtype, UWtype);
23451c586b8Smrg CALC_BITS (bits_per_UHWtype, UHWtype);
23551c586b8Smrg CHECK_CONDITION (2*bits_per_UHWtype >= bits_per_UWtype);
23651c586b8Smrg }
23751c586b8Smrg
23851c586b8Smrg ASSERT_ALWAYS_LIMB (MODLIMB_INVERSE_3);
23951c586b8Smrg {
24051c586b8Smrg mp_limb_t modlimb_inverse_3_calc;
24151c586b8Smrg binvert_limb (modlimb_inverse_3_calc, CNST_LIMB(3));
24251c586b8Smrg ASSERT_ALWAYS_LIMB (modlimb_inverse_3_calc);
24351c586b8Smrg CHECK_LIMB (MODLIMB_INVERSE_3, modlimb_inverse_3_calc);
24451c586b8Smrg }
24551c586b8Smrg {
24651c586b8Smrg mp_limb_t MODLIMB_INVERSE_3_times_3
24751c586b8Smrg = (MODLIMB_INVERSE_3 * CNST_LIMB(3)) & GMP_NUMB_MASK;
24851c586b8Smrg CHECK_LIMB (MODLIMB_INVERSE_3_times_3, CNST_LIMB(1));
24951c586b8Smrg }
25051c586b8Smrg
25151c586b8Smrg {
25251c586b8Smrg mp_limb_t hi, lo;
25351c586b8Smrg hi = refmpn_umul_ppmm (&lo, GMP_NUMB_CEIL_MAX_DIV3-1,
25451c586b8Smrg CNST_LIMB(3) << GMP_NAIL_BITS);
25551c586b8Smrg if (! (hi < 1))
25651c586b8Smrg {
25751c586b8Smrg printf ("GMP_NUMB_CEIL_MAX_DIV3 too big\n");
25851c586b8Smrg error = 1;
25951c586b8Smrg }
26051c586b8Smrg hi = refmpn_umul_ppmm (&lo, GMP_NUMB_CEIL_MAX_DIV3,
26151c586b8Smrg CNST_LIMB(3) << GMP_NAIL_BITS);
26251c586b8Smrg if (! (hi >= 1))
26351c586b8Smrg {
26451c586b8Smrg printf ("GMP_NUMB_CEIL_MAX_DIV3 too small\n");
26551c586b8Smrg error = 1;
26651c586b8Smrg }
26751c586b8Smrg }
26851c586b8Smrg
26951c586b8Smrg {
27051c586b8Smrg mp_limb_t hi, lo;
27151c586b8Smrg hi = refmpn_umul_ppmm (&lo, GMP_NUMB_CEIL_2MAX_DIV3-1,
27251c586b8Smrg CNST_LIMB(3) << GMP_NAIL_BITS);
27351c586b8Smrg if (! (hi < 2))
27451c586b8Smrg {
27551c586b8Smrg printf ("GMP_NUMB_CEIL_2MAX_DIV3 too big\n");
27651c586b8Smrg error = 1;
27751c586b8Smrg }
27851c586b8Smrg hi = refmpn_umul_ppmm (&lo, GMP_NUMB_CEIL_2MAX_DIV3,
27951c586b8Smrg CNST_LIMB(3) << GMP_NAIL_BITS);
28051c586b8Smrg if (! (hi >= 2))
28151c586b8Smrg {
28251c586b8Smrg printf ("GMP_NUMB_CEIL_2MAX_DIV3 too small\n");
28351c586b8Smrg error = 1;
28451c586b8Smrg }
28551c586b8Smrg }
28651c586b8Smrg
28751c586b8Smrg #ifdef PP_INVERTED
28851c586b8Smrg {
28951c586b8Smrg mp_limb_t pp_inverted_calc;
29051c586b8Smrg invert_limb (pp_inverted_calc, PP);
29151c586b8Smrg CHECK_LIMB (PP_INVERTED, pp_inverted_calc);
29251c586b8Smrg }
29351c586b8Smrg #endif
29451c586b8Smrg
29551c586b8Smrg if (argc >= 2 || error)
29651c586b8Smrg {
29751c586b8Smrg int bits;
29851c586b8Smrg
29951c586b8Smrg printf ("\n");
30051c586b8Smrg printf ("After gmp.h,\n");
30151c586b8Smrg printf (" ULONG_MAX %s\n", ulong_max_def);
30251c586b8Smrg printf (" LONG_MAX %s\n", long_max_def);
30351c586b8Smrg printf (" UINT_MAX %s\n", uint_max_def);
30451c586b8Smrg printf (" INT_MAX %s\n", int_max_def);
30551c586b8Smrg printf (" USHRT_MAX %s\n", ushrt_max_def);
30651c586b8Smrg printf (" SHRT_MAX %s\n", shrt_max_def);
30751c586b8Smrg printf ("\n");
30851c586b8Smrg
30951c586b8Smrg #ifdef _CRAY
31051c586b8Smrg printf ("_CRAY is defined, so limits.h is being used\n");
31151c586b8Smrg #endif
31251c586b8Smrg
31351c586b8Smrg printf ("ULONG_MAX %lX\n", ULONG_MAX);
31451c586b8Smrg printf ("ULONG_HIGHBIT %lX\n", ULONG_HIGHBIT);
31551c586b8Smrg printf ("LONG_MAX %lX\n", LONG_MAX);
31651c586b8Smrg printf ("LONG_MIN %lX\n", LONG_MIN);
31751c586b8Smrg
31851c586b8Smrg printf ("UINT_MAX %X\n", UINT_MAX);
31951c586b8Smrg printf ("UINT_HIGHBIT %X\n", UINT_HIGHBIT);
32051c586b8Smrg printf ("INT_MAX %X\n", INT_MAX);
32151c586b8Smrg printf ("INT_MIN %X\n", INT_MIN);
32251c586b8Smrg
323ce543368Smrg printf ("USHRT_MAX %X\n", USHRT_MAX);
324ce543368Smrg printf ("USHRT_HIGHBIT %X\n", USHRT_HIGHBIT);
325ce543368Smrg printf ("SHRT_MAX %X\n", SHRT_MAX);
326ce543368Smrg printf ("SHRT_MIN %X\n", SHRT_MIN);
32751c586b8Smrg
32851c586b8Smrg printf ("\n");
32951c586b8Smrg printf ("Bits\n");
33051c586b8Smrg CALC_BITS (bits, long); printf (" long %d\n", bits);
33151c586b8Smrg CALC_BITS (bits, int); printf (" int %d\n", bits);
33251c586b8Smrg CALC_BITS (bits, short); printf (" short %d\n", bits);
33351c586b8Smrg CALC_BITS (bits, unsigned long); printf (" unsigned long %d\n", bits);
33451c586b8Smrg CALC_BITS (bits, unsigned int); printf (" unsigned int %d\n", bits);
33551c586b8Smrg CALC_BITS (bits, unsigned short); printf (" unsigned short %d\n", bits);
33651c586b8Smrg CALC_BITS (bits, mp_size_t); printf (" mp_size_t %d\n", bits);
33751c586b8Smrg }
33851c586b8Smrg
33951c586b8Smrg if (error)
34051c586b8Smrg abort ();
34151c586b8Smrg
34251c586b8Smrg exit (0);
34351c586b8Smrg }
344