Bug 39878 - gcc 4.3.2 converts Decimal FP constants wrong
Summary: gcc 4.3.2 converts Decimal FP constants wrong
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.3.2
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2009-04-24 00:32 UTC by Fred J. Tydeman
Modified: 2021-09-17 07:12 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Fred J. Tydeman 2009-04-24 00:32:16 UTC
/* 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;
}
Comment 1 Janis Johnson 2009-06-24 22:03:31 UTC
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.