@@ -198,6 +198,31 @@ typedef union {
198
198
return c.q; \
199
199
} while(0)
200
200
201
+ #define child_q_q_pi (funcStr , arg ) do { \
202
+ char str[256]; \
203
+ cnv128 c; \
204
+ c.q = arg; \
205
+ sprintf(str, funcStr " %" PRIx64 ":%" PRIx64 "\n", c.h, c.l); \
206
+ write(ptoc[1], str, strlen(str)); \
207
+ if (fgets(str, 255, fpctop) == NULL) stop("child " funcStr); \
208
+ int i; \
209
+ sscanf(str, "%" PRIx64 ":%" PRIx64 " %d", &c.h, &c.l, &i); \
210
+ *ptr = i; \
211
+ return c.q; \
212
+ } while(0)
213
+
214
+ #define child_q_q_pq (funcStr , arg ) do { \
215
+ char str[256]; \
216
+ cnv128 c0, c1; \
217
+ c0.q = arg; \
218
+ sprintf(str, funcStr " %" PRIx64 ":%" PRIx64 "\n", c0.h, c0.l); \
219
+ write(ptoc[1], str, strlen(str)); \
220
+ if (fgets(str, 255, fpctop) == NULL) stop("child " funcStr); \
221
+ sscanf(str, "%" PRIx64 ":%" PRIx64 " %" PRIx64 ":%" PRIx64, &c0.h, &c0.l, &c1.h, &c1.l); \
222
+ *ptr = c1.q; \
223
+ return c0.q; \
224
+ } while(0)
225
+
201
226
#define child_q_str (funcStr , arg ) do { \
202
227
char str[256]; \
203
228
sprintf(str, funcStr " %s\n", arg); \
@@ -283,6 +308,9 @@ Sleef_quad child_ceilq(Sleef_quad x) { child_q_q("ceilq", x); }
283
308
Sleef_quad child_roundq (Sleef_quad x ) { child_q_q ("roundq" , x ); }
284
309
Sleef_quad child_rintq (Sleef_quad x ) { child_q_q ("rintq" , x ); }
285
310
311
+ Sleef_quad child_frexpq (Sleef_quad x , int * ptr ) { child_q_q_pi ("frexpq" , x ); }
312
+ Sleef_quad child_modfq (Sleef_quad x , Sleef_quad * ptr ) { child_q_q_pq ("modfq" , x ); }
313
+
286
314
//
287
315
288
316
#define cmpDenorm_q (mpfrFunc , childFunc , argx ) do { \
@@ -326,6 +354,36 @@ Sleef_quad child_rintq(Sleef_quad x) { child_q_q("rintq", x); }
326
354
} \
327
355
} while(0)
328
356
357
+ #define cmpDenorm_q_pi (mpfrFunc , childFunc , argx ) do { \
358
+ mpfr_set_f128(frx, argx, GMP_RNDN); \
359
+ mpfr_exp_t e; \
360
+ mpfrFunc(&e, frz, frx, GMP_RNDN); \
361
+ int i; \
362
+ Sleef_quad t = childFunc(argx, &i); \
363
+ double u = countULPf128(t, frz, 1); \
364
+ if (u >= 10 || i != (int)e) { \
365
+ fprintf(stderr, "\narg = %s\ntest = %s, %d\ncorrect = %s, %d\nulp = %g\n", \
366
+ sprintf128(argx), sprintf128(t), i, sprintfr(frz), (int)e, u); \
367
+ success = 0; \
368
+ break; \
369
+ } \
370
+ } while(0)
371
+
372
+ #define cmpDenorm_q_pq (mpfrFunc , childFunc , argx ) do { \
373
+ mpfr_set_f128(frx, argx, GMP_RNDN); \
374
+ mpfrFunc(fry, frz, frx, GMP_RNDN); \
375
+ Sleef_quad qi, qf; \
376
+ qf = childFunc(argx, &qi); \
377
+ double u = countULPf128(qf, frz, 1); \
378
+ double v = countULPf128(qi, fry, 1); \
379
+ if (u >= 10 || v >= 10) { \
380
+ fprintf(stderr, "\narg = %s\ntest = %s, %s\ncorrect = %s, %s\nulp = %g, %g\n", \
381
+ sprintf128(argx), sprintf128(qf), sprintf128(qi), sprintfr(frz), sprintfr(fry), u, v); \
382
+ success = 0; \
383
+ break; \
384
+ } \
385
+ } while(0)
386
+
329
387
#define checkAccuracy_q (mpfrFunc , childFunc , argx , bound ) do { \
330
388
mpfr_set_f128(frx, argx, GMP_RNDN); \
331
389
mpfrFunc(frz, frx, GMP_RNDN); \
@@ -369,6 +427,39 @@ Sleef_quad child_rintq(Sleef_quad x) { child_q_q("rintq", x); }
369
427
} \
370
428
} while(0)
371
429
430
+ #define checkAccuracy_q_pi (mpfrFunc , childFunc , argx , bound ) do { \
431
+ mpfr_set_f128(frx, argx, GMP_RNDN); \
432
+ mpfr_exp_t ex; \
433
+ mpfrFunc(&ex, frz, frx, GMP_RNDN); \
434
+ int i; \
435
+ Sleef_quad t = childFunc(argx, &i); \
436
+ double e = countULPf128(t, frz, 0); \
437
+ maxError = fmax(maxError, e); \
438
+ if (e > bound || i != (int)ex) { \
439
+ fprintf(stderr, "\narg = %s, test = %s, %d, correct = %s, %d, ULP = %lf\n", \
440
+ sprintf128(argx), sprintf128(t), i, sprintfr(frz), (int)ex, countULPf128(t, frz, 0)); \
441
+ success = 0; \
442
+ break; \
443
+ } \
444
+ } while(0)
445
+
446
+ #define checkAccuracy_q_pq (mpfrFunc , childFunc , argx , bound ) do { \
447
+ mpfr_set_f128(frx, argx, GMP_RNDN); \
448
+ mpfrFunc(fry, frz, frx, GMP_RNDN); \
449
+ Sleef_quad qi, qf; \
450
+ qf = childFunc(argx, &qi); \
451
+ double ef = countULPf128(qf, frz, 0); \
452
+ double ei = countULPf128(qi, fry, 0); \
453
+ maxError = fmax(maxError, ef); \
454
+ maxError = fmax(maxError, ei); \
455
+ if (ef > bound || ei > bound) { \
456
+ fprintf(stderr, "\narg = %s, test = %s, %s, correct = %s, %s, ULP = %lf, %lf\n", \
457
+ sprintf128(argx), sprintf128(qf), sprintf128(qi), sprintfr(frz), sprintfr(fry), ef, ei); \
458
+ success = 0; \
459
+ break; \
460
+ } \
461
+ } while(0)
462
+
372
463
#define testComparison (mpfrFunc , childFunc , argx , argy ) do { \
373
464
mpfr_set_f128(frx, argx, GMP_RNDN); \
374
465
mpfr_set_f128(fry, argy, GMP_RNDN); \
@@ -408,6 +499,20 @@ Sleef_quad child_rintq(Sleef_quad x) { child_q_q("rintq", x); }
408
499
} \
409
500
} while(0)
410
501
502
+ #define cmpDenormOuterLoop_q_pi (mpfrFunc , childFunc , checkVals ) do { \
503
+ for(int i=0;i<sizeof(checkVals)/sizeof(char *);i++) { \
504
+ Sleef_quad a0 = cast_q_str(checkVals[i]); \
505
+ cmpDenorm_q_pi(mpfrFunc, childFunc, a0); \
506
+ } \
507
+ } while(0)
508
+
509
+ #define cmpDenormOuterLoop_q_pq (mpfrFunc , childFunc , checkVals ) do { \
510
+ for(int i=0;i<sizeof(checkVals)/sizeof(char *);i++) { \
511
+ Sleef_quad a0 = cast_q_str(checkVals[i]); \
512
+ cmpDenorm_q_pq(mpfrFunc, childFunc, a0); \
513
+ } \
514
+ } while(0)
515
+
411
516
//
412
517
413
518
#define checkAccuracyOuterLoop_q_q (mpfrFunc , childFunc , minStr , maxStr , sign , nLoop , bound , seed ) do { \
@@ -471,6 +576,38 @@ Sleef_quad child_rintq(Sleef_quad x) { child_q_q("rintq", x); }
471
576
} \
472
577
} while(0)
473
578
579
+ #define checkAccuracyOuterLoop_q_pi (mpfrFunc , childFunc , minStr , maxStr , sign , nLoop , bound , seed ) do { \
580
+ xsrand(seed); \
581
+ Sleef_quad min = cast_q_str(minStr), max = cast_q_str(maxStr); \
582
+ for(int i=0;i<nLoop && success;i++) { \
583
+ Sleef_quad x = rndf128(min, max, sign); \
584
+ checkAccuracy_q_pi(mpfrFunc, childFunc, x, bound); \
585
+ } \
586
+ } while(0)
587
+
588
+ #define checkAccuracyOuterLoop2_q_pi (mpfrFunc , childFunc , checkVals , bound ) do { \
589
+ for(int i=0;i<sizeof(checkVals)/sizeof(char *);i++) { \
590
+ Sleef_quad x = cast_q_str(checkVals[i]); \
591
+ checkAccuracy_q_pi(mpfrFunc, childFunc, x, bound); \
592
+ } \
593
+ } while(0)
594
+
595
+ #define checkAccuracyOuterLoop_q_pq (mpfrFunc , childFunc , minStr , maxStr , sign , nLoop , bound , seed ) do { \
596
+ xsrand(seed); \
597
+ Sleef_quad min = cast_q_str(minStr), max = cast_q_str(maxStr); \
598
+ for(int i=0;i<nLoop && success;i++) { \
599
+ Sleef_quad x = rndf128(min, max, sign); \
600
+ checkAccuracy_q_pq(mpfrFunc, childFunc, x, bound); \
601
+ } \
602
+ } while(0)
603
+
604
+ #define checkAccuracyOuterLoop2_q_pq (mpfrFunc , childFunc , checkVals , bound ) do { \
605
+ for(int i=0;i<sizeof(checkVals)/sizeof(char *);i++) { \
606
+ Sleef_quad x = cast_q_str(checkVals[i]); \
607
+ checkAccuracy_q_pq(mpfrFunc, childFunc, x, bound); \
608
+ } \
609
+ } while(0)
610
+
474
611
//
475
612
476
613
void checkResult (int success , double e ) {
@@ -545,6 +682,17 @@ void do_test(int options) {
545
682
"NaN"
546
683
};
547
684
685
+ static const char * finiteCheckVals [] = {
686
+ "-0.0" , "0.0" , "+0.25" , "-0.25" , "+0.5" , "-0.5" , "+0.75" , "-0.75" , "+1.0" , "-1.0" ,
687
+ "+1.25" , "-1.25" , "+1.5" , "-1.5" , "+2.0" , "-2.0" , "+2.5" , "-2.5" , "+3.0" , "-3.0" ,
688
+ "+4.0" , "-4.0" , "+5.0" , "-5.0" , "+6.0" , "-6.0" , "+7.0" , "-7.0" ,
689
+ "1.234" , "-1.234" , "+1.234e+100" , "-1.234e+100" , "+1.234e-100" , "-1.234e-100" ,
690
+ "+1.234e+3000" , "-1.234e+3000" , "+1.234e-3000" , "-1.234e-3000" ,
691
+ "3.1415926535897932384626433832795028841971693993751058209749445923078164" ,
692
+ "+" STR_QUAD_MIN , "-" STR_QUAD_MIN ,
693
+ "+" STR_QUAD_DENORM_MIN , "-" STR_QUAD_DENORM_MIN ,
694
+ };
695
+
548
696
static const char * trigCheckVals [] = {
549
697
"3.141592653589793238462643383279502884197169399375105820974944592307" ,
550
698
"6.283185307179586476925286766559005768394338798750211641949889184615" ,
@@ -665,6 +813,22 @@ void do_test(int options) {
665
813
666
814
//
667
815
816
+ fprintf (stderr , "frexp : " );
817
+ maxError = 0 ;
818
+ cmpDenormOuterLoop_q_pi (mpfr_frexp , child_frexpq , finiteCheckVals );
819
+ checkAccuracyOuterLoop2_q_pi (mpfr_frexp , child_frexpq , finiteCheckVals , 0 );
820
+ checkAccuracyOuterLoop_q_pi (mpfr_frexp , child_frexpq , "1e-4000" , "1e+4000" , 1 , 10 * NTEST , 0 , 1 );
821
+ checkResult (success , maxError );
822
+
823
+ fprintf (stderr , "modf : " );
824
+ maxError = 0 ;
825
+ cmpDenormOuterLoop_q_pq (mpfr_modf , child_modfq , stdCheckVals );
826
+ checkAccuracyOuterLoop2_q_pq (mpfr_modf , child_modfq , stdCheckVals , 0 );
827
+ checkAccuracyOuterLoop_q_pq (mpfr_modf , child_modfq , "1e-4000" , "1e+4000" , 1 , 10 * NTEST , 0 , 1 );
828
+ checkResult (success , maxError );
829
+
830
+ //
831
+
668
832
fprintf (stderr , "cast_from_doubleq : " );
669
833
{
670
834
xsrand (0 );
0 commit comments