1 /* Check the values of some constants. 2 3 Copyright 2000, 2001, 2002, 2003 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 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 27 const char *ulong_max_def = "defined"; 28 #else 29 const char *ulong_max_def = "not defined"; 30 #endif 31 #ifdef LONG_MAX 32 const char *long_max_def = "defined"; 33 #else 34 const char *long_max_def = "not defined"; 35 #endif 36 37 #ifdef UINT_MAX 38 const char *uint_max_def = "defined"; 39 #else 40 const char *uint_max_def = "not defined"; 41 #endif 42 #ifdef INT_MAX 43 const char *int_max_def = "defined"; 44 #else 45 const char *int_max_def = "not defined"; 46 #endif 47 48 #ifdef USHRT_MAX 49 const char *ushrt_max_def = "defined"; 50 #else 51 const char *ushrt_max_def = "not defined"; 52 #endif 53 #ifdef SHRT_MAX 54 const char *shrt_max_def = "defined"; 55 #else 56 const char *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 206 int 207 main (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