https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88931
Bug ID: 88931 Summary: Failed to convert int128 to float/double with round=FE_UPWARD/FE_TOWARDZERO Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libgcc Assignee: unassigned at gcc dot gnu.org Reporter: hjl.tools at gmail dot com Target Milestone: --- [hjl@gnu-cfl-1 float128-5]$ cat x.c #include <fenv.h> #include <stdio.h> #include <quadmath.h> #pragma STDC FENV_ACCESS ON #define ROUNDING(r) { r, #r } int main (void) { char buf[128]; union { long long ll[2]; __int128 q; } u = { 0xdLL, 0x8000000000000000LL }; int i; struct { int r; const char *s; } round[] = { ROUNDING (FE_DOWNWARD), ROUNDING (FE_UPWARD), ROUNDING (FE_TOWARDZERO), ROUNDING (FE_TONEAREST) }; for (i = 0; i < sizeof (round) / sizeof (round[0]); i++) { fesetround(round[i].r); float f = (float) u.q; double d = (double) u.q; __float128 q = (__float128) u.q; printf("fegetround=%d: %d, %s\n", fegetround(), round[i].r, round[i].s); printf("f=%f\t%x\n", f, *(int*)&f); printf("d=%lf\t%llx\n", d, *(long long*)&d); quadmath_snprintf(buf, 128, "%Qf", 100, q); printf("q=%s\t%016llx%016llx\n", buf, *((long long *)&q + 1), *(long long *)&q); } return 0; } [hjl@gnu-cfl-1 float128-5]$ make gcc -std=c99 -fno-strict-aliasing -g -c -o x.o x.c gcc -o x x.o -lm -lquadmath ./x fegetround=1024: 1024, FE_DOWNWARD f=-170141183460469231731687303715884105728.000000 ff000000 d=-170141183460469231731687303715884105728.000000 c7e0000000000000 q=-170141183460469231731687303715884105728.000000 c07e0000000000000000000000000000 fegetround=2048: 2048, FE_UPWARD f=-170141183460469231731687303715884105728.000000 ff000000 d=-170141183460469231731687303715884105728.000000 c7e0000000000000 q=-170141183460469231731687303715884089344.000000 c07dffffffffffffffffffffffffffff fegetround=3072: 3072, FE_TOWARDZERO f=-170141183460469231731687303715884105728.000000 ff000000 d=-170141183460469231731687303715884105728.000000 c7e0000000000000 q=-170141183460469231731687303715884089344.000000 c07dffffffffffffffffffffffffffff fegetround=0: 0, FE_TONEAREST f=-170141183460469231731687303715884105728.000000 ff000000 d=-170141183460469231731687303715884105728.000000 c7e0000000000000 q=-170141183460469231731687303715884105728.000000 c07e0000000000000000000000000000 [hjl@gnu-cfl-1 float128-5]$ For FE_UPWARD and FE_TOWARDZERO, float should be feffffff and double should be c7dfffffffffffff.