github.com/cznic/mathutil@v0.0.0-20181122101859-297441e03548/binarylog_test.go (about) 1 // Copyright (c) 2016 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 "fmt" 9 "math/big" 10 "testing" 11 ) 12 13 func TestNewFloat(t *testing.T) { 14 for i, v := range []struct { 15 n0, f0 int 16 n, f int 17 }{ 18 {1, 0, 1, 0}, 19 {2, 0, 2, 0}, 20 {2, 1, 1, 0}, 21 {3, 0, 3, 0}, 22 {3, 1, 3, 1}, 23 {4, 0, 4, 0}, 24 {4, 1, 2, 0}, 25 {4, 2, 1, 0}, 26 } { 27 f := newFloat(big.NewInt(int64(v.n0)), v.f0, 10) 28 if g, e := f.n.Int64(), int64(v.n); g != e { 29 t.Fatal(i, "n", g, e) 30 } 31 32 if g, e := f.fracBits, v.f; g != e { 33 t.Fatal(i, "fracBits", g, e) 34 } 35 } 36 } 37 38 func TestFloatDiv2(t *testing.T) { 39 for i, v := range []struct { 40 n0, f0 int 41 n, f int 42 }{ 43 {1, 0, 1, 1}, 44 {2, 0, 1, 0}, 45 {2, 1, 1, 1}, 46 {3, 0, 3, 1}, 47 {3, 1, 3, 2}, 48 {4, 0, 2, 0}, 49 {4, 1, 1, 0}, 50 {4, 2, 1, 1}, 51 {5, 0, 5, 1}, 52 {5, 1, 5, 2}, 53 {5, 2, 5, 3}, 54 {6, 0, 3, 0}, 55 {6, 1, 3, 1}, 56 {6, 2, 3, 2}, 57 {7, 0, 7, 1}, 58 {7, 1, 7, 2}, 59 {7, 2, 7, 3}, 60 {8, 0, 4, 0}, 61 {8, 1, 2, 0}, 62 {8, 2, 1, 0}, 63 {8, 3, 1, 1}, 64 } { 65 f := newFloat(big.NewInt(int64(v.n0)), v.f0, 10) 66 f.div2() 67 if g, e := f.n.Int64(), int64(v.n); g != e { 68 t.Fatal(i, "n", g, e) 69 } 70 71 if g, e := f.fracBits, v.f; g != e { 72 t.Fatal(i, "fracBits", g, e) 73 } 74 } 75 } 76 77 func TestFloatSqr(t *testing.T) { 78 for i, v := range []struct { 79 n0, f0 int 80 n, f int 81 }{ 82 {1, 1, 1, 2}, 83 {1, 0, 1, 0}, 84 {2, 0, 4, 0}, 85 {2, 1, 1, 0}, 86 {3, 0, 9, 0}, 87 {3, 1, 9, 2}, 88 {4, 0, 16, 0}, 89 {4, 1, 4, 0}, 90 {4, 2, 1, 0}, 91 {5, 0, 25, 0}, 92 {5, 1, 25, 2}, 93 {5, 2, 25, 4}, 94 {6, 0, 36, 0}, 95 {6, 1, 9, 0}, 96 {6, 2, 9, 2}, 97 {7, 0, 49, 0}, 98 {7, 1, 49, 2}, 99 {7, 2, 49, 4}, 100 {8, 0, 64, 0}, 101 {8, 1, 16, 0}, 102 {8, 2, 4, 0}, 103 {8, 3, 1, 0}, 104 {9, 0, 81, 0}, 105 {9, 1, 81, 2}, 106 } { 107 f := newFloat(big.NewInt(int64(v.n0)), v.f0, 10) 108 f.sqr() 109 if g, e := f.n.Int64(), int64(v.n); g != e { 110 t.Fatal(i, "n", g, e) 111 } 112 113 if g, e := f.fracBits, v.f; g != e { 114 t.Fatal(i, "fracBits", g, e) 115 } 116 } 117 } 118 119 func TestFloatEq1(t *testing.T) { 120 for i, v := range []struct { 121 n0, f0 int 122 b bool 123 }{ 124 {1, 1, false}, 125 {1, 0, true}, 126 {2, 0, false}, 127 {2, 1, true}, 128 {3, 0, false}, 129 {3, 1, false}, 130 {4, 0, false}, 131 {4, 1, false}, 132 {4, 2, true}, 133 {5, 0, false}, 134 {5, 1, false}, 135 {5, 2, false}, 136 } { 137 f := newFloat(big.NewInt(int64(v.n0)), v.f0, 10) 138 if g, e := f.eq1(), v.b; g != e { 139 t.Fatal(i, g, e) 140 } 141 } 142 } 143 144 func TestFloatGe2(t *testing.T) { 145 for i, v := range []struct { 146 n0, f0 int 147 b bool 148 }{ 149 {1, 1, false}, 150 {1, 0, false}, 151 {2, 0, true}, 152 {2, 1, false}, 153 {3, 0, true}, 154 {3, 1, false}, 155 {4, 0, true}, 156 {4, 1, true}, 157 {4, 2, false}, 158 {5, 0, true}, 159 {5, 1, true}, 160 {5, 2, false}, 161 } { 162 f := newFloat(big.NewInt(int64(v.n0)), v.f0, 10) 163 if g, e := f.ge2(), v.b; g != e { 164 t.Fatal(i, g, e) 165 } 166 } 167 } 168 169 func TestFloatMaxFracBits(t *testing.T) { 170 for i, v := range []struct { 171 n0, f0 int 172 n, f int 173 }{ 174 {1, 0, 1, 0}, 175 {2, 0, 4, 0}, 176 {3, 0, 9, 0}, 177 } { 178 f := newFloat(big.NewInt(int64(v.n0)), v.f0, 0) 179 f.sqr() 180 if g, e := f.n.Int64(), int64(v.n); g != e { 181 t.Fatal(i, "n", g, e) 182 } 183 184 if g, e := f.fracBits, v.f; g != e { 185 t.Fatal(i, "fracBits", g, e) 186 } 187 } 188 for i, v := range []struct { 189 n0, f0 int 190 n, f int 191 }{ 192 {1, 0, 1, 0}, 193 {2, 0, 4, 0}, 194 {2, 1, 1, 0}, 195 {3, 0, 9, 0}, 196 {3, 1, 5, 1}, 197 {4, 0, 16, 0}, 198 {4, 1, 4, 0}, 199 {5, 0, 25, 0}, 200 {5, 1, 13, 1}, 201 {6, 0, 36, 0}, 202 {6, 1, 9, 0}, 203 {7, 0, 49, 0}, 204 {7, 1, 25, 1}, 205 {8, 0, 64, 0}, 206 {8, 1, 16, 0}, 207 } { 208 f := newFloat(big.NewInt(int64(v.n0)), v.f0, 1) 209 f.sqr() 210 if g, e := f.n.Int64(), int64(v.n); g != e { 211 t.Fatal(i, "n", g, e) 212 } 213 214 if g, e := f.fracBits, v.f; g != e { 215 t.Fatal(i, "fracBits", g, e) 216 } 217 } 218 for i, v := range []struct { 219 n0, f0 int 220 n, f int 221 }{ 222 {1, 0, 1, 0}, 223 {2, 0, 4, 0}, 224 {2, 1, 1, 0}, 225 {3, 0, 9, 0}, 226 {3, 1, 9, 2}, 227 {4, 0, 16, 0}, 228 {4, 1, 4, 0}, 229 {4, 2, 1, 0}, 230 {5, 0, 25, 0}, 231 {5, 1, 25, 2}, 232 {5, 2, 3, 1}, 233 {6, 0, 36, 0}, 234 {6, 1, 9, 0}, 235 {6, 2, 9, 2}, 236 {7, 0, 49, 0}, 237 {7, 1, 49, 2}, 238 {7, 2, 3, 0}, 239 {8, 0, 64, 0}, 240 {8, 1, 16, 0}, 241 {8, 2, 4, 0}, 242 {9, 0, 81, 0}, 243 {9, 1, 81, 2}, 244 {9, 2, 5, 0}, 245 } { 246 f := newFloat(big.NewInt(int64(v.n0)), v.f0, 2) 247 f.sqr() 248 if g, e := f.n.Int64(), int64(v.n); g != e { 249 t.Fatal(i, "n", g, e) 250 } 251 252 if g, e := f.fracBits, v.f; g != e { 253 t.Fatal(i, "fracBits", g, e) 254 } 255 } 256 for i, v := range []struct { 257 n0, f0 int 258 n, f int 259 }{ 260 {1, 0, 1, 0}, 261 {2, 0, 4, 0}, 262 {2, 1, 1, 0}, 263 {3, 0, 9, 0}, 264 {3, 1, 9, 2}, 265 {4, 0, 16, 0}, 266 {4, 1, 4, 0}, 267 {4, 2, 1, 0}, 268 {5, 0, 25, 0}, 269 {5, 1, 25, 2}, 270 {5, 2, 13, 3}, 271 {6, 0, 36, 0}, 272 {6, 1, 9, 0}, 273 {6, 2, 9, 2}, 274 {7, 0, 49, 0}, 275 {7, 1, 49, 2}, 276 {7, 2, 25, 3}, 277 {8, 0, 64, 0}, 278 {8, 1, 16, 0}, 279 {8, 2, 4, 0}, 280 {8, 3, 1, 0}, 281 {9, 0, 81, 0}, 282 {9, 1, 81, 2}, 283 {9, 2, 41, 3}, 284 {9, 3, 5, 2}, 285 {10, 0, 100, 0}, 286 {10, 1, 25, 0}, 287 {10, 2, 25, 2}, 288 {10, 3, 13, 3}, 289 {11, 0, 121, 0}, 290 {11, 1, 121, 2}, 291 {11, 2, 61, 3}, 292 {11, 3, 15, 3}, 293 } { 294 f := newFloat(big.NewInt(int64(v.n0)), v.f0, 3) 295 f.sqr() 296 if g, e := f.n.Int64(), int64(v.n); g != e { 297 t.Fatal(i, "n", g, e) 298 } 299 300 if g, e := f.fracBits, v.f; g != e { 301 t.Fatal(i, "fracBits", g, e) 302 } 303 } 304 } 305 306 func TestBinaryLog(t *testing.T) { 307 for i, v := range []struct { 308 n, b int 309 c int 310 m string 311 }{ 312 {1, 0, 0, "0"}, 313 {1, 1, 0, "0"}, 314 {2, 0, 1, "0"}, 315 {2, 1, 1, "0"}, 316 {3, 0, 1, "0"}, 317 {3, 1, 1, "1"}, 318 {3, 2, 1, "10"}, 319 {3, 3, 1, "100"}, 320 {3, 4, 1, "1001"}, 321 {3, 20, 1, "10010101110000000001"}, 322 {42, 20, 5, "1100100011011101110"}, 323 {700, 20, 9, "1110011100000101001"}, 324 } { 325 c, m := BinaryLog(big.NewInt(int64(v.n)), v.b) 326 if g, e := c, v.c; g != e { 327 t.Fatalf("characteristic[%v]: %v %v", i, g, e) 328 } 329 330 if g, e := fmt.Sprintf("%b", m), v.m; g != e { 331 t.Fatalf("mantissa[%v]: %v %v", i, g, e) 332 } 333 } 334 } 335 336 func ExampleBinaryLog() { 337 const mantBits = 257 338 x, _ := big.NewInt(0).SetString("89940344608680314083397671686667731393131665861770496634981932531495305005604", 10) 339 c, m := BinaryLog(x, mantBits) 340 f := big.NewFloat(0).SetPrec(mantBits).SetInt(m) 341 f = f.SetMantExp(f, -mantBits) 342 f.Add(f, big.NewFloat(float64(c))) 343 f.Quo(f, big.NewFloat(4)) 344 fmt.Printf("%.75f", f) 345 // Output: 346 // 63.908875905794799149011030723455843229394283193466612998787786375106246936971 347 }