diff options
author | Robert Griesemer <gri@golang.org> | 2021-04-29 15:01:29 -0700 |
---|---|---|
committer | Robert Griesemer <gri@golang.org> | 2021-04-30 00:13:38 +0000 |
commit | 3498027329a32c77315754054d1591e06349db59 (patch) | |
tree | bcc30130da2e8903014c18df34702ee4e567e5f6 /src/math | |
parent | 02ab8d1a1dc82ce019969221313bfa28911f54a1 (diff) | |
download | go-3498027329a32c77315754054d1591e06349db59.tar.gz go-3498027329a32c77315754054d1591e06349db59.zip |
math: increase precision of math.SmallestNonzeroFloat64
The original value was rounded too early, which lead to the
surprising behavior that float64(math.SmallestNonzeroFloat64 / 2)
wasn't 0. That is, the exact compile-time computation of
math.SmallestNonzeroFloat64 / 2 resulted in a value that was
rounded up when converting to float64. To address this, added 3
more digits to the mantissa, ending in a 0.
While at it, also slightly increased the precision of MaxFloat64
to end in a 0.
Computed exact values via https://play.golang.org/p/yt4KTpIx_wP.
Added a test to verify expected behavior.
In contrast to the other (irrational) constants, expanding these
extreme values to more digits is unlikely to be important as they
are not going to appear in numeric computations except for tests
verifying their correctness (as is the case here).
Re-enabled a disabled test in go/types and types2.
Updates #44057.
Fixes #44058.
Change-Id: I8f363155e02331354e929beabe993c8d8de75646
Reviewed-on: https://go-review.googlesource.com/c/go/+/315170
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/math')
-rw-r--r-- | src/math/all_test.go | 9 | ||||
-rw-r--r-- | src/math/const.go | 4 |
2 files changed, 11 insertions, 2 deletions
diff --git a/src/math/all_test.go b/src/math/all_test.go index d154457999..55c805e199 100644 --- a/src/math/all_test.go +++ b/src/math/all_test.go @@ -3196,6 +3196,15 @@ func TestFloatMinMax(t *testing.T) { } } +func TestFloatMinima(t *testing.T) { + if q := float32(SmallestNonzeroFloat32 / 2); q != 0 { + t.Errorf("float32(SmallestNonzeroFloat32 / 2) = %g, want 0", q) + } + if q := float64(SmallestNonzeroFloat64 / 2); q != 0 { + t.Errorf("float64(SmallestNonzeroFloat64 / 2) = %g, want 0", q) + } +} + var indirectSqrt = Sqrt // TestFloat32Sqrt checks the correctness of the float32 square root optimization result. diff --git a/src/math/const.go b/src/math/const.go index 0fc8715dd0..441b295ed4 100644 --- a/src/math/const.go +++ b/src/math/const.go @@ -31,8 +31,8 @@ const ( MaxFloat32 = 3.40282346638528859811704183484516925440e+38 // 2**127 * (2**24 - 1) / 2**23 SmallestNonzeroFloat32 = 1.401298464324817070923729583289916131280e-45 // 1 / 2**(127 - 1 + 23) - MaxFloat64 = 1.797693134862315708145274237317043567981e+308 // 2**1023 * (2**53 - 1) / 2**52 - SmallestNonzeroFloat64 = 4.940656458412465441765687928682213723651e-324 // 1 / 2**(1023 - 1 + 52) + MaxFloat64 = 1.79769313486231570814527423731704356798070e+308 // 2**1023 * (2**53 - 1) / 2**52 + SmallestNonzeroFloat64 = 4.9406564584124654417656879286822137236505980e-324 // 1 / 2**(1023 - 1 + 52) ) // Integer limit values. |