https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121976

            Bug ID: 121976
           Summary: DFP expression evaluations not consistent
           Product: gcc
           Version: 15.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: tydeman at tybor dot com
  Target Milestone: ---

DFP (decimal floating point) expressions are evaluated differently depending
upon context.

/* Prereq: dnf install libdfp-devel */
#define __STDC_WANT_DEC_FP__ 1
#define __STDC_WANT_IEC_60559_DFP_EXT__ 1

#include <assert.h>
#include <stdio.h>
#include <limits.h>
#include <errno.h>
#include <fenv.h>
#include <float.h>
#include <math.h>

#pragma STDC FENV_ACCESS ON
#pragma STDC FP_CONTRACT OFF
#pragma STDC FENV_ROUND FE_TONEAREST
#pragma STDC FENV_DEC_ROUND FE_DEC_TONEAREST
#pragma STDC CX_LIMITED_RANGE OFF

int main(void){

  if(1){
/*
 * Compute magnitude of ULP (may be negative or positive depending
 * upon rounding).  This is a power of radix.  This expression comes
 * from Kahan's Paranoia.
 */
#define LD10 _Decimal128
#define  D10 _Decimal64
#define  F10 _Decimal32
#define FP_F10(x) x##df
#define Q \
 (((FP_F10(4.)/FP_F10(3.) - FP_F10(1.)) - FP_F10(1.)/FP_F10(4.))*FP_F10(3.) -
FP_F10(1.)/FP_F10(4.))
    static LD10 fs_ulp_ld = Q;
    static D10  fs_ulp_d  = Q;
    static F10  fs_ulp_f  = Q;
    LD10 ls_ulp_ld = Q;
    D10  ls_ulp_d  = Q;
    F10  ls_ulp_f  = Q;
    assert( fs_ulp_d  == fs_ulp_f );
    assert( fs_ulp_ld == fs_ulp_d );
    assert( fs_ulp_f  == ls_ulp_f );
    assert( (fs_ulp_ld  == ls_ulp_ld)
            || (fs_ulp_d  == ls_ulp_d) );       /* fails */
  }
  return 0;
}

Reply via email to