/* DFP TR 24732 == WG14 / N1312 */ #define __STDC_WANT_DEC_FP__ /* Tell implementation that we want Decimal FP */ #include <stdio.h> int main(void){ /* * If DEC_EVAL_METHOD is 0, then these triples are not the same. * If DEC_EVAL_METHOD is 1 or 2, then these suffer double rounding * and are the same. */ _Decimal32 f1 = 9999998.499999999999999999999999999999999999DF; _Decimal32 f2 = 9999998.5DF; _Decimal32 f3 = 9999998.500000000000000000000000000000000001DF; _Decimal32 f4 = 9999999.499999999999999999999999999999999999DF; _Decimal32 f5 = 9999999.5DF; _Decimal32 f6 = 9999999.500000000000000000000000000000000001DF; _Decimal128 ld1 = .6666666666666666666666666666666666666666DF; if( .6666667DF == ld1 ){ (void)printf("DEC_EVAL_METHOD appears to be 0\n"); }else if( .6666666666666667DD == ld1 ){ (void)printf("DEC_EVAL_METHOD appears to be 1\n"); }else if( .6666666666666666666666666666666667DL == ld1 ){ (void)printf("DEC_EVAL_METHOD appears to be 2\n"); }else{ (void)printf("DEC_EVAL_METHOD appears to be -1\n"); } if( (f1==f2) && (f2==f3) ){ (void)printf("Fail 1 if DEC_EVAL_METHOD is 0\n"); } if( (f4==f5) && (f5==f6) ){ (void)printf("Fail 2 if DEC_EVAL_METHOD is 0\n"); } return 0; }
GCC defines DEC_EVAL_METHOD to be 0: "evaluate all operations just to the range and precision of the type". The arithmetic/comparison/conversion functions in libgcc (for DPD, not sure about BID) use the range and precision of the type, which matches 0. Except for compile-time constants, use of hardware DFP support for POWER6 matches 1: "evaluate operations [and constants] of type _Decimal32 and _Decimal64 to the range and precision of the _Decimal64 type, evaluate _Decimal128 operations [and constants] to the range and precision of the _Decimal128 type". Within the compiler, decimal float constants are evaluated and folded using 128-bit precision, which matches 2: "evaluate all operations and constants to the range and precision of the _Decimal128 type". We could cop out and set DEC_EVAL_METHOD to -1 (indeterminable) but it would be better to pick one of the other values and honor it consistently.