github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/demos/expr/t-expr.c (about) 1 /* Test expression evaluation (print nothing and exit 0 if successful). 2 3 Copyright 2000-2004 Free Software Foundation, Inc. 4 5 This file is part of the GNU MP Library. 6 7 The GNU MP Library is free software; you can redistribute it and/or modify 8 it under the terms of either: 9 10 * the GNU Lesser General Public License as published by the Free 11 Software Foundation; either version 3 of the License, or (at your 12 option) any later version. 13 14 or 15 16 * the GNU General Public License as published by the Free Software 17 Foundation; either version 2 of the License, or (at your option) any 18 later version. 19 20 or both in parallel, as here. 21 22 The GNU MP Library is distributed in the hope that it will be useful, but 23 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 24 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 25 for more details. 26 27 You should have received copies of the GNU General Public License and the 28 GNU Lesser General Public License along with the GNU MP Library. If not, 29 see https://www.gnu.org/licenses/. */ 30 31 #include <stdio.h> 32 #include <stdlib.h> 33 34 #include "gmp.h" 35 #include "tests.h" 36 #include "expr-impl.h" 37 38 39 int option_trace = 0; 40 41 42 struct data_t { 43 int base; 44 const char *expr; 45 const char *want; 46 }; 47 48 #define numberof(x) (sizeof (x) / sizeof ((x)[0])) 49 50 51 /* These data_xxx[] arrays are tables to be tested with one or more of the 52 mp?_t types. z=mpz_t, q=mpz_t, f=mpf_t. */ 53 54 struct data_t data_zqf[] = { 55 56 /* various deliberately wrong expressions */ 57 { 0, "", NULL }, 58 { 0, "1+", NULL }, 59 { 0, "+2", NULL }, 60 { 0, "1,2", NULL }, 61 { 0, "foo(1,2)", NULL }, 62 { 0, "1+foo", NULL }, 63 { 10, "0fff", NULL }, 64 { 0, "!", NULL }, 65 { 0, "10!", NULL }, 66 { 0, "-10!", NULL }, 67 { 0, "gcd((4,6))", NULL }, 68 { 0, "()", NULL }, 69 { 0, "fac(2**1000)", NULL }, 70 { 0, "$", NULL }, 71 { 0, "$-", NULL }, 72 73 /* some basics */ 74 { 10, "123", "123" }, 75 { 10, "-123", "-123" }, 76 { 10, "1+2", "3" }, 77 { 10, "1+2+3", "6" }, 78 { 10, "1+2*3", "7" }, 79 { 10, "3*2+1", "7" }, 80 { 10, "$a", "55" }, 81 { 10, "b", "99" }, 82 { 16, "b", "11" }, 83 { 10, "4**3 * 2 + 1", "129" }, 84 { 10, "1<2", "1" }, 85 { 10, "1>2", "0" }, 86 87 { 10, "(123)", "123" }, 88 89 { 10, "sgn(-123)", "-1" }, 90 { 10, "5-7", "-2" }, 91 92 { 0, "cmp(0,0)", "0" }, 93 { 0, "cmp(1,0)", "1" }, 94 { 0, "cmp(0,1)", "-1" }, 95 { 0, "cmp(-1,0)", "-1" }, 96 { 0, "cmp(0,-1)", "1" }, 97 98 { 10, "0 ? 123 : 456", "456" }, 99 { 10, "1 ? 4+5 : 6+7", "9" }, 100 101 { 10, "(123)", "123" }, 102 { 10, "(2+3)", "5" }, 103 { 10, "(4+5)*(5+6)", "99" }, 104 105 { 0, "1 << 16", "65536" }, 106 { 0, "256 >> 4", "16" }, 107 { 0, "-256 >> 4", "-16" }, 108 109 { 0, "!1", "0" }, 110 { 0, "!9", "0" }, 111 { 0, "!0", "1" }, 112 113 { 0, "2**2**2", "16" }, 114 { 0, "-2**2**2", "-16" }, 115 116 { 0, "0x100", "256" }, 117 { 10, "0x100", NULL }, 118 { 10, "0x 100", NULL }, 119 120 { 0, " max ( 1, 2, 3, 4, 5, 6, 7, 8)", "8" }, 121 { 0, " max ( 1, 9, 2, 3, 4, 5, 6, 7, 8)", "9" }, 122 { 0, " min ( 1, 9, 2, 3, 4, 5, 6, 7, 8)", "1" }, 123 124 { 10, "abs(123)", "123" }, 125 { 10, "abs(-123)", "123" }, 126 { 10, "abs(0)", "0" }, 127 128 /* filling data stack */ 129 { 0, "1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+1))))))))))))))", "16" }, 130 131 /* filling control stack */ 132 { 0, "----------------------------------------------------1", "1" }, 133 }; 134 135 136 const struct data_t data_z[] = { 137 { 0, "divisible_p(333,3)", "1" }, 138 { 0, "congruent_p(7,1,3)", "1" }, 139 140 { 0, "cmpabs(0,0)", "0" }, 141 { 0, "cmpabs(1,0)", "1" }, 142 { 0, "cmpabs(0,1)", "-1" }, 143 { 0, "cmpabs(-1,0)", "1" }, 144 { 0, "cmpabs(0,-1)", "-1" }, 145 146 { 0, "odd_p(1)", "1" }, 147 { 0, "odd_p(0)", "0" }, 148 { 0, "odd_p(-1)", "1" }, 149 150 { 0, "even_p(1)", "0" }, 151 { 0, "even_p(0)", "1" }, 152 { 0, "even_p(-1)", "0" }, 153 154 { 0, "fac(0)", "1" }, 155 { 0, "fac(1)", "1" }, 156 { 0, "fac(2)", "2" }, 157 { 0, "fac(3)", "6" }, 158 { 0, "fac(10)", "3628800" }, 159 160 { 10, "root(81,4)", "3" }, 161 162 { 10, "gcd(4,6)", "2" }, 163 { 10, "gcd(4,6,9)", "1" }, 164 165 { 10, "powm(3,2,9)", "0" }, 166 { 10, "powm(3,2,8)", "1" }, 167 168 /* filling data stack */ 169 { 0, "1 ? 1 : 1 || 1 && 1 | 1 ^ 1 & 1 == 1 >= 1 << 1 - 1 * 1 ** 1", "1" }, 170 171 /* filling control stack */ 172 { 0, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1", "1" }, 173 174 { 0, "fib(10)", "55" }, 175 176 { 0, "setbit(0,5)", "32" }, 177 { 0, "clrbit(32,5)", "0" }, 178 { 0, "tstbit(32,5)", "1" }, 179 { 0, "tstbit(32,4)", "0" }, 180 { 0, "scan0(7,0)", "3" }, 181 { 0, "scan1(7,0)", "0" }, 182 }; 183 184 const struct data_t data_zq[] = { 185 /* expecting failure */ 186 { 0, "1.2", NULL }, 187 }; 188 189 const struct data_t data_q[] = { 190 { 10, "(1/2 + 1/3 + 1/4 + 1/5 + 1/6)*20", "29" }, 191 { 0, "num(5/9)", "5" }, 192 { 0, "den(5/9)", "9" }, 193 }; 194 195 const struct data_t data_zf[] = { 196 { 10, "sqrt ( 49 )", "7" }, 197 { 10, "sqrt ( 49 ) + 1", "8" }, 198 { 10, "sqrt((49))", "7" }, 199 { 10, "sqrt((((((((49))))))))", "7" }, 200 }; 201 202 const struct data_t data_f[] = { 203 { 0, "1@10", "10000000000" }, 204 { 0, "1.5@10", "15000000000" }, 205 { 0, "1000@-1", "100" }, 206 { 0, "10.00@-1", "1" }, 207 208 { 0, "1e10", "10000000000" }, 209 { 0, "1.5e10", "15000000000" }, 210 { 0, "1000e-1", "100" }, 211 { 0, "10.00e-1", "1" }, 212 213 { 16, "1@9", "68719476736" }, 214 215 { 16, "1@10", "18446744073709551616" }, 216 { -16, "1@10", "1099511627776" }, 217 218 { 0, "ceil(0)", "0" }, 219 { 0, "ceil(0.25)", "1" }, 220 { 0, "ceil(0.5)", "1" }, 221 { 0, "ceil(1.5)", "2" }, 222 { 0, "ceil(-0.5)", "0" }, 223 { 0, "ceil(-1.5)", "-1" }, 224 225 /* only simple cases because mpf_eq currently only works on whole limbs */ 226 { 0, "eq(0xFFFFFFFFFFFFFFFF1111111111111111,0xFFFFFFFFFFFFFFFF2222222222222222,64)", "1" }, 227 { 0, "eq(0xFFFFFFFFFFFFFFFF1111111111111111,0xFFFFFFFFFFFFFFFF2222222222222222,128)", "0" }, 228 229 { 0, "floor(0)", "0" }, 230 { 0, "floor(0.25)", "0" }, 231 { 0, "floor(0.5)", "0" }, 232 { 0, "floor(1.5)", "1" }, 233 { 0, "floor(-0.5)", "-1" }, 234 { 0, "floor(-1.5)", "-2" }, 235 236 { 0, "integer_p(1)", "1" }, 237 { 0, "integer_p(0.5)", "0" }, 238 239 { 0, "trunc(0)", "0" }, 240 { 0, "trunc(0.25)", "0" }, 241 { 0, "trunc(0.5)", "0" }, 242 { 0, "trunc(1.5)", "1" }, 243 { 0, "trunc(-0.5)", "0" }, 244 { 0, "trunc(-1.5)", "-1" }, 245 }; 246 247 struct datalist_t { 248 const struct data_t *data; 249 int num; 250 }; 251 252 #define DATALIST(data) { data, numberof (data) } 253 254 struct datalist_t list_z[] = { 255 DATALIST (data_z), 256 DATALIST (data_zq), 257 DATALIST (data_zf), 258 DATALIST (data_zqf), 259 }; 260 261 struct datalist_t list_q[] = { 262 DATALIST (data_q), 263 DATALIST (data_zq), 264 DATALIST (data_zqf), 265 }; 266 267 struct datalist_t list_f[] = { 268 DATALIST (data_zf), 269 DATALIST (data_zqf), 270 DATALIST (data_f), 271 }; 272 273 274 void 275 check_z (void) 276 { 277 const struct data_t *data; 278 mpz_t a, b, got, want; 279 int l, i, ret; 280 281 mpz_init (got); 282 mpz_init (want); 283 mpz_init_set_ui (a, 55); 284 mpz_init_set_ui (b, 99); 285 286 for (l = 0; l < numberof (list_z); l++) 287 { 288 data = list_z[l].data; 289 290 for (i = 0; i < list_z[l].num; i++) 291 { 292 if (option_trace) 293 printf ("mpz_expr \"%s\"\n", data[i].expr); 294 295 ret = mpz_expr (got, data[i].base, data[i].expr, a, b, NULL); 296 297 if (data[i].want == NULL) 298 { 299 /* expect to fail */ 300 if (ret == MPEXPR_RESULT_OK) 301 { 302 printf ("mpz_expr wrong return value, got %d, expected failure\n", ret); 303 goto error; 304 } 305 } 306 else 307 { 308 if (mpz_set_str (want, data[i].want, 0) != 0) 309 { 310 printf ("Cannot parse wanted value string\n"); 311 goto error; 312 } 313 if (ret != MPEXPR_RESULT_OK) 314 { 315 printf ("mpz_expr failed unexpectedly\n"); 316 printf (" return value %d\n", ret); 317 goto error; 318 } 319 if (mpz_cmp (got, want) != 0) 320 { 321 printf ("mpz_expr wrong result\n"); 322 printf (" got "); mpz_out_str (stdout, 10, got); 323 printf ("\n"); 324 printf (" want "); mpz_out_str (stdout, 10, want); 325 printf ("\n"); 326 goto error; 327 } 328 } 329 } 330 } 331 mpz_clear (a); 332 mpz_clear (b); 333 mpz_clear (got); 334 mpz_clear (want); 335 return; 336 337 error: 338 printf (" base %d\n", data[i].base); 339 printf (" expr \"%s\"\n", data[i].expr); 340 if (data[i].want != NULL) 341 printf (" want \"%s\"\n", data[i].want); 342 abort (); 343 } 344 345 void 346 check_q (void) 347 { 348 const struct data_t *data; 349 mpq_t a, b, got, want; 350 int l, i, ret; 351 352 mpq_init (got); 353 mpq_init (want); 354 mpq_init (a); 355 mpq_init (b); 356 357 mpq_set_ui (a, 55, 1); 358 mpq_set_ui (b, 99, 1); 359 360 for (l = 0; l < numberof (list_q); l++) 361 { 362 data = list_q[l].data; 363 364 for (i = 0; i < list_q[l].num; i++) 365 { 366 if (option_trace) 367 printf ("mpq_expr \"%s\"\n", data[i].expr); 368 369 ret = mpq_expr (got, data[i].base, data[i].expr, a, b, NULL); 370 371 if (data[i].want == NULL) 372 { 373 /* expect to fail */ 374 if (ret == MPEXPR_RESULT_OK) 375 { 376 printf ("mpq_expr wrong return value, got %d, expected failure\n", ret); 377 goto error; 378 } 379 } 380 else 381 { 382 if (mpz_set_str (mpq_numref(want), data[i].want, 0) != 0) 383 { 384 printf ("Cannot parse wanted value string\n"); 385 goto error; 386 } 387 mpz_set_ui (mpq_denref(want), 1); 388 389 if (ret != MPEXPR_RESULT_OK) 390 { 391 printf ("mpq_expr failed unexpectedly\n"); 392 printf (" return value %d\n", ret); 393 goto error; 394 } 395 if (mpq_cmp (got, want) != 0) 396 { 397 printf ("mpq_expr wrong result\n"); 398 printf (" got "); mpq_out_str (stdout, 10, got); 399 printf ("\n"); 400 printf (" want "); mpq_out_str (stdout, 10, want); 401 printf ("\n"); 402 goto error; 403 } 404 } 405 } 406 } 407 mpq_clear (a); 408 mpq_clear (b); 409 mpq_clear (got); 410 mpq_clear (want); 411 return; 412 413 error: 414 printf (" base %d\n", data[i].base); 415 printf (" expr \"%s\"\n", data[i].expr); 416 if (data[i].want != NULL) 417 printf (" want \"%s\"\n", data[i].want); 418 abort (); 419 } 420 421 void 422 check_f (void) 423 { 424 const struct data_t *data; 425 mpf_t a, b, got, want; 426 int l, i, ret; 427 428 mpf_set_default_prec (200L); 429 430 mpf_init (got); 431 mpf_init (want); 432 mpf_init_set_ui (a, 55); 433 mpf_init_set_ui (b, 99); 434 435 for (l = 0; l < numberof (list_f); l++) 436 { 437 data = list_f[l].data; 438 439 for (i = 0; i < list_f[l].num; i++) 440 { 441 if (option_trace) 442 printf ("mpf_expr \"%s\"\n", data[i].expr); 443 444 ret = mpf_expr (got, data[i].base, data[i].expr, a, b, NULL); 445 446 if (data[i].want == NULL) 447 { 448 /* expect to fail */ 449 if (ret == MPEXPR_RESULT_OK) 450 { 451 printf ("mpf_expr wrong return value, got %d, expected failure\n", ret); 452 goto error; 453 } 454 } 455 else 456 { 457 if (mpf_set_str (want, data[i].want, 0) != 0) 458 { 459 printf ("Cannot parse wanted value string\n"); 460 goto error; 461 } 462 463 if (ret != MPEXPR_RESULT_OK) 464 { 465 printf ("mpf_expr failed unexpectedly\n"); 466 printf (" return value %d\n", ret); 467 goto error; 468 } 469 if (mpf_cmp (got, want) != 0) 470 { 471 printf ("mpf_expr wrong result\n"); 472 printf (" got "); mpf_out_str (stdout, 10, 20, got); 473 printf ("\n"); 474 printf (" want "); mpf_out_str (stdout, 10, 20, want); 475 printf ("\n"); 476 goto error; 477 } 478 } 479 } 480 } 481 mpf_clear (a); 482 mpf_clear (b); 483 mpf_clear (got); 484 mpf_clear (want); 485 return; 486 487 error: 488 printf (" base %d\n", data[i].base); 489 printf (" expr \"%s\"\n", data[i].expr); 490 if (data[i].want != NULL) 491 printf (" want \"%s\"\n", data[i].want); 492 abort (); 493 } 494 495 496 int 497 main (int argc, char *argv[]) 498 { 499 tests_start (); 500 501 if (argc >= 2) 502 option_trace = 1; 503 504 check_z (); 505 check_q (); 506 check_f (); 507 508 tests_end (); 509 exit (0); 510 }