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