-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlog_2_test.go
55 lines (45 loc) · 1.18 KB
/
log_2_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package main
import (
"math/big"
"math/rand"
"testing"
"github.com/ALTree/bigfloat"
)
const FloatOperationPrec = 1024
func getLog2BigFloat(y *big.Int, precision uint, one *big.Float, twoLog *big.Float) (*big.Int, error) {
f := big.NewFloat(0).SetPrec(FloatOperationPrec).SetInt(y)
f.Quo(f, one)
f = bigfloat.Log(f)
f.Quo(f, twoLog)
f.Mul(f, one)
r, _ := f.Int(nil)
return r, nil
}
func FuzzGetLog2(t *testing.F) {
r := rand.New(rand.NewSource(0))
for i := 0; i < 15; i++ {
v := make([]byte, 8)
r.Read(v)
t.Add(v)
}
one := big.NewInt(0).Lsh(big.NewInt(1), 64)
two := big.NewInt(0).Lsh(big.NewInt(2), 64)
oneFloat := big.NewFloat(0).SetPrec(FloatOperationPrec).SetInt(one)
twoLogFloat := bigfloat.Log(big.NewFloat(2).SetPrec(FloatOperationPrec))
t.Fuzz(func(t *testing.T, v []byte) {
if len(v) > 8 {
v = v[:8]
}
x := big.NewInt(0).SetBytes(v)
x.Add(x, one)
l, err := getLog2(x, 64, one, two)
if err != nil {
t.Errorf("failed to get log 2: %s", err.Error())
}
r, _ := getLog2BigFloat(x, 64, oneFloat, twoLogFloat)
diff := big.NewInt(0).Sub(l, r).Int64()
if diff <= -4 || diff >= 4 {
t.Errorf("want: %s\ngot: %s\n", r.String(), l.String())
}
})
}