1/* Check the values of some constants. 2 3Copyright 2000-2003, 2014 Free Software Foundation, Inc. 4 5This file is part of the GNU MP Library test suite. 6 7The GNU MP Library test suite is free software; you can redistribute it 8and/or modify it under the terms of the GNU General Public License as 9published by the Free Software Foundation; either version 3 of the License, 10or (at your option) any later version. 11 12The GNU MP Library test suite is distributed in the hope that it will be 13useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 15Public License for more details. 16 17You should have received a copy of the GNU General Public License along with 18the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ 19 20#include <stdio.h> 21#include <stdlib.h> 22#include "gmp-impl.h" 23#include "tests.h" 24 25 26#ifdef ULONG_MAX 27const char *ulong_max_def = "defined"; 28#else 29const char *ulong_max_def = "not defined"; 30#endif 31#ifdef LONG_MAX 32const char *long_max_def = "defined"; 33#else 34const char *long_max_def = "not defined"; 35#endif 36 37#ifdef UINT_MAX 38const char *uint_max_def = "defined"; 39#else 40const char *uint_max_def = "not defined"; 41#endif 42#ifdef INT_MAX 43const char *int_max_def = "defined"; 44#else 45const char *int_max_def = "not defined"; 46#endif 47 48#ifdef USHRT_MAX 49const char *ushrt_max_def = "defined"; 50#else 51const char *ushrt_max_def = "not defined"; 52#endif 53#ifdef SHRT_MAX 54const char *shrt_max_def = "defined"; 55#else 56const 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#define CHECK_LIMB(x,y) CHECK_LIMB_S (x, #x, y, #y) 180#define CHECK_INT(x,y) CHECK_INT_S (x, #x, y, #y) 181#define CHECK_CONDITION(x) CHECK_CONDITION_S (x, #x) 182#define CHECK_BITS(c,t) CHECK_BITS_S (c, #c, t) 183#define CHECK_MAX(m,n,t,f) CHECK_MAX_S (m, #m, n, #n, t, f) 184#define CHECK_HIGHBIT(n,t,f) CHECK_HIGHBIT_S (n, #n, t, f) 185 186 187/* The tests below marked "Bad!" fail on Cray T90 systems, where int, short 188 and mp_size_t are 48 bits or some such but don't wraparound in a plain 189 twos complement fashion. In particular, 190 191 INT_HIGHBIT << 1 = 0xFFFFC00000000000 != 0 192 INT_MAX + 1 = 35184372088832 != INT_MIN = -35184372088832 193 194 This is a bit bizarre, but doesn't matter because GMP doesn't rely on any 195 particular overflow behaviour for int or short, only for mp_limb_t. */ 196 197int 198main (int argc, char *argv[]) 199{ 200 int error = 0; 201 202 CHECK_INT (GMP_LIMB_BYTES, (int) sizeof(mp_limb_t)); 203 CHECK_INT (mp_bits_per_limb, GMP_LIMB_BITS); 204 205 CHECK_BITS (GMP_LIMB_BITS, mp_limb_t); 206 CHECK_BITS (BITS_PER_ULONG, unsigned long); 207 208 CHECK_HIGHBIT (GMP_LIMB_HIGHBIT, mp_limb_t, LL("0x%lX","0x%llX")); 209 CHECK_HIGHBIT (ULONG_HIGHBIT, unsigned long, "0x%lX"); 210 CHECK_HIGHBIT (UINT_HIGHBIT, unsigned int, "0x%X"); 211 CHECK_HIGHBIT (USHRT_HIGHBIT, unsigned short, "0x%hX"); 212#if 0 /* Bad! */ 213 CHECK_HIGHBIT (LONG_HIGHBIT, long, "0x%lX"); 214 CHECK_HIGHBIT (INT_HIGHBIT, int, "0x%X"); 215 CHECK_HIGHBIT (SHRT_HIGHBIT, short, "0x%hX"); 216#endif 217 218#if 0 /* Bad! */ 219 CHECK_MAX (LONG_MAX, LONG_MIN, long, "%ld"); 220 CHECK_MAX (INT_MAX, INT_MIN, int, "%d"); 221 CHECK_MAX (SHRT_MAX, SHRT_MIN, short, "%hd"); 222#endif 223 CHECK_MAX (ULONG_MAX, 0, unsigned long, "%lu"); 224 CHECK_MAX (UINT_MAX, 0, unsigned int, "%u"); 225 CHECK_MAX (USHRT_MAX, 0, unsigned short, "%hu"); 226#if 0 /* Bad! */ 227 CHECK_MAX (MP_SIZE_T_MAX, MP_SIZE_T_MIN, mp_size_t, SS("%d","%ld")); 228#endif 229 230 /* UHWtype should have at least enough bits for half a UWtype */ 231 { 232 int bits_per_UWtype, bits_per_UHWtype; 233 CALC_BITS (bits_per_UWtype, UWtype); 234 CALC_BITS (bits_per_UHWtype, UHWtype); 235 CHECK_CONDITION (2*bits_per_UHWtype >= bits_per_UWtype); 236 } 237 238 ASSERT_ALWAYS_LIMB (MODLIMB_INVERSE_3); 239 { 240 mp_limb_t modlimb_inverse_3_calc; 241 binvert_limb (modlimb_inverse_3_calc, CNST_LIMB(3)); 242 ASSERT_ALWAYS_LIMB (modlimb_inverse_3_calc); 243 CHECK_LIMB (MODLIMB_INVERSE_3, modlimb_inverse_3_calc); 244 } 245 { 246 mp_limb_t MODLIMB_INVERSE_3_times_3 247 = (MODLIMB_INVERSE_3 * CNST_LIMB(3)) & GMP_NUMB_MASK; 248 CHECK_LIMB (MODLIMB_INVERSE_3_times_3, CNST_LIMB(1)); 249 } 250 251 { 252 mp_limb_t hi, lo; 253 hi = refmpn_umul_ppmm (&lo, GMP_NUMB_CEIL_MAX_DIV3-1, 254 CNST_LIMB(3) << GMP_NAIL_BITS); 255 if (! (hi < 1)) 256 { 257 printf ("GMP_NUMB_CEIL_MAX_DIV3 too big\n"); 258 error = 1; 259 } 260 hi = refmpn_umul_ppmm (&lo, GMP_NUMB_CEIL_MAX_DIV3, 261 CNST_LIMB(3) << GMP_NAIL_BITS); 262 if (! (hi >= 1)) 263 { 264 printf ("GMP_NUMB_CEIL_MAX_DIV3 too small\n"); 265 error = 1; 266 } 267 } 268 269 { 270 mp_limb_t hi, lo; 271 hi = refmpn_umul_ppmm (&lo, GMP_NUMB_CEIL_2MAX_DIV3-1, 272 CNST_LIMB(3) << GMP_NAIL_BITS); 273 if (! (hi < 2)) 274 { 275 printf ("GMP_NUMB_CEIL_2MAX_DIV3 too big\n"); 276 error = 1; 277 } 278 hi = refmpn_umul_ppmm (&lo, GMP_NUMB_CEIL_2MAX_DIV3, 279 CNST_LIMB(3) << GMP_NAIL_BITS); 280 if (! (hi >= 2)) 281 { 282 printf ("GMP_NUMB_CEIL_2MAX_DIV3 too small\n"); 283 error = 1; 284 } 285 } 286 287#ifdef PP_INVERTED 288 { 289 mp_limb_t pp_inverted_calc; 290 invert_limb (pp_inverted_calc, PP); 291 CHECK_LIMB (PP_INVERTED, pp_inverted_calc); 292 } 293#endif 294 295 if (argc >= 2 || error) 296 { 297 int bits; 298 299 printf ("\n"); 300 printf ("After gmp.h,\n"); 301 printf (" ULONG_MAX %s\n", ulong_max_def); 302 printf (" LONG_MAX %s\n", long_max_def); 303 printf (" UINT_MAX %s\n", uint_max_def); 304 printf (" INT_MAX %s\n", int_max_def); 305 printf (" USHRT_MAX %s\n", ushrt_max_def); 306 printf (" SHRT_MAX %s\n", shrt_max_def); 307 printf ("\n"); 308 309#ifdef _CRAY 310 printf ("_CRAY is defined, so limits.h is being used\n"); 311#endif 312 313 printf ("ULONG_MAX %lX\n", ULONG_MAX); 314 printf ("ULONG_HIGHBIT %lX\n", ULONG_HIGHBIT); 315 printf ("LONG_MAX %lX\n", LONG_MAX); 316 printf ("LONG_MIN %lX\n", LONG_MIN); 317 318 printf ("UINT_MAX %X\n", UINT_MAX); 319 printf ("UINT_HIGHBIT %X\n", UINT_HIGHBIT); 320 printf ("INT_MAX %X\n", INT_MAX); 321 printf ("INT_MIN %X\n", INT_MIN); 322 323 printf ("USHRT_MAX %X\n", USHRT_MAX); 324 printf ("USHRT_HIGHBIT %X\n", USHRT_HIGHBIT); 325 printf ("SHRT_MAX %X\n", SHRT_MAX); 326 printf ("SHRT_MIN %X\n", SHRT_MIN); 327 328 printf ("\n"); 329 printf ("Bits\n"); 330 CALC_BITS (bits, long); printf (" long %d\n", bits); 331 CALC_BITS (bits, int); printf (" int %d\n", bits); 332 CALC_BITS (bits, short); printf (" short %d\n", bits); 333 CALC_BITS (bits, unsigned long); printf (" unsigned long %d\n", bits); 334 CALC_BITS (bits, unsigned int); printf (" unsigned int %d\n", bits); 335 CALC_BITS (bits, unsigned short); printf (" unsigned short %d\n", bits); 336 CALC_BITS (bits, mp_size_t); printf (" mp_size_t %d\n", bits); 337 } 338 339 if (error) 340 abort (); 341 342 exit (0); 343} 344