github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/mini-gmp/tests/t-cmp_d.c (about) 1 /* Test mpz_cmp_d and mpz_cmpabs_d. 2 3 Copyright 2001-2003, 2005, 2013 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 https://www.gnu.org/licenses/. */ 19 20 #include <math.h> 21 22 #include "testutils.h" 23 24 /* FIXME: Not sure if the tests here are exhaustive. Ought to try to get 25 each possible exit from mpz_cmp_d (and mpz_cmpabs_d) exercised. */ 26 27 28 #define SGN(n) ((n) > 0 ? 1 : (n) < 0 ? -1 : 0) 29 30 31 void 32 check_one (const char *name, mpz_srcptr x, double y, int cmp, int cmpabs) 33 { 34 int got; 35 36 got = mpz_cmp_d (x, y); 37 if (SGN(got) != cmp) 38 { 39 unsigned i; 40 printf ("mpz_cmp_d wrong (from %s)\n", name); 41 printf (" got %d\n", got); 42 printf (" want %d\n", cmp); 43 fail: 44 printf (" x="); 45 mpz_out_str (stdout, 10, x); 46 printf ("\n y %g\n", y); 47 printf (" x=0x"); 48 mpz_out_str (stdout, -16, x); 49 printf ("\n y %g\n", y); 50 printf (" y"); 51 for (i = 0; i < sizeof(y); i++) 52 printf (" %02X", (unsigned) ((unsigned char *) &y)[i]); 53 printf ("\n"); 54 abort (); 55 } 56 57 got = mpz_cmpabs_d (x, y); 58 if (SGN(got) != cmpabs) 59 { 60 printf ("mpz_cmpabs_d wrong\n"); 61 printf (" got %d\n", got); 62 printf (" want %d\n", cmpabs); 63 goto fail; 64 } 65 } 66 67 void 68 check_data (void) 69 { 70 static const struct { 71 const char *x; 72 double y; 73 int cmp, cmpabs; 74 75 } data[] = { 76 77 { "0", 0.0, 0, 0 }, 78 79 { "1", 0.0, 1, 1 }, 80 { "-1", 0.0, -1, 1 }, 81 82 { "1", 0.5, 1, 1 }, 83 { "-1", -0.5, -1, 1 }, 84 85 { "0", 1.0, -1, -1 }, 86 { "0", -1.0, 1, -1 }, 87 88 { "0x1000000000000000000000000000000000000000000000000", 1.0, 1, 1 }, 89 { "-0x1000000000000000000000000000000000000000000000000", 1.0, -1, 1 }, 90 91 { "0", 1e100, -1, -1 }, 92 { "0", -1e100, 1, -1 }, 93 94 { "2", 1.5, 1, 1 }, 95 { "2", -1.5, 1, 1 }, 96 { "-2", 1.5, -1, 1 }, 97 { "-2", -1.5, -1, 1 }, 98 }; 99 100 mpz_t x; 101 unsigned i; 102 103 mpz_init (x); 104 105 for (i = 0; i < numberof (data); i++) 106 { 107 mpz_set_str_or_abort (x, data[i].x, 0); 108 check_one ("check_data", x, data[i].y, data[i].cmp, data[i].cmpabs); 109 } 110 111 mpz_clear (x); 112 } 113 114 115 /* Equality of integers with up to 53 bits */ 116 void 117 check_onebits (void) 118 { 119 mpz_t x, x2; 120 double y; 121 int i; 122 123 mpz_init_set_ui (x, 0L); 124 mpz_init (x2); 125 126 for (i = 0; i < 512; i++) 127 { 128 mpz_mul_2exp (x, x, 1); 129 mpz_add_ui (x, x, 1L); 130 131 y = mpz_get_d (x); 132 mpz_set_d (x2, y); 133 134 /* stop if any truncation is occurring */ 135 if (mpz_cmp (x, x2) != 0) 136 break; 137 138 check_one ("check_onebits", x, y, 0, 0); 139 check_one ("check_onebits", x, -y, 1, 0); 140 mpz_neg (x, x); 141 check_one ("check_onebits", x, y, -1, 0); 142 check_one ("check_onebits", x, -y, 0, 0); 143 mpz_neg (x, x); 144 } 145 146 mpz_clear (x); 147 mpz_clear (x2); 148 } 149 150 151 /* With the mpz differing by 1, in a limb position possibly below the double */ 152 void 153 check_low_z_one (void) 154 { 155 mpz_t x; 156 double y; 157 unsigned long i; 158 159 mpz_init (x); 160 161 /* FIXME: It'd be better to base this on the float format. */ 162 #if defined (__vax) || defined (__vax__) 163 #define LIM 127 /* vax fp numbers have limited range */ 164 #else 165 #define LIM 512 166 #endif 167 168 for (i = 1; i < LIM; i++) 169 { 170 mpz_set_ui (x, 1L); 171 mpz_mul_2exp (x, x, i); 172 y = mpz_get_d (x); 173 174 check_one ("check_low_z_one", x, y, 0, 0); 175 check_one ("check_low_z_one", x, -y, 1, 0); 176 mpz_neg (x, x); 177 check_one ("check_low_z_one", x, y, -1, 0); 178 check_one ("check_low_z_one", x, -y, 0, 0); 179 mpz_neg (x, x); 180 181 mpz_sub_ui (x, x, 1); 182 183 check_one ("check_low_z_one", x, y, -1, -1); 184 check_one ("check_low_z_one", x, -y, 1, -1); 185 mpz_neg (x, x); 186 check_one ("check_low_z_one", x, y, -1, -1); 187 check_one ("check_low_z_one", x, -y, 1, -1); 188 mpz_neg (x, x); 189 190 mpz_add_ui (x, x, 2); 191 192 check_one ("check_low_z_one", x, y, 1, 1); 193 check_one ("check_low_z_one", x, -y, 1, 1); 194 mpz_neg (x, x); 195 check_one ("check_low_z_one", x, y, -1, 1); 196 check_one ("check_low_z_one", x, -y, -1, 1); 197 mpz_neg (x, x); 198 } 199 200 mpz_clear (x); 201 } 202 203 /* Comparing 1 and 1+2^-n. "y" is volatile to make gcc store and fetch it, 204 which forces it to a 64-bit double, whereas on x86 it would otherwise 205 remain on the float stack as an 80-bit long double. */ 206 void 207 check_one_2exp (void) 208 { 209 double e; 210 mpz_t x; 211 volatile double y; 212 int i; 213 214 mpz_init (x); 215 216 e = 1.0; 217 for (i = 0; i < 128; i++) 218 { 219 e /= 2.0; 220 y = 1.0 + e; 221 if (y == 1.0) 222 break; 223 224 mpz_set_ui (x, 1L); 225 check_one ("check_one_2exp", x, y, -1, -1); 226 check_one ("check_one_2exp", x, -y, 1, -1); 227 228 mpz_set_si (x, -1L); 229 check_one ("check_one_2exp", x, y, -1, -1); 230 check_one ("check_one_2exp", x, -y, 1, -1); 231 } 232 233 mpz_clear (x); 234 } 235 236 void 237 check_infinity (void) 238 { 239 mpz_t x; 240 double y = HUGE_VAL; 241 if (y != 2*y) 242 return; 243 244 mpz_init (x); 245 246 /* 0 cmp inf */ 247 mpz_set_ui (x, 0L); 248 check_one ("check_infinity", x, y, -1, -1); 249 check_one ("check_infinity", x, -y, 1, -1); 250 251 /* 123 cmp inf */ 252 mpz_set_ui (x, 123L); 253 check_one ("check_infinity", x, y, -1, -1); 254 check_one ("check_infinity", x, -y, 1, -1); 255 256 /* -123 cmp inf */ 257 mpz_set_si (x, -123L); 258 check_one ("check_infinity", x, y, -1, -1); 259 check_one ("check_infinity", x, -y, 1, -1); 260 261 /* 2^5000 cmp inf */ 262 mpz_set_ui (x, 1L); 263 mpz_mul_2exp (x, x, 5000L); 264 check_one ("check_infinity", x, y, -1, -1); 265 check_one ("check_infinity", x, -y, 1, -1); 266 267 /* -2^5000 cmp inf */ 268 mpz_neg (x, x); 269 check_one ("check_infinity", x, y, -1, -1); 270 check_one ("check_infinity", x, -y, 1, -1); 271 272 mpz_clear (x); 273 } 274 275 void 276 testmain (int argc, char *argv[]) 277 { 278 check_data (); 279 check_onebits (); 280 check_low_z_one (); 281 check_one_2exp (); 282 check_infinity (); 283 }