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;
}