Skip to content

Commit

Permalink
Fix strtof decimal rounding close to half least subnormal (bug 18247).
Browse files Browse the repository at this point in the history
Bug 18247 is an off-by-one error in strtof's determination of a
decimal exponent such that any value with that decimal exponent is at
most half the least subnormal and so the appropriate underflowing
value for the rounding mode can be determined with no
multiple-precision computations.  (Whether the value is in fact safe
despite the off-by-one depends on the floating-point format in
question.  It's wrong for float and for m68k ldbl-96 but not for other
supported formats.)  This patch corrects the computation of the
exponent in question to be safe in general, adding a comment
explaining the new computation.

Tested for x86_64.

	[BZ #18247]
	* stdlib/strtod_l.c (____STRTOF_INTERNAL): Decrease minimum
	decimal exponent by 1.
	* stdlib/tst-strtod-round-data: Add more tests.
	* stdlib/tst-strtod-round.c (tests): Regenerated.
  • Loading branch information
Joseph Myers committed Apr 10, 2015
1 parent b3c66c5 commit 5556d30
Show file tree
Hide file tree
Showing 5 changed files with 4,689 additions and 3 deletions.
8 changes: 8 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
2015-04-10 Joseph Myers <joseph@codesourcery.com>

[BZ #18247]
* stdlib/strtod_l.c (____STRTOF_INTERNAL): Decrease minimum
decimal exponent by 1.
* stdlib/tst-strtod-round-data: Add more tests.
* stdlib/tst-strtod-round.c (tests): Regenerated.

2015-04-09 Joseph Myers <joseph@codesourcery.com>

* math/auto-libm-test-in: Add more tests of clog and clog10.
Expand Down
2 changes: 1 addition & 1 deletion NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Version 2.22
17969, 17978, 17987, 17991, 17996, 17998, 17999, 18019, 18020, 18029,
18030, 18032, 18036, 18038, 18039, 18042, 18043, 18046, 18047, 18068,
18080, 18093, 18100, 18104, 18110, 18111, 18128, 18138, 18185, 18197,
18210, 18211.
18210, 18211, 18247.

* A powerpc and powerpc64 optimization for TLS, similar to TLS descriptors
for LD and GD on x86 and x86-64, has been implemented. You will need
Expand Down
13 changes: 11 additions & 2 deletions stdlib/strtod_l.c
Original file line number Diff line number Diff line change
Expand Up @@ -1189,7 +1189,16 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc)
if (__glibc_unlikely (exponent > MAX_10_EXP + 1 - (intmax_t) int_no))
return overflow_value (negative);

if (__glibc_unlikely (exponent < MIN_10_EXP - (DIG + 1)))
/* 10^(MIN_10_EXP-1) is not normal. Thus, 10^(MIN_10_EXP-1) /
2^MANT_DIG is below half the least subnormal, so anything with a
base-10 exponent less than the base-10 exponent (which is
MIN_10_EXP - 1 - ceil(MANT_DIG*log10(2))) of that value
underflows. DIG is floor((MANT_DIG-1)log10(2)), so an exponent
below MIN_10_EXP - (DIG + 3) underflows. But EXPONENT is
actually an exponent multiplied only by a fractional part, not an
integer part, so an exponent below MIN_10_EXP - (DIG + 2)
underflows. */
if (__glibc_unlikely (exponent < MIN_10_EXP - (DIG + 2)))
return underflow_value (negative);

if (int_no > 0)
Expand Down Expand Up @@ -1356,7 +1365,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc)

assert (dig_no > int_no
&& exponent <= 0
&& exponent >= MIN_10_EXP - (DIG + 1));
&& exponent >= MIN_10_EXP - (DIG + 2));

/* We need to compute MANT_DIG - BITS fractional bits that lie
within the mantissa of the result, the following bit for
Expand Down
31 changes: 31 additions & 0 deletions stdlib/tst-strtod-round-data

Large diffs are not rendered by default.

Loading

0 comments on commit 5556d30

Please sign in to comment.