]> Cypherpunks repositories - gostls13.git/commitdiff
math: fix bad shift in Expm1
authorMatthew Dempsky <mdempsky@google.com>
Fri, 30 Oct 2015 02:16:20 +0000 (19:16 -0700)
committerRobert Griesemer <gri@golang.org>
Fri, 30 Oct 2015 22:55:19 +0000 (22:55 +0000)
Noticed by cmd/vet.

Expected values array produced by Python instead of Keisan because:

1) Keisan's website calculator is painfully difficult to copy/paste
values into and out of, and

2) after tediously computing e^(vf[i] * 10) - 1 via Keisan I
discovered that Keisan computing vf[i]*10 in a higher precision was
giving substantially different output values.

Also, testing uses "close" instead of "veryclose" because 386's
assembly implementation produces values for some of the test cases
that fail "veryclose".  Curiously, Expm1(vf[i]*10) is identical to
Exp(vf[i]*10)-1 on 386, whereas with the portable implementation
they're only "veryclose".

Investigating these questions is left to someone else.  I just wanted
to fix the cmd/vet warning.

Fixes #13101.

Change-Id: Ica8f6c267d01aa4cc31f53593e95812746942fbc
Reviewed-on: https://go-review.googlesource.com/16505
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Klaus Post <klauspost@gmail.com>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/math/all_test.go
src/math/expm1.go

index 4838ffc5e1db91e853707d0e47c8080327f0643b..968a7b18372a0e2fbfd825f0950ea625e6fe7386 100644 (file)
@@ -234,6 +234,18 @@ var expm1 = []float64{
        1.842068661871398836913874273e-02,
        -8.3193870863553801814961137573e-02,
 }
+var expm1Large = []float64{
+       4.2031418113550844e+21,
+       4.0690789717473863e+33,
+       -0.9372627915981363e+00,
+       -1.0,
+       7.077694784145933e+41,
+       5.117936223839153e+12,
+       5.124137759001189e+22,
+       7.03546003972584e+11,
+       8.456921800389698e+07,
+       -1.0,
+}
 var exp2 = []float64{
        3.1537839463286288034313104e+01,
        2.1361549283756232296144849e+02,
@@ -1987,6 +1999,12 @@ func TestExpm1(t *testing.T) {
                        t.Errorf("Expm1(%g) = %g, want %g", a, f, expm1[i])
                }
        }
+       for i := 0; i < len(vf); i++ {
+               a := vf[i] * 10
+               if f := Expm1(a); !close(expm1Large[i], f) {
+                       t.Errorf("Expm1(%g) = %g, want %g", a, f, expm1Large[i])
+               }
+       }
        for i := 0; i < len(vfexpm1SC); i++ {
                if f := Expm1(vfexpm1SC[i]); !alike(expm1SC[i], f) {
                        t.Errorf("Expm1(%g) = %g, want %g", vfexpm1SC[i], f, expm1SC[i])
index 064e131161df9c6492fdfd500036d337e1ca2d04..670b96de5e20f2c2683bc717a8100006ec3b880a 100644 (file)
@@ -227,7 +227,7 @@ func expm1(x float64) float64 {
                        y = Float64frombits(Float64bits(y) + uint64(k)<<52) // add k to y's exponent
                        return y
                }
-               t := Float64frombits(uint64((0x3ff - k) << 52)) // 2**-k
+               t := Float64frombits(uint64(0x3ff-k) << 52) // 2**-k
                y := x - (e + t)
                y += 1
                y = Float64frombits(Float64bits(y) + uint64(k)<<52) // add k to y's exponent