diff options
authorRich Felker <>2019-10-18 19:56:53 -0400
committerRich Felker <>2019-10-18 20:52:18 -0400
commitbff78954995b115e469aadb7636357798978fffd (patch)
parent2d3083e746cf314c16048875e919305b1018bf8b (diff)
fix incorrect use of fabs on long double operand in floatscan.c
based on patch by Dan Gohman, who caught this via compiler warnings. analysis by Szabolcs Nagy determined that it's a bug, whereby errno can be set incorrectly for values where the coercion from long double to double causes rounding. it seems likely that floating point status flags may be set incorrectly as a result too. at the same time, clean up use of preprocessor concatenation involving LDBL_MANT_DIG, which spuriously depends on it being a single unadorned decimal integer literal, and instead use the equivalent formulation 2/LDBL_EPSILON. an equivalent change on the printf side was made in commit bff6095d915f3e41206e47ea2a570ecb937ef926.
1 files changed, 1 insertions, 4 deletions
diff --git a/src/internal/floatscan.c b/src/internal/floatscan.c
index 278bf250..8c0828fc 100644
--- a/src/internal/floatscan.c
+++ b/src/internal/floatscan.c
@@ -33,9 +33,6 @@
#define MASK (KMAX-1)
-#define CONCAT2(x,y) x ## y
-#define CONCAT(x,y) CONCAT2(x,y)
static long long scanexp(FILE *f, int pok)
int c;
@@ -301,7 +298,7 @@ static long double decfloat(FILE *f, int c, int bits, int emin, int sign, int po
y -= bias;
if ((e2+LDBL_MANT_DIG & INT_MAX) > emax-5) {
- if (fabs(y) >= CONCAT(0x1p, LDBL_MANT_DIG)) {
+ if (fabsl(y) >= 2/LDBL_EPSILON) {
if (denormal && bits==LDBL_MANT_DIG+e2-emin)
denormal = 0;
y *= 0.5;