X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=src%2Fmath%2Ffma.c;h=7076d4b9308fbf9b7a0c60801b347c1c5e6c4e40;hb=1701e4f3d46b14c4c4be8a46e64f8eaf15a5c061;hp=5fb9540601c520dac6ce9a519e8c9abe91aed7d7;hpb=2786c7d21611b9fa3b2fe356542cf213e7dd0ba4;p=musl diff --git a/src/math/fma.c b/src/math/fma.c index 5fb95406..7076d4b9 100644 --- a/src/math/fma.c +++ b/src/math/fma.c @@ -41,7 +41,7 @@ static void mul(long double *hi, long double *lo, long double x, long double y) /* assume (long double)(hi+lo) == hi -return an adjusted hi so that rounding it to double is correct +return an adjusted hi so that rounding it to double (or less) precision is correct */ static long double adjust(long double hi, long double lo) { @@ -55,17 +55,25 @@ static long double adjust(long double hi, long double lo) ulo.x = lo; if (uhi.bits.s == ulo.bits.s) uhi.bits.m++; - else + else { uhi.bits.m--; + /* handle underflow and take care of ld80 implicit msb */ + if (uhi.bits.m == (uint64_t)-1/2) { + uhi.bits.m *= 2; + uhi.bits.e--; + } + } return uhi.x; } +/* adjusted add so the result is correct when rounded to double (or less) precision */ static long double dadd(long double x, long double y) { add(&x, &y, x, y); return adjust(x, y); } +/* adjusted mul so the result is correct when rounded to double (or less) precision */ static long double dmul(long double x, long double y) { mul(&x, &y, x, y);