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