1#!/usr/bin/nickle 2 3# Use nickle's extended precision floating point implementation 4# to generate some simple test vectors for long double math functions 5 6typedef struct { 7 real(real a) f; 8 string name; 9} func_f_f_t; 10 11typedef struct { 12 real(real a, real b) f; 13 string name; 14} func_f_ff_t; 15 16typedef struct { 17 real(real a, real b, real c) f; 18 string name; 19} func_f_fff_t; 20 21typedef struct { 22 real(real a, int b) f; 23 string name; 24} func_f_fi_t; 25 26typedef struct { 27 int(real a) f; 28 string name; 29} func_i_f_t; 30 31string[] limited_funcs = { 32 "ceill", 33 "copysignl", 34 "fabsl", 35 "floorl", 36 "fmaxl", 37 "fminl", 38 "frexpl", 39 "hypotl", 40 "ilogbl", 41 "ldexpl", 42 "logbl", 43 "llrintl", 44 "lrintl", 45 "lroundl", 46 "llroundl", 47 "nanl", 48 "nearbyintl", 49 "rintl", 50 "roundl", 51 "scalbnl", 52 "scalblnl", 53 "truncl", 54 "logbl", 55 "sqrtl", 56}; 57 58bool 59is_full_func(string name) 60{ 61 for (int i = 0; i < dim(limited_funcs); i++) 62 if (limited_funcs[i] == name) 63 return false; 64 return true; 65} 66 67exception infinity(real v); 68exception nan(); 69 70int prec = 512; 71int out_prec = 192; 72 73string 74toupper(string s) 75{ 76 string o = ""; 77 for (int i = 0; i < String::length(s); i++) { 78 int c = s[i]; 79 if ('a' <= c && c <= 'z') 80 c = c - 'a' + 'A'; 81 o = o + String::new(c); 82 } 83 return o; 84} 85 86string 87make_prec(string name) 88{ 89 string prec = toupper(name) + "_PREC"; 90 printf("#ifndef %s\n", prec); 91 printf("#define %s DEFAULT_PREC\n", prec); 92 printf("#endif\n"); 93 return prec; 94} 95 96void 97gen_real_f_f(func_f_f_t f) 98{ 99 real x, y; 100 string vec = sprintf("%s_vec", f.name); 101 printf("\n"); 102 if (is_full_func(f.name)) 103 printf("#ifdef FULL_LONG_DOUBLE\n"); 104 string prec_name = make_prec(f.name); 105 printf("long_double_test_f_f_t %s[] = {\n", vec); 106 for (x = -10; x <= 10; x += .1) { 107 try { 108 string sy; 109 try { 110 try { 111 y = imprecise(f.f(imprecise(x, prec)), out_prec); 112 sy = sprintf("%.-eL", y); 113 } catch divide_by_zero(real x, real y) { 114 if (x == 0) 115 raise invalid_argument(f.name, 0, x); 116 raise infinity(x); 117 } 118 } catch infinity(real v) { 119 sy = "(long double) INFINITY"; 120 if (v < 0) 121 sy = "-" + sy; 122 } catch nan() { 123 sy = "(long double) NAN"; 124 } 125 printf(" { .line = __LINE__, .x = %.-eL, .y = %s },\n", x, sy); 126 } catch invalid_argument(string s, int i, poly x) { 127 } 128 } 129 printf("};\n\n"); 130 printf("int test_%s(void) {\n", f.name); 131 printf(" unsigned int i;\n"); 132 printf(" int result = 0;\n"); 133 printf(" for (i = 0; i < sizeof(%s)/sizeof(%s[0]); i++) {\n", vec, vec); 134 printf(" long double y = %s(%s[i].x);\n", f.name, vec); 135 printf(" result += check_long_double(\"%s\", %s[i].line, %s, %s[i].y, y);\n", f.name, vec, prec_name, vec); 136 printf(" }\n"); 137 printf(" return result;\n"); 138 printf("}\n"); 139 if (is_full_func(f.name)) 140 printf("#endif /* FULL_LONG_DOUBLE */\n"); 141} 142 143real cbrt(real x) { return x**(1/3); } 144real exp10(real x) { return 10**x; } 145real exp2(real x) { return 2**x; } 146real expm1(real x) { 147 x = imprecise(x); 148 int bits = precision(x); 149 int obits = bits; 150 151 if (0 < x && x < 1) 152 obits -= exponent(x); 153 154 x = imprecise(x, obits); 155 156 return imprecise(exp(x) - 1, bits); 157} 158real lgamma(real x) { 159 if (x < 0 && x == floor(x)) 160 raise infinity(1); 161 return log(gamma(x)); 162} 163real log1p(real x) { return log(1+x); } 164real logb(real x) { 165 if (x == 0) 166 raise infinity(-1); 167 return exponent(imprecise(x)) - 1; 168} 169real pow10(real x) { return 10**x; } 170 171real round(x) { if (x < 0) return -round(-x); return floor(x+0.5); } 172real trunc(x) { if (x < 0) return -trunc(-x); return floor(x); } 173 174real acosh(x) { 175 if (x < 1) 176 raise nan(); 177 return log(x + sqrt(x*x-1)); 178} 179 180real asinh(x) { 181 if (x == 0) return 0; 182 real sign = 1; 183 if (x < 0) { 184 sign = -1; 185 x = -x; 186 } 187 return sign * log(x + sqrt(x*x+1)); 188} 189 190real atanh(x) { 191 if (abs(x) > 1) 192 raise nan(); 193 if (abs(x) == 1) 194 raise infinity(x); 195 return 0.5 * log((1 + x) / (1 - x)); 196} 197 198real cosh(x) { 199 return (exp(x) + exp(-x)) / 2; 200} 201 202real sinh(x) { 203 return (exp(x) - exp(-x)) / 2; 204} 205 206real tanh(x) { 207 return sinh(x) / cosh(x); 208} 209 210real tgamma(real x) { 211 if (x == 0) 212 raise infinity(1); 213 if (x < 0 && x == floor(x)) 214 raise nan(); 215 return gamma(x); 216} 217 218real nearbyint(real x) { 219 real y; 220 221 if (x < 0) 222 y = ceil(x-0.5); 223 else 224 y = floor(x+0.5); 225 if (abs(x-y) == 0.5) { 226 if (y % 2 != 0) { 227 if (y > 0) 228 y--; 229 else 230 y++; 231 } 232 } 233 return y; 234} 235 236real _erf(real x, real off) 237{ 238 x = imprecise(x); 239 int bits = precision(x); 240 int obits = bits + 512; 241 real factor = 2 / sqrt(pi_value(obits)); 242 243 x = imprecise(x, obits); 244 off = imprecise(off, obits) / factor; 245 real val = x - off; 246 247 for (int n = 1; ; n++) { 248 int f = 2 * n + 1; 249 real a = ((-1)**n * x**f) / (n! * f); 250 val += a; 251 if (exponent(val) - exponent(a) > obits) 252 break; 253 } 254 return imprecise(val * factor, bits); 255} 256 257real erf(real x) 258{ 259 return _erf(x, 0); 260} 261 262real erfc(real x) 263{ 264 return -_erf(x, 1); 265} 266 267real jn(real x, int n) 268{ 269 x = imprecise(x); 270 int bits = precision(x); 271 int obits = bits + 512; 272 273 x = imprecise(x, obits); 274 real val = imprecise(0, obits); 275 276 for (int m = 0; ; m++) { 277 real a = ((-1)**m / (m! * gamma(m + n + 1))) * (x/2)**(2 * m + n); 278 val += a; 279 if (exponent(val) - exponent(a) > obits) 280 break; 281 } 282 return imprecise(val, bits); 283} 284 285real scalbnl(real x, int exp) 286{ 287 return x * (2 ** exp); 288} 289 290real ldexpl(real x, int exp) 291{ 292 return x * (2 ** exp); 293} 294 295real rintl(real x) { 296 return nearbyint(x); 297} 298 299real round_even(real x, int bits) 300{ 301 int exp = exponent(x); 302 real mant = abs(mantissa(x)) * 2**bits; 303 304 int ipart = floor(mant); 305 real fpart = mant - ipart; 306 307 if (fpart == 0.5) { 308 if ((ipart & 1) != 0) 309 ipart++; 310 } else if (fpart > 0.5) 311 ipart++; 312 313 real ret = ipart * (2 ** (exp - bits)); 314 if (x < 0) 315 ret = -ret; 316 return ret; 317} 318 319real j0(real x) = jn(x,0); 320real j1(real x) = jn(x,1); 321 322real default_prec = 1e-20; 323 324func_f_f_t[] funcs_f_f = { 325 { .f = acosh, .name = "acoshl" }, 326 { .f = acos, .name = "acosl" }, 327 { .f = asinh, .name = "asinhl" }, 328 { .f = asin, .name = "asinl" }, 329 { .f = atanh, .name = "atanhl" }, 330 { .f = atan, .name = "atanl" }, 331 { .f = cbrt, .name = "cbrtl" }, 332 { .f = ceil, .name = "ceill" }, 333 { .f = cosh, .name = "coshl" }, 334 { .f = cos, .name = "cosl" }, 335 { .f = erfc, .name = "erfcl" }, 336 { .f = erf, .name = "erfl" }, 337 { .f = exp10, .name = "exp10l" }, 338 { .f = exp2, .name = "exp2l" }, 339 { .f = exp, .name = "expl" }, 340 { .f = expm1, .name = "expm1l" }, 341 { .f = floor, .name = "floorl" }, 342# { .f = j0, .name = "j0l" }, 343# { .f = j1, .name = "j1l" }, 344# { .f = jn, .name = "jnl" }, 345 { .f = lgamma, .name = "lgammal" }, 346 { .f = log10, .name = "log10l" }, 347 { .f = log1p, .name = "log1pl" }, 348 { .f = log2, .name = "log2l" }, 349 { .f = logb, .name = "logbl" }, 350 { .f = log, .name = "logl" }, 351 { .f = nearbyint, .name = "nearbyintl" }, 352# { .f = pow10, .name = "pow10l" }, /* an alias for exp10 */ 353 { .f = rintl, .name = "rintl" }, 354 { .f = round, .name = "roundl" }, 355 { .f = sinh, .name = "sinhl" }, 356 { .f = sin, .name = "sinl" }, 357 { .f = sqrt, .name = "sqrtl" }, 358 { .f = tanh, .name = "tanhl" }, 359 { .f = tan, .name = "tanl" }, 360 { .f = tgamma, .name = "tgammal" }, 361 { .f = trunc, .name = "truncl" }, 362# { .f = y0, .name = "y0l" }, 363# { .f = y1, .name = "y1l" }, 364# { .f = yn, .name = "ynl" }, 365}; 366 367void 368gen_real_f_ff(func_f_ff_t f) 369{ 370 real x0, x1, y; 371 string vec = sprintf("%s_vec", f.name); 372 373 printf("\n"); 374 if (is_full_func(f.name)) 375 printf("#ifdef FULL_LONG_DOUBLE\n"); 376 string prec_name = make_prec(f.name); 377 printf("long_double_test_f_ff_t %s[] = {\n", vec); 378 for (x0 = -4; x0 <= 4; x0 += .25) { 379 for (x1 = -4; x1 <= 4; x1 += 0.25) { 380 try { 381 string sy; 382 try { 383 try { 384 y = round_even(f.f(imprecise(x0, prec), imprecise(x1, prec)), out_prec); 385 sy = sprintf("%.-eL", y); 386 } catch divide_by_zero(real x, real y) { 387 if (x == 0) 388 raise invalid_argument(f.name, 0, x); 389 raise infinity(x); 390 } 391 } catch infinity(real v) { 392 sy = "(long double) INFINITY"; 393 if (v < 0) 394 sy = "-" + sy; 395 } catch nan() { 396 sy = "(long double) NAN"; 397 } 398 printf(" { .line = __LINE__, .x0 = %.-eL, .x1 = %.-eL, .y = %s },\n", x0, x1, sy); 399 } catch invalid_argument(string s, int i, poly x) { 400 } 401 } 402 } 403 printf("};\n\n"); 404 printf("int test_%s(void) {\n", f.name); 405 printf(" unsigned int i;\n"); 406 printf(" int result = 0;\n"); 407 printf(" for (i = 0; i < sizeof(%s)/sizeof(%s[0]); i++) {\n", vec, vec); 408 printf(" long double y = %s(%s[i].x0, %s[i].x1);\n", f.name, vec, vec); 409 printf(" result += check_long_double(\"%s\", %s[i].line, %s, %s[i].y, y);\n", f.name, vec,prec_name, vec); 410 printf(" }\n"); 411 printf(" return result;\n"); 412 printf("}\n"); 413 if (is_full_func(f.name)) 414 printf("#endif /* FULL_LONG_DOUBLE */\n"); 415} 416 417void 418gen_real_f_fff(func_f_fff_t f) 419{ 420 real x0, x1, x2,y; 421 string vec = sprintf("%s_vec", f.name); 422 423 printf("\n"); 424 if (is_full_func(f.name)) 425 printf("#ifdef FULL_LONG_DOUBLE\n"); 426 string prec_name = make_prec(f.name); 427 printf("long_double_test_f_fff_t %s[] = {\n", vec); 428 for (x0 = -4; x0 <= 4; x0 += 0.6) { 429 for (x1 = -4; x1 <= 4; x1 += 0.6) { 430 for (x2 = -4; x2 <= 4; x2 += 0.6) { 431 try { 432 string sy; 433 try { 434 try { 435 y = imprecise(f.f(imprecise(x0, prec), imprecise(x1, prec), imprecise(x2, prec)), out_prec); 436 sy = sprintf("%.-eL", y); 437 } catch divide_by_zero(real x, real y) { 438 if (x == 0) 439 raise invalid_argument(f.name, 0, x); 440 raise infinity(x); 441 } 442 } catch infinity(real v) { 443 sy = "(long double) INFINITY"; 444 if (v < 0) 445 sy = "-" + sy; 446 } catch nan() { 447 sy = "(long double) NAN"; 448 } 449 printf(" { .line = __LINE__, .x0 = %.-eL, .x1 = %.-eL, .x2 = %.-eL, .y = %s },\n", x0, x1, x2, sy); 450 } catch invalid_argument(string s, int i, poly x) { 451 } 452 } 453 } 454 } 455 printf("};\n\n"); 456 printf("int test_%s(void) {\n", f.name); 457 printf(" unsigned int i;\n"); 458 printf(" int result = 0;\n"); 459 printf(" for (i = 0; i < sizeof(%s)/sizeof(%s[0]); i++) {\n", vec, vec); 460 printf(" long double y = %s(%s[i].x0, %s[i].x1, %s[i].x2);\n", f.name, vec, vec, vec); 461 printf(" result += check_long_double(\"%s\", %s[i].line, %s, %s[i].y, y);\n", f.name, vec,prec_name, vec); 462 printf(" }\n"); 463 printf(" return result;\n"); 464 printf("}\n"); 465 if (is_full_func(f.name)) 466 printf("#endif /* FULL_LONG_DOUBLE */\n"); 467} 468 469real fmod(real x, real y) { 470 if (y == 0) 471 raise nan(); 472 real n = x / y; 473 if (n < 0) 474 n = ceil(n); 475 else 476 n = floor(n); 477 return x - n * y; 478} 479real fdim(real x, real y) { return max(x-y, 0); } 480real fmax(real x, real y) { return max(x,y); } 481real fmin(real x, real y) { return min(x,y); } 482 483real hypot(real x, real y) { return sqrt(x*x + y*y); } 484 485/* Compute an IEEE remainder */ 486real remainder(real x, real y) { 487 if (y == 0) 488 raise nan(); 489 real q = x / y; 490 int n; 491 if (q < 0) 492 n = ceil(q - 0.5); 493 else 494 n = floor(q + 0.5); 495 if (abs(q-n) == 0.5) { 496 if (n % 2 != 0) { 497 if (n > 0) 498 n--; 499 else 500 n++; 501 } 502 } 503 return x - n * y; 504} 505 506real drem(real x, real y) { 507 return remainder (x, y); 508} 509 510real copysign(real x, real y) { 511 x = abs(x); 512 if (y < 0) 513 x = -x; 514 return x; 515} 516 517bool 518isoddint(real x) { 519 return x == floor(x) && (floor(x) & 1) == 1; 520} 521 522bool 523isevenint(real x) { 524 return x == floor(x) && (floor(x) & 1) == 0; 525} 526 527bool 528isint(real x) { 529 return x == floor(x); 530} 531 532/* Deal with the oddities of IEEE pow */ 533real powl(real x, real y) { 534 if (x == 0 && isoddint(y) && y < 0) 535 raise infinity(1); 536 if (x == 0 && y < 0) 537 raise infinity(1); 538 if (x == 0 && y > 0) 539 return 0; 540 if (x == 1) 541 return 1; 542 if (y == 0) 543 return 1; 544 if (x < 0 && !isint(y)) 545 raise nan(); 546 return pow(x, y); 547} 548 549real scalb(real x, real y) { 550 if (!isint(y)) 551 raise nan(); 552 return x * 2 ** y; 553} 554 555/* Functions of the form f(x,y) */ 556func_f_ff_t[] funcs_f_ff = { 557 { .f = atan2, .name = "atan2l" }, 558 { .f = powl, .name = "powl" }, 559 { .f = fmod, .name = "fmodl" }, 560# { .f = nextafter, .name = "nextafterl" }, 561# { .f = nexttoward, .name = "nexttowardl" }, 562 { .f = fdim, .name = "fdiml" }, 563 { .f = fmax, .name = "fmaxl" }, 564 { .f = fmin, .name = "fminl" }, 565 { .f = hypot, .name = "hypotl" }, 566 { .f = scalb, .name = "scalbl" }, 567 { .f = remainder, .name = "remainderl" }, 568 { .f = drem, .name = "dreml" }, 569 { .f = copysign, .name = "copysignl" }, 570}; 571 572real fma(real x, real y, real z) 573{ 574 real t = x * y + z; 575 576 return imprecise(t, precision(x)); 577} 578 579/* Functions of the form f(x,y,z) */ 580func_f_fff_t[] funcs_f_fff = { 581 { .f = fma, .name = "fmal" }, 582}; 583 584void 585gen_real_f_fi(func_f_fi_t f) 586{ 587 real x0, y; 588 int x1; 589 string vec = sprintf("%s_vec", f.name); 590 591 printf("\n"); 592 if (is_full_func(f.name)) 593 printf("#ifdef FULL_LONG_DOUBLE\n"); 594 string prec_name = make_prec(f.name); 595 printf("long_double_test_f_fi_t %s[] = {\n", vec); 596 for (x0 = -4; x0 <= 4; x0 += .25) { 597 for (x1 = -16; x1 <= 16; x1 += 1) { 598 try { 599 string sy; 600 try { 601 try { 602 y = imprecise(f.f(imprecise(x0, prec), x1), out_prec); 603 sy = sprintf("%.-eL", y); 604 } catch divide_by_zero(real x, real y) { 605 if (x == 0) 606 raise invalid_argument(f.name, 0, x); 607 raise infinity(x); 608 } 609 } catch infinity(real v) { 610 sy = "(long double) INFINITY"; 611 if (v < 0) 612 sy = "-" + sy; 613 } catch nan() { 614 sy = "(long double) NAN"; 615 } 616 printf(" { .line = __LINE__, .x0 = %.-eL, .x1 = %d, .y = %s },\n", x0, x1, sy); 617 } catch invalid_argument(string s, int i, poly x) { 618 } 619 } 620 } 621 printf("};\n\n"); 622 printf("int test_%s(void) {\n", f.name); 623 printf(" unsigned int i;\n"); 624 printf(" int result = 0;\n"); 625 printf(" for (i = 0; i < sizeof(%s)/sizeof(%s[0]); i++) {\n", vec, vec); 626 printf(" long double y = %s(%s[i].x0, %s[i].x1);\n", f.name, vec, vec); 627 printf(" result += check_long_double(\"%s\", %s[i].line, %s, %s[i].y, y);\n", f.name, vec,prec_name, vec); 628 printf(" }\n"); 629 printf(" return result;\n"); 630 printf("}\n"); 631 if (is_full_func(f.name)) 632 printf("#endif /* FULL_LONG_DOUBLE */\n"); 633} 634 635/* Functions of the form f(x,y) */ 636func_f_fi_t[] funcs_f_fi = { 637 { .f = ldexpl, .name = "ldexpl" }, 638 { .f = scalbnl, .name = "scalbnl" }, 639}; 640 641exception invalid_int(string y); 642 643void 644gen_real_i_f(func_i_f_t f) 645{ 646 real x; 647 int y; 648 string vec = sprintf("%s_vec", f.name); 649 650 printf("\n"); 651 if (is_full_func(f.name)) 652 printf("#ifdef FULL_LONG_DOUBLE\n"); 653 printf("long_double_test_i_f_t %s[] = {\n", vec); 654 for (x = -10; x <= 10; x += .1) { 655 try { 656 string sy; 657 try { 658 y = f.f(imprecise(x, prec)); 659 sy = sprintf("%d", y); 660 } catch invalid_int(string s) { 661 sy = s; 662 } 663 printf(" { .line = __LINE__, .x = %.-eL, .y = %s },\n", x, sy); 664 } catch invalid_argument(string s, int i, poly x) { 665 } 666 } 667 printf("};\n\n"); 668 printf("int test_%s(void) {\n", f.name); 669 printf(" unsigned int i;\n"); 670 printf(" int result = 0;\n"); 671 printf(" for (i = 0; i < sizeof(%s)/sizeof(%s[0]); i++) {\n", vec, vec); 672 printf(" long long y = %s(%s[i].x);\n", f.name, vec); 673 printf(" result += check_long_long(\"%s\", %s[i].line, %s[i].y, y);\n", f.name, vec, vec); 674 printf(" }\n"); 675 printf(" return result;\n"); 676 printf("}\n"); 677 if (is_full_func(f.name)) 678 printf("#endif /* FULL_LONG_DOUBLE */\n"); 679} 680 681int finite(real x) { 682 return 1; 683} 684 685int ilogb(real x) { 686 if (x == 0) 687 raise invalid_int("FP_ILOGB0"); 688 return exponent(imprecise(x)) - 1; 689} 690 691int isinf(real x) { 692 return 0; 693} 694 695int isnan(real x) { 696 return 0; 697} 698 699int lrint(real x) { 700 return rintl(x); 701} 702 703int lround(real x) { 704 int ix = floor(x); 705 real diff = x - ix; 706 if ((diff == 0.5) && (x > 0) || (diff > 0.5)) 707 ix++; 708 return ix; 709} 710 711/* Functions of the form i(x) */ 712func_i_f_t[] funcs_i_f = { 713 { .f = finite, .name = "finitel" }, 714 { .f = ilogb, .name = "ilogb" }, 715 { .f = isinf, .name = "isinfl" }, 716 { .f = isnan, .name = "isnanl" }, 717 { .f = lrint, .name = "lrintl" }, 718 { .f = lrint, .name = "llrintl" }, 719 { .f = lround, .name = "lroundl" }, 720 { .f = lround, .name = "llroundl" }, 721}; 722 723 724/* 725 * These functions aren't tested yet 726 * 727 * long double modfl (long double, long double *); 728 * float nexttowardf (float, long double); 729 * double nexttoward (double, long double); 730 * long double nextowardl (long double, long double); 731 * long double remquol (long double, long double, int *); 732 * long double lgammal_r (long double, int *); 733 * void sincosl (long double, long double *, long double *); 734 */ 735 736void 737main() 738{ 739 for (int i = 0; i < dim(funcs_i_f); i++) 740 gen_real_i_f(funcs_i_f[i]); 741 742 for (int i = 0; i < dim(funcs_f_fi); i++) 743 gen_real_f_fi(funcs_f_fi[i]); 744 745 for (int i = 0; i < dim(funcs_f_ff); i++) 746 gen_real_f_ff(funcs_f_ff[i]); 747 748 for (int i = 0; i < dim(funcs_f_f); i++) 749 gen_real_f_f(funcs_f_f[i]); 750 751 for (int i = 0; i < dim(funcs_f_fff); i++) 752 gen_real_f_fff(funcs_f_fff[i]); 753 754 printf("long_double_test_t long_double_tests[] = {\n"); 755 for (int i = 0; i < dim(funcs_f_f); i++) { 756 if (is_full_func(funcs_f_f[i].name)) 757 printf("#ifdef FULL_LONG_DOUBLE\n"); 758 printf(" { .name = \"%s\", .test = test_%s },\n", funcs_f_f[i].name, funcs_f_f[i].name); 759 if (is_full_func(funcs_f_f[i].name)) 760 printf("#endif /* FULL_LONG_DOUBLE */\n"); 761 } 762 for (int i = 0; i < dim(funcs_f_ff); i++) { 763 if (is_full_func(funcs_f_ff[i].name)) 764 printf("#ifdef FULL_LONG_DOUBLE\n"); 765 printf(" { .name = \"%s\", .test = test_%s },\n", funcs_f_ff[i].name, funcs_f_ff[i].name); 766 if (is_full_func(funcs_f_ff[i].name)) 767 printf("#endif /* FULL_LONG_DOUBLE */\n"); 768 } 769 for (int i = 0; i < dim(funcs_f_fff); i++) { 770 if (is_full_func(funcs_f_fff[i].name)) 771 printf("#ifdef FULL_LONG_DOUBLE\n"); 772 printf(" { .name = \"%s\", .test = test_%s },\n", funcs_f_fff[i].name, funcs_f_fff[i].name); 773 if (is_full_func(funcs_f_fff[i].name)) 774 printf("#endif /* FULL_LONG_DOUBLE */\n"); 775 } 776 for (int i = 0; i < dim(funcs_f_fi); i++) { 777 if (is_full_func(funcs_f_fi[i].name)) 778 printf("#ifdef FULL_LONG_DOUBLE\n"); 779 printf(" { .name = \"%s\", .test = test_%s },\n", funcs_f_fi[i].name, funcs_f_fi[i].name); 780 if (is_full_func(funcs_f_fi[i].name)) 781 printf("#endif /* FULL_LONG_DOUBLE */\n"); 782 } 783 for (int i = 0; i < dim(funcs_i_f); i++) { 784 if (is_full_func(funcs_i_f[i].name)) 785 printf("#ifdef FULL_LONG_DOUBLE\n"); 786 printf(" { .name = \"%s\", .test = test_%s },\n", funcs_i_f[i].name, funcs_i_f[i].name); 787 if (is_full_func(funcs_i_f[i].name)) 788 printf("#endif /* FULL_LONG_DOUBLE */\n"); 789 } 790 printf("};\n"); 791} 792 793main(); 794