github.com/cznic/mathutil@v0.0.0-20181122101859-297441e03548/int_test.go (about) 1 // Copyright (c) 2018 The mathutil Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package mathutil 6 7 import ( 8 "math/big" 9 "math/rand" 10 "testing" 11 ) 12 13 const bits128 = 128 14 15 var ( 16 rnd = rand.New(rand.NewSource(42)) 17 off128 *big.Int 18 mod128 *big.Int 19 ) 20 21 func init() { 22 mod128 = big.NewInt(0) 23 mod128.SetBit(mod128, bits128, 1) 24 off128 = big.NewInt(0) 25 off128.SetBit(off128, bits128-1, 1) 26 } 27 28 func rnd128() *big.Int { 29 var n big.Int 30 n.SetBit(&n, bits128, 1) 31 n.Rand(rnd, &n) 32 n.Sub(&n, off128) 33 return &n 34 } 35 36 func TestMaxInt128(t *testing.T) { 37 if g, e := MaxInt128.String(), "170141183460469231731687303715884105727"; g != e { 38 t.Fatal(g, e) 39 } 40 } 41 42 func TestMinInt128(t *testing.T) { 43 if g, e := MinInt128.String(), "-170141183460469231731687303715884105728"; g != e { 44 t.Fatal(g, e) 45 } 46 } 47 48 func testInt128Add(t *testing.T, a, b *big.Int) { 49 var x, y Int128 50 if _, err := x.SetBigInt(a); err != nil { 51 t.Fatal(a, err) 52 } 53 54 if _, err := y.SetBigInt(b); err != nil { 55 t.Fatal(b, err) 56 } 57 58 z, gc := x.Add(y) 59 g := z.BigInt() 60 e := big.NewInt(0) 61 e.Add(a, b) 62 ec := e.Cmp(MaxInt128) > 0 || e.Cmp(MinInt128) < 0 63 if gc != ec { 64 t.Fatal(a, b, g, e, gc, ec) 65 } 66 67 if gc { 68 switch { 69 case e.Cmp(MaxInt128) > 0: 70 g.Add(g, mod128) 71 case e.Cmp(MinInt128) < 0: 72 g.Sub(g, mod128) 73 default: 74 t.Fatal() 75 } 76 } 77 78 if g.Cmp(e) != 0 { 79 t.Fatal(a, b, g, e, gc, ec) 80 } 81 } 82 83 func TestInt128Add(t *testing.T) { 84 a := []string{ 85 "0x0", 86 "0x1", 87 "0x3fffffffffffffff", 88 "0x7fffffffffffffff", 89 "0xffffffffffffffff", 90 "0x3fffffffffffffffffffffffffffffff", 91 "0x7fffffffffffffffffffffffffffffff", 92 } 93 for _, i := range []int{-1, 1} { 94 bi := big.NewInt(int64(i)) 95 for _, j := range []int{-1, 1} { 96 bj := big.NewInt(int64(j)) 97 for _, k := range a { 98 bk, ok := big.NewInt(0).SetString(k, 0) 99 if !ok { 100 t.Fatal() 101 } 102 103 for _, l := range a { 104 bl, ok := big.NewInt(0).SetString(l, 0) 105 if !ok { 106 t.Fatal() 107 } 108 109 testInt128Add(t, bk.Mul(bk, bi), bl.Mul(bl, bj)) 110 continue 111 } 112 } 113 } 114 } 115 } 116 117 func TestInt128Add2(t *testing.T) { 118 const n = 500000 119 for i := 0; i < n; i++ { 120 testInt128Add(t, rnd128(), rnd128()) 121 } 122 } 123 124 func TestInt128BigInt(t *testing.T) { 125 for _, v := range []int64{-128, -1, 0, 1, 127} { 126 a := big.NewInt(v) 127 var b Int128 128 if _, err := b.SetBigInt(a); err != nil { 129 t.Fatal(v) 130 } 131 132 c := b.BigInt() 133 if a.Cmp(c) != 0 { 134 t.Fatal(a, c) 135 } 136 } 137 } 138 139 func TestInt128BigInt2(t *testing.T) { 140 const n = 1000000 141 for i := 0; i < n; i++ { 142 a := rnd128() 143 var b Int128 144 if _, err := b.SetBigInt(a); err != nil { 145 t.Fatal(a) 146 } 147 148 c := b.BigInt() 149 if a.Cmp(c) != 0 { 150 t.Fatal(a, c) 151 } 152 } 153 } 154 155 func testInt128Cmp(t *testing.T, a, b *big.Int) { 156 var x, y Int128 157 if _, err := x.SetBigInt(a); err != nil { 158 t.Fatal(a, err) 159 } 160 161 if _, err := y.SetBigInt(b); err != nil { 162 t.Fatal(b, err) 163 } 164 165 if g, e := x.Cmp(y), a.Cmp(b); g != e { 166 t.Fatal(a, b, g, e) 167 } 168 } 169 170 func TestInt128Cmp(t *testing.T) { 171 a := []string{ 172 "0x0", 173 "0x1", 174 "0x3fffffffffffffff", 175 "0x7fffffffffffffff", 176 "0xffffffffffffffff", 177 "0x3fffffffffffffffffffffffffffffff", 178 "0x7fffffffffffffffffffffffffffffff", 179 } 180 for _, i := range []int{-1, 1} { 181 bi := big.NewInt(int64(i)) 182 for _, j := range []int{-1, 1} { 183 bj := big.NewInt(int64(j)) 184 for _, k := range a { 185 bk, ok := big.NewInt(0).SetString(k, 0) 186 if !ok { 187 t.Fatal() 188 } 189 190 for _, l := range a { 191 bl, ok := big.NewInt(0).SetString(l, 0) 192 if !ok { 193 t.Fatal() 194 } 195 196 testInt128Cmp(t, bk.Mul(bk, bi), bl.Mul(bl, bj)) 197 } 198 } 199 } 200 } 201 } 202 203 func TestInt128Cmp2(t *testing.T) { 204 const n = 1000000 205 for i := 0; i < n; i++ { 206 testInt128Cmp(t, rnd128(), rnd128()) 207 } 208 } 209 210 func testInt128Neg(t *testing.T, a *big.Int) { 211 var x Int128 212 if _, err := x.SetBigInt(a); err != nil { 213 t.Fatal(a, err) 214 } 215 216 eok := a.Cmp(MinInt128) != 0 217 y, gok := x.Neg() 218 if g, e := gok, eok; g != e { 219 t.Fatal(a, x, y, gok, eok) 220 } 221 222 if gok { 223 a.Neg(a) 224 } 225 if g, e := y.BigInt(), a; g.Cmp(e) != 0 { 226 t.Fatal(g, e, gok, eok) 227 } 228 } 229 230 func TestInt128Neg(t *testing.T) { 231 a := []string{ 232 "0x0", 233 "0x1", 234 "0x3fffffffffffffff", 235 "0x7fffffffffffffff", 236 "0xffffffffffffffff", 237 "0x3fffffffffffffffffffffffffffffff", 238 "0x7fffffffffffffffffffffffffffffff", 239 } 240 for _, i := range []int{-1, 1} { 241 bi := big.NewInt(int64(i)) 242 for _, k := range a { 243 bk, ok := big.NewInt(0).SetString(k, 0) 244 if !ok { 245 t.Fatal() 246 } 247 248 testInt128Neg(t, bk.Mul(bk, bi)) 249 } 250 } 251 } 252 253 func TestInt128Neg2(t *testing.T) { 254 const n = 1000000 255 for i := 0; i < n; i++ { 256 testInt128Neg(t, rnd128()) 257 } 258 } 259 260 func TestInt128SetInt64(t *testing.T) { 261 const n = 1000000 262 for i := 0; i < n; i++ { 263 r := big.NewInt(0).SetInt64(rnd128().Int64()) 264 var x Int128 265 y := x.SetInt64(r.Int64()) 266 if x.Cmp(y) != 0 { 267 t.Fatal(r, x, y) 268 } 269 270 if g, e := x.BigInt(), r; g.Cmp(e) != 0 { 271 t.Fatal(r, x, g) 272 } 273 } 274 } 275 276 func TestInt128SetUint64(t *testing.T) { 277 const n = 1000000 278 for i := 0; i < n; i++ { 279 r := big.NewInt(0).SetUint64(rnd128().Uint64()) 280 var x Int128 281 y := x.SetUint64(r.Uint64()) 282 if x.Cmp(y) != 0 { 283 t.Fatal(r, x, y) 284 } 285 286 if g, e := x.BigInt(), r; g.Cmp(e) != 0 { 287 t.Fatal(r, x, g) 288 } 289 } 290 }