Skip to content

Instantly share code, notes, and snippets.

@dmage
Created October 14, 2016 10:06
Show Gist options
  • Save dmage/60fd65933020fd0aaf0eba75b9d3e333 to your computer and use it in GitHub Desktop.
Save dmage/60fd65933020fd0aaf0eba75b9d3e333 to your computer and use it in GitHub Desktop.
package main
import (
"math"
"testing"
)
func Log2Sum(logx, logy float64) float64 {
if logx < logy {
logx, logy = logy, logx
}
if logx-logy < 2 {
p := 1 - math.Exp2(logy-logx)
p2 := p * p
return 1 + logx - (p/2+p2/8+p2*p/24+p2*p2/64)/math.Ln2
}
p := math.Exp2(logy - logx)
p2 := p * p
return logx + (p-p2/2+p2*p/3-p2*p2/4)/math.Ln2
}
func slowLog2Sum(logx, logy float64) float64 {
return math.Log2(math.Pow(2, logx) + math.Pow(2, logy))
}
func TestLog2Sum(t *testing.T) {
for x := 1; x < 200; x++ {
for y := 1; y < 200; y++ {
logx := math.Log2(float64(x))
logy := math.Log2(float64(y))
a := Log2Sum(logx, logy)
b := slowLog2Sum(logx, logy)
if math.Abs(a-b) >= 0.005 {
t.Errorf("Log2(%d + %d) = %f, want %f", x, y, a, b)
}
}
}
for x := float64(1); x < 2e9; x *= 10 {
for y := float64(1); y < 2e9; y *= 10 {
logx := math.Log2(x)
logy := math.Log2(y)
a := Log2Sum(logx, logy)
b := slowLog2Sum(logx, logy)
if math.Abs(a-b) >= 0.00001 {
t.Errorf("Log2(%f + %f) = %f, want %f", x, y, a, b)
}
}
}
}
func BenchmarkLog2Sum(b *testing.B) {
x, y := math.Log2(50), math.Log2(200)
for i := 0; i < b.N; i++ {
Log2Sum(x, y)
}
}
func BenchmarkSlowLog2Sum(b *testing.B) {
x, y := math.Log2(50), math.Log2(200)
for i := 0; i < b.N; i++ {
slowLog2Sum(x, y)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment