github.com/ylsGit/go-ethereum@v1.6.5/common/math/big_test.go (about) 1 // Copyright 2017 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package math 18 19 import ( 20 "bytes" 21 "encoding/hex" 22 "math/big" 23 "testing" 24 ) 25 26 func TestHexOrDecimal256(t *testing.T) { 27 tests := []struct { 28 input string 29 num *big.Int 30 ok bool 31 }{ 32 {"", big.NewInt(0), true}, 33 {"0", big.NewInt(0), true}, 34 {"0x0", big.NewInt(0), true}, 35 {"12345678", big.NewInt(12345678), true}, 36 {"0x12345678", big.NewInt(0x12345678), true}, 37 {"0X12345678", big.NewInt(0x12345678), true}, 38 // Tests for leading zero behaviour: 39 {"0123456789", big.NewInt(123456789), true}, // note: not octal 40 {"00", big.NewInt(0), true}, 41 {"0x00", big.NewInt(0), true}, 42 {"0x012345678abc", big.NewInt(0x12345678abc), true}, 43 // Invalid syntax: 44 {"abcdef", nil, false}, 45 {"0xgg", nil, false}, 46 // Larger than 256 bits: 47 {"115792089237316195423570985008687907853269984665640564039457584007913129639936", nil, false}, 48 } 49 for _, test := range tests { 50 var num HexOrDecimal256 51 err := num.UnmarshalText([]byte(test.input)) 52 if (err == nil) != test.ok { 53 t.Errorf("ParseBig(%q) -> (err == nil) == %t, want %t", test.input, err == nil, test.ok) 54 continue 55 } 56 if test.num != nil && (*big.Int)(&num).Cmp(test.num) != 0 { 57 t.Errorf("ParseBig(%q) -> %d, want %d", test.input, (*big.Int)(&num), test.num) 58 } 59 } 60 } 61 62 func TestMustParseBig256(t *testing.T) { 63 defer func() { 64 if recover() == nil { 65 t.Error("MustParseBig should've panicked") 66 } 67 }() 68 MustParseBig256("ggg") 69 } 70 71 func TestBigMax(t *testing.T) { 72 a := big.NewInt(10) 73 b := big.NewInt(5) 74 75 max1 := BigMax(a, b) 76 if max1 != a { 77 t.Errorf("Expected %d got %d", a, max1) 78 } 79 80 max2 := BigMax(b, a) 81 if max2 != a { 82 t.Errorf("Expected %d got %d", a, max2) 83 } 84 } 85 86 func TestBigMin(t *testing.T) { 87 a := big.NewInt(10) 88 b := big.NewInt(5) 89 90 min1 := BigMin(a, b) 91 if min1 != b { 92 t.Errorf("Expected %d got %d", b, min1) 93 } 94 95 min2 := BigMin(b, a) 96 if min2 != b { 97 t.Errorf("Expected %d got %d", b, min2) 98 } 99 } 100 101 func TestFirstBigSet(t *testing.T) { 102 tests := []struct { 103 num *big.Int 104 ix int 105 }{ 106 {big.NewInt(0), 0}, 107 {big.NewInt(1), 0}, 108 {big.NewInt(2), 1}, 109 {big.NewInt(0x100), 8}, 110 } 111 for _, test := range tests { 112 if ix := FirstBitSet(test.num); ix != test.ix { 113 t.Errorf("FirstBitSet(b%b) = %d, want %d", test.num, ix, test.ix) 114 } 115 } 116 } 117 118 func TestPaddedBigBytes(t *testing.T) { 119 tests := []struct { 120 num *big.Int 121 n int 122 result []byte 123 }{ 124 {num: big.NewInt(0), n: 4, result: []byte{0, 0, 0, 0}}, 125 {num: big.NewInt(1), n: 4, result: []byte{0, 0, 0, 1}}, 126 {num: big.NewInt(512), n: 4, result: []byte{0, 0, 2, 0}}, 127 {num: BigPow(2, 32), n: 4, result: []byte{1, 0, 0, 0, 0}}, 128 } 129 for _, test := range tests { 130 if result := PaddedBigBytes(test.num, test.n); !bytes.Equal(result, test.result) { 131 t.Errorf("PaddedBigBytes(%d, %d) = %v, want %v", test.num, test.n, result, test.result) 132 } 133 } 134 } 135 136 func BenchmarkPaddedBigBytes(b *testing.B) { 137 bigint := MustParseBig256("123456789123456789123456789123456789") 138 for i := 0; i < b.N; i++ { 139 PaddedBigBytes(bigint, 32) 140 } 141 } 142 143 func TestReadBits(t *testing.T) { 144 check := func(input string) { 145 want, _ := hex.DecodeString(input) 146 int, _ := new(big.Int).SetString(input, 16) 147 buf := make([]byte, len(want)) 148 ReadBits(int, buf) 149 if !bytes.Equal(buf, want) { 150 t.Errorf("have: %x\nwant: %x", buf, want) 151 } 152 } 153 check("000000000000000000000000000000000000000000000000000000FEFCF3F8F0") 154 check("0000000000012345000000000000000000000000000000000000FEFCF3F8F0") 155 check("18F8F8F1000111000110011100222004330052300000000000000000FEFCF3F8F0") 156 } 157 158 func TestU256(t *testing.T) { 159 tests := []struct{ x, y *big.Int }{ 160 {x: big.NewInt(0), y: big.NewInt(0)}, 161 {x: big.NewInt(1), y: big.NewInt(1)}, 162 {x: BigPow(2, 255), y: BigPow(2, 255)}, 163 {x: BigPow(2, 256), y: big.NewInt(0)}, 164 {x: new(big.Int).Add(BigPow(2, 256), big.NewInt(1)), y: big.NewInt(1)}, 165 // negative values 166 {x: big.NewInt(-1), y: new(big.Int).Sub(BigPow(2, 256), big.NewInt(1))}, 167 {x: big.NewInt(-2), y: new(big.Int).Sub(BigPow(2, 256), big.NewInt(2))}, 168 {x: BigPow(2, -255), y: big.NewInt(1)}, 169 } 170 for _, test := range tests { 171 if y := U256(new(big.Int).Set(test.x)); y.Cmp(test.y) != 0 { 172 t.Errorf("U256(%x) = %x, want %x", test.x, y, test.y) 173 } 174 } 175 } 176 177 func TestS256(t *testing.T) { 178 tests := []struct{ x, y *big.Int }{ 179 {x: big.NewInt(0), y: big.NewInt(0)}, 180 {x: big.NewInt(1), y: big.NewInt(1)}, 181 {x: big.NewInt(2), y: big.NewInt(2)}, 182 { 183 x: new(big.Int).Sub(BigPow(2, 255), big.NewInt(1)), 184 y: new(big.Int).Sub(BigPow(2, 255), big.NewInt(1)), 185 }, 186 { 187 x: BigPow(2, 255), 188 y: new(big.Int).Neg(BigPow(2, 255)), 189 }, 190 { 191 x: new(big.Int).Sub(BigPow(2, 256), big.NewInt(1)), 192 y: big.NewInt(-1), 193 }, 194 { 195 x: new(big.Int).Sub(BigPow(2, 256), big.NewInt(2)), 196 y: big.NewInt(-2), 197 }, 198 } 199 for _, test := range tests { 200 if y := S256(test.x); y.Cmp(test.y) != 0 { 201 t.Errorf("S256(%x) = %x, want %x", test.x, y, test.y) 202 } 203 } 204 } 205 206 func TestExp(t *testing.T) { 207 tests := []struct{ base, exponent, result *big.Int }{ 208 {base: big.NewInt(0), exponent: big.NewInt(0), result: big.NewInt(1)}, 209 {base: big.NewInt(1), exponent: big.NewInt(0), result: big.NewInt(1)}, 210 {base: big.NewInt(1), exponent: big.NewInt(1), result: big.NewInt(1)}, 211 {base: big.NewInt(1), exponent: big.NewInt(2), result: big.NewInt(1)}, 212 {base: big.NewInt(3), exponent: big.NewInt(144), result: MustParseBig256("507528786056415600719754159741696356908742250191663887263627442114881")}, 213 {base: big.NewInt(2), exponent: big.NewInt(255), result: MustParseBig256("57896044618658097711785492504343953926634992332820282019728792003956564819968")}, 214 } 215 for _, test := range tests { 216 if result := Exp(test.base, test.exponent); result.Cmp(test.result) != 0 { 217 t.Errorf("Exp(%d, %d) = %d, want %d", test.base, test.exponent, result, test.result) 218 } 219 } 220 }