Commit b233ac8f authored by Charles L. Dorian's avatar Charles L. Dorian Committed by Russ Cox

math: Fix off-by-one error in Ilogb and Logb.

Fixes #1141.

R=rsc
CC=adg, golang-dev
https://golang.org/cl/2194047
parent 0e66a13d
...@@ -383,16 +383,16 @@ var log = []float64{ ...@@ -383,16 +383,16 @@ var log = []float64{
2.161703872847352815363655e+00, 2.161703872847352815363655e+00,
} }
var logb = []float64{ var logb = []float64{
3.0000000000000000e+00, 2.0000000000000000e+00,
3.0000000000000000e+00, 2.0000000000000000e+00,
-1.0000000000000000e+00, -2.0000000000000000e+00,
3.0000000000000000e+00,
4.0000000000000000e+00,
2.0000000000000000e+00, 2.0000000000000000e+00,
3.0000000000000000e+00, 3.0000000000000000e+00,
1.0000000000000000e+00,
2.0000000000000000e+00, 2.0000000000000000e+00,
1.0000000000000000e+00, 1.0000000000000000e+00,
4.0000000000000000e+00, 0.0000000000000000e+00,
3.0000000000000000e+00,
} }
var log10 = []float64{ var log10 = []float64{
6.9714316642508290997617083e-01, 6.9714316642508290997617083e-01,
...@@ -1806,8 +1806,9 @@ func TestHypot(t *testing.T) { ...@@ -1806,8 +1806,9 @@ func TestHypot(t *testing.T) {
func TestIlogb(t *testing.T) { func TestIlogb(t *testing.T) {
for i := 0; i < len(vf); i++ { for i := 0; i < len(vf); i++ {
if e := Ilogb(vf[i]); frexp[i].i != e { a := frexp[i].i - 1 // adjust because fr in the interval [½, 1)
t.Errorf("Ilogb(%g) = %d, want %d", vf[i], e, frexp[i].i) if e := Ilogb(vf[i]); a != e {
t.Errorf("Ilogb(%g) = %d, want %d", vf[i], e, a)
} }
} }
for i := 0; i < len(vflogbSC); i++ { for i := 0; i < len(vflogbSC); i++ {
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
package math package math
// Logb(x) returns the binary logarithm of non-zero x. // Logb(x) returns the binary exponent of non-zero x.
// //
// Special cases are: // Special cases are:
// Logb(±Inf) = +Inf // Logb(±Inf) = +Inf
...@@ -22,10 +22,10 @@ func Logb(x float64) float64 { ...@@ -22,10 +22,10 @@ func Logb(x float64) float64 {
case x != x: // IsNaN(x): case x != x: // IsNaN(x):
return x return x
} }
return float64(int((Float64bits(x)>>shift)&mask) - bias) return float64(int((Float64bits(x)>>shift)&mask) - (bias + 1))
} }
// Ilogb(x) returns the binary logarithm of non-zero x as an integer. // Ilogb(x) returns the binary exponent of non-zero x as an integer.
// //
// Special cases are: // Special cases are:
// Ilogb(±Inf) = MaxInt32 // Ilogb(±Inf) = MaxInt32
...@@ -43,5 +43,5 @@ func Ilogb(x float64) int { ...@@ -43,5 +43,5 @@ func Ilogb(x float64) int {
case x < -MaxFloat64 || x > MaxFloat64: // IsInf(x, 0): case x < -MaxFloat64 || x > MaxFloat64: // IsInf(x, 0):
return MaxInt32 return MaxInt32
} }
return int((Float64bits(x)>>shift)&mask) - bias return int((Float64bits(x)>>shift)&mask) - (bias + 1)
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment