1 // Copyright 2014 The Go 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 big 6 7 import ( 8 "flag" 9 "fmt" 10 "math" 11 "strconv" 12 "strings" 13 "testing" 14 ) 15 16 // Verify that ErrNaN implements the error interface. 17 var _ error = ErrNaN{} 18 19 func (x *Float) uint64() uint64 { 20 u, acc := x.Uint64() 21 if acc != Exact { 22 panic(fmt.Sprintf("%s is not a uint64", x.Text('g', 10))) 23 } 24 return u 25 } 26 27 func (x *Float) int64() int64 { 28 i, acc := x.Int64() 29 if acc != Exact { 30 panic(fmt.Sprintf("%s is not an int64", x.Text('g', 10))) 31 } 32 return i 33 } 34 35 func TestFloatZeroValue(t *testing.T) { 36 // zero (uninitialized) value is a ready-to-use 0.0 37 var x Float 38 if s := x.Text('f', 1); s != "0.0" { 39 t.Errorf("zero value = %s; want 0.0", s) 40 } 41 42 // zero value has precision 0 43 if prec := x.Prec(); prec != 0 { 44 t.Errorf("prec = %d; want 0", prec) 45 } 46 47 // zero value can be used in any and all positions of binary operations 48 make := func(x int) *Float { 49 var f Float 50 if x != 0 { 51 f.SetInt64(int64(x)) 52 } 53 // x == 0 translates into the zero value 54 return &f 55 } 56 for _, test := range []struct { 57 z, x, y, want int 58 opname rune 59 op func(z, x, y *Float) *Float 60 }{ 61 {0, 0, 0, 0, '+', (*Float).Add}, 62 {0, 1, 2, 3, '+', (*Float).Add}, 63 {1, 2, 0, 2, '+', (*Float).Add}, 64 {2, 0, 1, 1, '+', (*Float).Add}, 65 66 {0, 0, 0, 0, '-', (*Float).Sub}, 67 {0, 1, 2, -1, '-', (*Float).Sub}, 68 {1, 2, 0, 2, '-', (*Float).Sub}, 69 {2, 0, 1, -1, '-', (*Float).Sub}, 70 71 {0, 0, 0, 0, '*', (*Float).Mul}, 72 {0, 1, 2, 2, '*', (*Float).Mul}, 73 {1, 2, 0, 0, '*', (*Float).Mul}, 74 {2, 0, 1, 0, '*', (*Float).Mul}, 75 76 // {0, 0, 0, 0, '/', (*Float).Quo}, // panics 77 {0, 2, 1, 2, '/', (*Float).Quo}, 78 {1, 2, 0, 0, '/', (*Float).Quo}, // = +Inf 79 {2, 0, 1, 0, '/', (*Float).Quo}, 80 } { 81 z := make(test.z) 82 test.op(z, make(test.x), make(test.y)) 83 got := 0 84 if !z.IsInf() { 85 got = int(z.int64()) 86 } 87 if got != test.want { 88 t.Errorf("%d %c %d = %d; want %d", test.x, test.opname, test.y, got, test.want) 89 } 90 } 91 92 // TODO(gri) test how precision is set for zero value results 93 } 94 95 func makeFloat(s string) *Float { 96 x, _, err := ParseFloat(s, 0, 1000, ToNearestEven) 97 if err != nil { 98 panic(err) 99 } 100 return x 101 } 102 103 func TestFloatSetPrec(t *testing.T) { 104 for _, test := range []struct { 105 x string 106 prec uint 107 want string 108 acc Accuracy 109 }{ 110 // prec 0 111 {"0", 0, "0", Exact}, 112 {"-0", 0, "-0", Exact}, 113 {"-Inf", 0, "-Inf", Exact}, 114 {"+Inf", 0, "+Inf", Exact}, 115 {"123", 0, "0", Below}, 116 {"-123", 0, "-0", Above}, 117 118 // prec at upper limit 119 {"0", MaxPrec, "0", Exact}, 120 {"-0", MaxPrec, "-0", Exact}, 121 {"-Inf", MaxPrec, "-Inf", Exact}, 122 {"+Inf", MaxPrec, "+Inf", Exact}, 123 124 // just a few regular cases - general rounding is tested elsewhere 125 {"1.5", 1, "2", Above}, 126 {"-1.5", 1, "-2", Below}, 127 {"123", 1e6, "123", Exact}, 128 {"-123", 1e6, "-123", Exact}, 129 } { 130 x := makeFloat(test.x).SetPrec(test.prec) 131 prec := test.prec 132 if prec > MaxPrec { 133 prec = MaxPrec 134 } 135 if got := x.Prec(); got != prec { 136 t.Errorf("%s.SetPrec(%d).Prec() == %d; want %d", test.x, test.prec, got, prec) 137 } 138 if got, acc := x.String(), x.Acc(); got != test.want || acc != test.acc { 139 t.Errorf("%s.SetPrec(%d) = %s (%s); want %s (%s)", test.x, test.prec, got, acc, test.want, test.acc) 140 } 141 } 142 } 143 144 func TestFloatMinPrec(t *testing.T) { 145 const max = 100 146 for _, test := range []struct { 147 x string 148 want uint 149 }{ 150 {"0", 0}, 151 {"-0", 0}, 152 {"+Inf", 0}, 153 {"-Inf", 0}, 154 {"1", 1}, 155 {"2", 1}, 156 {"3", 2}, 157 {"0x8001", 16}, 158 {"0x8001p-1000", 16}, 159 {"0x8001p+1000", 16}, 160 {"0.1", max}, 161 } { 162 x := makeFloat(test.x).SetPrec(max) 163 if got := x.MinPrec(); got != test.want { 164 t.Errorf("%s.MinPrec() = %d; want %d", test.x, got, test.want) 165 } 166 } 167 } 168 169 func TestFloatSign(t *testing.T) { 170 for _, test := range []struct { 171 x string 172 s int 173 }{ 174 {"-Inf", -1}, 175 {"-1", -1}, 176 {"-0", 0}, 177 {"+0", 0}, 178 {"+1", +1}, 179 {"+Inf", +1}, 180 } { 181 x := makeFloat(test.x) 182 s := x.Sign() 183 if s != test.s { 184 t.Errorf("%s.Sign() = %d; want %d", test.x, s, test.s) 185 } 186 } 187 } 188 189 // alike(x, y) is like x.Cmp(y) == 0 but also considers the sign of 0 (0 != -0). 190 func alike(x, y *Float) bool { 191 return x.Cmp(y) == 0 && x.Signbit() == y.Signbit() 192 } 193 194 func alike32(x, y float32) bool { 195 // we can ignore NaNs 196 return x == y && math.Signbit(float64(x)) == math.Signbit(float64(y)) 197 198 } 199 200 func alike64(x, y float64) bool { 201 // we can ignore NaNs 202 return x == y && math.Signbit(x) == math.Signbit(y) 203 204 } 205 206 func TestFloatMantExp(t *testing.T) { 207 for _, test := range []struct { 208 x string 209 mant string 210 exp int 211 }{ 212 {"0", "0", 0}, 213 {"+0", "0", 0}, 214 {"-0", "-0", 0}, 215 {"Inf", "+Inf", 0}, 216 {"+Inf", "+Inf", 0}, 217 {"-Inf", "-Inf", 0}, 218 {"1.5", "0.75", 1}, 219 {"1.024e3", "0.5", 11}, 220 {"-0.125", "-0.5", -2}, 221 } { 222 x := makeFloat(test.x) 223 mant := makeFloat(test.mant) 224 m := new(Float) 225 e := x.MantExp(m) 226 if !alike(m, mant) || e != test.exp { 227 t.Errorf("%s.MantExp() = %s, %d; want %s, %d", test.x, m.Text('g', 10), e, test.mant, test.exp) 228 } 229 } 230 } 231 232 func TestFloatMantExpAliasing(t *testing.T) { 233 x := makeFloat("0.5p10") 234 if e := x.MantExp(x); e != 10 { 235 t.Fatalf("Float.MantExp aliasing error: got %d; want 10", e) 236 } 237 if want := makeFloat("0.5"); !alike(x, want) { 238 t.Fatalf("Float.MantExp aliasing error: got %s; want %s", x.Text('g', 10), want.Text('g', 10)) 239 } 240 } 241 242 func TestFloatSetMantExp(t *testing.T) { 243 for _, test := range []struct { 244 frac string 245 exp int 246 z string 247 }{ 248 {"0", 0, "0"}, 249 {"+0", 0, "0"}, 250 {"-0", 0, "-0"}, 251 {"Inf", 1234, "+Inf"}, 252 {"+Inf", -1234, "+Inf"}, 253 {"-Inf", -1234, "-Inf"}, 254 {"0", MinExp, "0"}, 255 {"0.25", MinExp, "+0"}, // exponent underflow 256 {"-0.25", MinExp, "-0"}, // exponent underflow 257 {"1", MaxExp, "+Inf"}, // exponent overflow 258 {"2", MaxExp - 1, "+Inf"}, // exponent overflow 259 {"0.75", 1, "1.5"}, 260 {"0.5", 11, "1024"}, 261 {"-0.5", -2, "-0.125"}, 262 {"32", 5, "1024"}, 263 {"1024", -10, "1"}, 264 } { 265 frac := makeFloat(test.frac) 266 want := makeFloat(test.z) 267 var z Float 268 z.SetMantExp(frac, test.exp) 269 if !alike(&z, want) { 270 t.Errorf("SetMantExp(%s, %d) = %s; want %s", test.frac, test.exp, z.Text('g', 10), test.z) 271 } 272 // test inverse property 273 mant := new(Float) 274 if z.SetMantExp(mant, want.MantExp(mant)).Cmp(want) != 0 { 275 t.Errorf("Inverse property not satisfied: got %s; want %s", z.Text('g', 10), test.z) 276 } 277 } 278 } 279 280 func TestFloatPredicates(t *testing.T) { 281 for _, test := range []struct { 282 x string 283 sign int 284 signbit, inf bool 285 }{ 286 {x: "-Inf", sign: -1, signbit: true, inf: true}, 287 {x: "-1", sign: -1, signbit: true}, 288 {x: "-0", signbit: true}, 289 {x: "0"}, 290 {x: "1", sign: 1}, 291 {x: "+Inf", sign: 1, inf: true}, 292 } { 293 x := makeFloat(test.x) 294 if got := x.Signbit(); got != test.signbit { 295 t.Errorf("(%s).Signbit() = %v; want %v", test.x, got, test.signbit) 296 } 297 if got := x.Sign(); got != test.sign { 298 t.Errorf("(%s).Sign() = %d; want %d", test.x, got, test.sign) 299 } 300 if got := x.IsInf(); got != test.inf { 301 t.Errorf("(%s).IsInf() = %v; want %v", test.x, got, test.inf) 302 } 303 } 304 } 305 306 func TestFloatIsInt(t *testing.T) { 307 for _, test := range []string{ 308 "0 int", 309 "-0 int", 310 "1 int", 311 "-1 int", 312 "0.5", 313 "1.23", 314 "1.23e1", 315 "1.23e2 int", 316 "0.000000001e+8", 317 "0.000000001e+9 int", 318 "1.2345e200 int", 319 "Inf", 320 "+Inf", 321 "-Inf", 322 } { 323 s := strings.TrimSuffix(test, " int") 324 want := s != test 325 if got := makeFloat(s).IsInt(); got != want { 326 t.Errorf("%s.IsInt() == %t", s, got) 327 } 328 } 329 } 330 331 func fromBinary(s string) int64 { 332 x, err := strconv.ParseInt(s, 2, 64) 333 if err != nil { 334 panic(err) 335 } 336 return x 337 } 338 339 func toBinary(x int64) string { 340 return strconv.FormatInt(x, 2) 341 } 342 343 func testFloatRound(t *testing.T, x, r int64, prec uint, mode RoundingMode) { 344 // verify test data 345 var ok bool 346 switch mode { 347 case ToNearestEven, ToNearestAway: 348 ok = true // nothing to do for now 349 case ToZero: 350 if x < 0 { 351 ok = r >= x 352 } else { 353 ok = r <= x 354 } 355 case AwayFromZero: 356 if x < 0 { 357 ok = r <= x 358 } else { 359 ok = r >= x 360 } 361 case ToNegativeInf: 362 ok = r <= x 363 case ToPositiveInf: 364 ok = r >= x 365 default: 366 panic("unreachable") 367 } 368 if !ok { 369 t.Fatalf("incorrect test data for prec = %d, %s: x = %s, r = %s", prec, mode, toBinary(x), toBinary(r)) 370 } 371 372 // compute expected accuracy 373 a := Exact 374 switch { 375 case r < x: 376 a = Below 377 case r > x: 378 a = Above 379 } 380 381 // round 382 f := new(Float).SetMode(mode).SetInt64(x).SetPrec(prec) 383 384 // check result 385 r1 := f.int64() 386 p1 := f.Prec() 387 a1 := f.Acc() 388 if r1 != r || p1 != prec || a1 != a { 389 t.Errorf("round %s (%d bits, %s) incorrect: got %s (%d bits, %s); want %s (%d bits, %s)", 390 toBinary(x), prec, mode, 391 toBinary(r1), p1, a1, 392 toBinary(r), prec, a) 393 return 394 } 395 396 // g and f should be the same 397 // (rounding by SetPrec after SetInt64 using default precision 398 // should be the same as rounding by SetInt64 after setting the 399 // precision) 400 g := new(Float).SetMode(mode).SetPrec(prec).SetInt64(x) 401 if !alike(g, f) { 402 t.Errorf("round %s (%d bits, %s) not symmetric: got %s and %s; want %s", 403 toBinary(x), prec, mode, 404 toBinary(g.int64()), 405 toBinary(r1), 406 toBinary(r), 407 ) 408 return 409 } 410 411 // h and f should be the same 412 // (repeated rounding should be idempotent) 413 h := new(Float).SetMode(mode).SetPrec(prec).Set(f) 414 if !alike(h, f) { 415 t.Errorf("round %s (%d bits, %s) not idempotent: got %s and %s; want %s", 416 toBinary(x), prec, mode, 417 toBinary(h.int64()), 418 toBinary(r1), 419 toBinary(r), 420 ) 421 return 422 } 423 } 424 425 // TestFloatRound tests basic rounding. 426 func TestFloatRound(t *testing.T) { 427 for _, test := range []struct { 428 prec uint 429 x, zero, neven, naway, away string // input, results rounded to prec bits 430 }{ 431 {5, "1000", "1000", "1000", "1000", "1000"}, 432 {5, "1001", "1001", "1001", "1001", "1001"}, 433 {5, "1010", "1010", "1010", "1010", "1010"}, 434 {5, "1011", "1011", "1011", "1011", "1011"}, 435 {5, "1100", "1100", "1100", "1100", "1100"}, 436 {5, "1101", "1101", "1101", "1101", "1101"}, 437 {5, "1110", "1110", "1110", "1110", "1110"}, 438 {5, "1111", "1111", "1111", "1111", "1111"}, 439 440 {4, "1000", "1000", "1000", "1000", "1000"}, 441 {4, "1001", "1001", "1001", "1001", "1001"}, 442 {4, "1010", "1010", "1010", "1010", "1010"}, 443 {4, "1011", "1011", "1011", "1011", "1011"}, 444 {4, "1100", "1100", "1100", "1100", "1100"}, 445 {4, "1101", "1101", "1101", "1101", "1101"}, 446 {4, "1110", "1110", "1110", "1110", "1110"}, 447 {4, "1111", "1111", "1111", "1111", "1111"}, 448 449 {3, "1000", "1000", "1000", "1000", "1000"}, 450 {3, "1001", "1000", "1000", "1010", "1010"}, 451 {3, "1010", "1010", "1010", "1010", "1010"}, 452 {3, "1011", "1010", "1100", "1100", "1100"}, 453 {3, "1100", "1100", "1100", "1100", "1100"}, 454 {3, "1101", "1100", "1100", "1110", "1110"}, 455 {3, "1110", "1110", "1110", "1110", "1110"}, 456 {3, "1111", "1110", "10000", "10000", "10000"}, 457 458 {3, "1000001", "1000000", "1000000", "1000000", "1010000"}, 459 {3, "1001001", "1000000", "1010000", "1010000", "1010000"}, 460 {3, "1010001", "1010000", "1010000", "1010000", "1100000"}, 461 {3, "1011001", "1010000", "1100000", "1100000", "1100000"}, 462 {3, "1100001", "1100000", "1100000", "1100000", "1110000"}, 463 {3, "1101001", "1100000", "1110000", "1110000", "1110000"}, 464 {3, "1110001", "1110000", "1110000", "1110000", "10000000"}, 465 {3, "1111001", "1110000", "10000000", "10000000", "10000000"}, 466 467 {2, "1000", "1000", "1000", "1000", "1000"}, 468 {2, "1001", "1000", "1000", "1000", "1100"}, 469 {2, "1010", "1000", "1000", "1100", "1100"}, 470 {2, "1011", "1000", "1100", "1100", "1100"}, 471 {2, "1100", "1100", "1100", "1100", "1100"}, 472 {2, "1101", "1100", "1100", "1100", "10000"}, 473 {2, "1110", "1100", "10000", "10000", "10000"}, 474 {2, "1111", "1100", "10000", "10000", "10000"}, 475 476 {2, "1000001", "1000000", "1000000", "1000000", "1100000"}, 477 {2, "1001001", "1000000", "1000000", "1000000", "1100000"}, 478 {2, "1010001", "1000000", "1100000", "1100000", "1100000"}, 479 {2, "1011001", "1000000", "1100000", "1100000", "1100000"}, 480 {2, "1100001", "1100000", "1100000", "1100000", "10000000"}, 481 {2, "1101001", "1100000", "1100000", "1100000", "10000000"}, 482 {2, "1110001", "1100000", "10000000", "10000000", "10000000"}, 483 {2, "1111001", "1100000", "10000000", "10000000", "10000000"}, 484 485 {1, "1000", "1000", "1000", "1000", "1000"}, 486 {1, "1001", "1000", "1000", "1000", "10000"}, 487 {1, "1010", "1000", "1000", "1000", "10000"}, 488 {1, "1011", "1000", "1000", "1000", "10000"}, 489 {1, "1100", "1000", "10000", "10000", "10000"}, 490 {1, "1101", "1000", "10000", "10000", "10000"}, 491 {1, "1110", "1000", "10000", "10000", "10000"}, 492 {1, "1111", "1000", "10000", "10000", "10000"}, 493 494 {1, "1000001", "1000000", "1000000", "1000000", "10000000"}, 495 {1, "1001001", "1000000", "1000000", "1000000", "10000000"}, 496 {1, "1010001", "1000000", "1000000", "1000000", "10000000"}, 497 {1, "1011001", "1000000", "1000000", "1000000", "10000000"}, 498 {1, "1100001", "1000000", "10000000", "10000000", "10000000"}, 499 {1, "1101001", "1000000", "10000000", "10000000", "10000000"}, 500 {1, "1110001", "1000000", "10000000", "10000000", "10000000"}, 501 {1, "1111001", "1000000", "10000000", "10000000", "10000000"}, 502 } { 503 x := fromBinary(test.x) 504 z := fromBinary(test.zero) 505 e := fromBinary(test.neven) 506 n := fromBinary(test.naway) 507 a := fromBinary(test.away) 508 prec := test.prec 509 510 testFloatRound(t, x, z, prec, ToZero) 511 testFloatRound(t, x, e, prec, ToNearestEven) 512 testFloatRound(t, x, n, prec, ToNearestAway) 513 testFloatRound(t, x, a, prec, AwayFromZero) 514 515 testFloatRound(t, x, z, prec, ToNegativeInf) 516 testFloatRound(t, x, a, prec, ToPositiveInf) 517 518 testFloatRound(t, -x, -a, prec, ToNegativeInf) 519 testFloatRound(t, -x, -z, prec, ToPositiveInf) 520 } 521 } 522 523 // TestFloatRound24 tests that rounding a float64 to 24 bits 524 // matches IEEE-754 rounding to nearest when converting a 525 // float64 to a float32 (excluding denormal numbers). 526 func TestFloatRound24(t *testing.T) { 527 const x0 = 1<<26 - 0x10 // 11...110000 (26 bits) 528 for d := 0; d <= 0x10; d++ { 529 x := float64(x0 + d) 530 f := new(Float).SetPrec(24).SetFloat64(x) 531 got, _ := f.Float32() 532 want := float32(x) 533 if got != want { 534 t.Errorf("Round(%g, 24) = %g; want %g", x, got, want) 535 } 536 } 537 } 538 539 func TestFloatSetUint64(t *testing.T) { 540 for _, want := range []uint64{ 541 0, 542 1, 543 2, 544 10, 545 100, 546 1<<32 - 1, 547 1 << 32, 548 1<<64 - 1, 549 } { 550 var f Float 551 f.SetUint64(want) 552 if got := f.uint64(); got != want { 553 t.Errorf("got %#x (%s); want %#x", got, f.Text('p', 0), want) 554 } 555 } 556 557 // test basic rounding behavior (exhaustive rounding testing is done elsewhere) 558 const x uint64 = 0x8765432187654321 // 64 bits needed 559 for prec := uint(1); prec <= 64; prec++ { 560 f := new(Float).SetPrec(prec).SetMode(ToZero).SetUint64(x) 561 got := f.uint64() 562 want := x &^ (1<<(64-prec) - 1) // cut off (round to zero) low 64-prec bits 563 if got != want { 564 t.Errorf("got %#x (%s); want %#x", got, f.Text('p', 0), want) 565 } 566 } 567 } 568 569 func TestFloatSetInt64(t *testing.T) { 570 for _, want := range []int64{ 571 0, 572 1, 573 2, 574 10, 575 100, 576 1<<32 - 1, 577 1 << 32, 578 1<<63 - 1, 579 } { 580 for i := range [2]int{} { 581 if i&1 != 0 { 582 want = -want 583 } 584 var f Float 585 f.SetInt64(want) 586 if got := f.int64(); got != want { 587 t.Errorf("got %#x (%s); want %#x", got, f.Text('p', 0), want) 588 } 589 } 590 } 591 592 // test basic rounding behavior (exhaustive rounding testing is done elsewhere) 593 const x int64 = 0x7654321076543210 // 63 bits needed 594 for prec := uint(1); prec <= 63; prec++ { 595 f := new(Float).SetPrec(prec).SetMode(ToZero).SetInt64(x) 596 got := f.int64() 597 want := x &^ (1<<(63-prec) - 1) // cut off (round to zero) low 63-prec bits 598 if got != want { 599 t.Errorf("got %#x (%s); want %#x", got, f.Text('p', 0), want) 600 } 601 } 602 } 603 604 func TestFloatSetFloat64(t *testing.T) { 605 for _, want := range []float64{ 606 0, 607 1, 608 2, 609 12345, 610 1e10, 611 1e100, 612 3.14159265e10, 613 2.718281828e-123, 614 1.0 / 3, 615 math.MaxFloat32, 616 math.MaxFloat64, 617 math.SmallestNonzeroFloat32, 618 math.SmallestNonzeroFloat64, 619 math.Inf(-1), 620 math.Inf(0), 621 -math.Inf(1), 622 } { 623 for i := range [2]int{} { 624 if i&1 != 0 { 625 want = -want 626 } 627 var f Float 628 f.SetFloat64(want) 629 if got, acc := f.Float64(); got != want || acc != Exact { 630 t.Errorf("got %g (%s, %s); want %g (Exact)", got, f.Text('p', 0), acc, want) 631 } 632 } 633 } 634 635 // test basic rounding behavior (exhaustive rounding testing is done elsewhere) 636 const x uint64 = 0x8765432143218 // 53 bits needed 637 for prec := uint(1); prec <= 52; prec++ { 638 f := new(Float).SetPrec(prec).SetMode(ToZero).SetFloat64(float64(x)) 639 got, _ := f.Float64() 640 want := float64(x &^ (1<<(52-prec) - 1)) // cut off (round to zero) low 53-prec bits 641 if got != want { 642 t.Errorf("got %g (%s); want %g", got, f.Text('p', 0), want) 643 } 644 } 645 646 // test NaN 647 defer func() { 648 if p, ok := recover().(ErrNaN); !ok { 649 t.Errorf("got %v; want ErrNaN panic", p) 650 } 651 }() 652 var f Float 653 f.SetFloat64(math.NaN()) 654 // should not reach here 655 t.Errorf("got %s; want ErrNaN panic", f.Text('p', 0)) 656 } 657 658 func TestFloatSetInt(t *testing.T) { 659 for _, want := range []string{ 660 "0", 661 "1", 662 "-1", 663 "1234567890", 664 "123456789012345678901234567890", 665 "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", 666 } { 667 var x Int 668 _, ok := x.SetString(want, 0) 669 if !ok { 670 t.Errorf("invalid integer %s", want) 671 continue 672 } 673 n := x.BitLen() 674 675 var f Float 676 f.SetInt(&x) 677 678 // check precision 679 if n < 64 { 680 n = 64 681 } 682 if prec := f.Prec(); prec != uint(n) { 683 t.Errorf("got prec = %d; want %d", prec, n) 684 } 685 686 // check value 687 got := f.Text('g', 100) 688 if got != want { 689 t.Errorf("got %s (%s); want %s", got, f.Text('p', 0), want) 690 } 691 } 692 693 // TODO(gri) test basic rounding behavior 694 } 695 696 func TestFloatSetRat(t *testing.T) { 697 for _, want := range []string{ 698 "0", 699 "1", 700 "-1", 701 "1234567890", 702 "123456789012345678901234567890", 703 "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", 704 "1.2", 705 "3.14159265", 706 // TODO(gri) expand 707 } { 708 var x Rat 709 _, ok := x.SetString(want) 710 if !ok { 711 t.Errorf("invalid fraction %s", want) 712 continue 713 } 714 n := max(x.Num().BitLen(), x.Denom().BitLen()) 715 716 var f1, f2 Float 717 f2.SetPrec(1000) 718 f1.SetRat(&x) 719 f2.SetRat(&x) 720 721 // check precision when set automatically 722 if n < 64 { 723 n = 64 724 } 725 if prec := f1.Prec(); prec != uint(n) { 726 t.Errorf("got prec = %d; want %d", prec, n) 727 } 728 729 got := f2.Text('g', 100) 730 if got != want { 731 t.Errorf("got %s (%s); want %s", got, f2.Text('p', 0), want) 732 } 733 } 734 } 735 736 func TestFloatSetInf(t *testing.T) { 737 var f Float 738 for _, test := range []struct { 739 signbit bool 740 prec uint 741 want string 742 }{ 743 {false, 0, "+Inf"}, 744 {true, 0, "-Inf"}, 745 {false, 10, "+Inf"}, 746 {true, 30, "-Inf"}, 747 } { 748 x := f.SetPrec(test.prec).SetInf(test.signbit) 749 if got := x.String(); got != test.want || x.Prec() != test.prec { 750 t.Errorf("SetInf(%v) = %s (prec = %d); want %s (prec = %d)", test.signbit, got, x.Prec(), test.want, test.prec) 751 } 752 } 753 } 754 755 func TestFloatUint64(t *testing.T) { 756 for _, test := range []struct { 757 x string 758 out uint64 759 acc Accuracy 760 }{ 761 {"-Inf", 0, Above}, 762 {"-1", 0, Above}, 763 {"-1e-1000", 0, Above}, 764 {"-0", 0, Exact}, 765 {"0", 0, Exact}, 766 {"1e-1000", 0, Below}, 767 {"1", 1, Exact}, 768 {"1.000000000000000000001", 1, Below}, 769 {"12345.0", 12345, Exact}, 770 {"12345.000000000000000000001", 12345, Below}, 771 {"18446744073709551615", 18446744073709551615, Exact}, 772 {"18446744073709551615.000000000000000000001", math.MaxUint64, Below}, 773 {"18446744073709551616", math.MaxUint64, Below}, 774 {"1e10000", math.MaxUint64, Below}, 775 {"+Inf", math.MaxUint64, Below}, 776 } { 777 x := makeFloat(test.x) 778 out, acc := x.Uint64() 779 if out != test.out || acc != test.acc { 780 t.Errorf("%s: got %d (%s); want %d (%s)", test.x, out, acc, test.out, test.acc) 781 } 782 } 783 } 784 785 func TestFloatInt64(t *testing.T) { 786 for _, test := range []struct { 787 x string 788 out int64 789 acc Accuracy 790 }{ 791 {"-Inf", math.MinInt64, Above}, 792 {"-1e10000", math.MinInt64, Above}, 793 {"-9223372036854775809", math.MinInt64, Above}, 794 {"-9223372036854775808.000000000000000000001", math.MinInt64, Above}, 795 {"-9223372036854775808", -9223372036854775808, Exact}, 796 {"-9223372036854775807.000000000000000000001", -9223372036854775807, Above}, 797 {"-9223372036854775807", -9223372036854775807, Exact}, 798 {"-12345.000000000000000000001", -12345, Above}, 799 {"-12345.0", -12345, Exact}, 800 {"-1.000000000000000000001", -1, Above}, 801 {"-1.5", -1, Above}, 802 {"-1", -1, Exact}, 803 {"-1e-1000", 0, Above}, 804 {"0", 0, Exact}, 805 {"1e-1000", 0, Below}, 806 {"1", 1, Exact}, 807 {"1.000000000000000000001", 1, Below}, 808 {"1.5", 1, Below}, 809 {"12345.0", 12345, Exact}, 810 {"12345.000000000000000000001", 12345, Below}, 811 {"9223372036854775807", 9223372036854775807, Exact}, 812 {"9223372036854775807.000000000000000000001", math.MaxInt64, Below}, 813 {"9223372036854775808", math.MaxInt64, Below}, 814 {"1e10000", math.MaxInt64, Below}, 815 {"+Inf", math.MaxInt64, Below}, 816 } { 817 x := makeFloat(test.x) 818 out, acc := x.Int64() 819 if out != test.out || acc != test.acc { 820 t.Errorf("%s: got %d (%s); want %d (%s)", test.x, out, acc, test.out, test.acc) 821 } 822 } 823 } 824 825 func TestFloatFloat32(t *testing.T) { 826 for _, test := range []struct { 827 x string 828 out float32 829 acc Accuracy 830 }{ 831 {"0", 0, Exact}, 832 833 // underflow to zero 834 {"1e-1000", 0, Below}, 835 {"0x0.000002p-127", 0, Below}, 836 {"0x.0000010p-126", 0, Below}, 837 838 // denormals 839 {"1.401298464e-45", math.SmallestNonzeroFloat32, Above}, // rounded up to smallest denormal 840 {"0x.ffffff8p-149", math.SmallestNonzeroFloat32, Above}, // rounded up to smallest denormal 841 {"0x.0000018p-126", math.SmallestNonzeroFloat32, Above}, // rounded up to smallest denormal 842 {"0x.0000020p-126", math.SmallestNonzeroFloat32, Exact}, 843 {"0x.8p-148", math.SmallestNonzeroFloat32, Exact}, 844 {"1p-149", math.SmallestNonzeroFloat32, Exact}, 845 {"0x.fffffep-126", math.Float32frombits(0x7fffff), Exact}, // largest denormal 846 847 // special denormal cases (see issues 14553, 14651) 848 {"0x0.0000001p-126", math.Float32frombits(0x00000000), Below}, // underflow to zero 849 {"0x0.0000008p-126", math.Float32frombits(0x00000000), Below}, // underflow to zero 850 {"0x0.0000010p-126", math.Float32frombits(0x00000000), Below}, // rounded down to even 851 {"0x0.0000011p-126", math.Float32frombits(0x00000001), Above}, // rounded up to smallest denormal 852 {"0x0.0000018p-126", math.Float32frombits(0x00000001), Above}, // rounded up to smallest denormal 853 854 {"0x1.0000000p-149", math.Float32frombits(0x00000001), Exact}, // smallest denormal 855 {"0x0.0000020p-126", math.Float32frombits(0x00000001), Exact}, // smallest denormal 856 {"0x0.fffffe0p-126", math.Float32frombits(0x007fffff), Exact}, // largest denormal 857 {"0x1.0000000p-126", math.Float32frombits(0x00800000), Exact}, // smallest normal 858 859 {"0x0.8p-149", math.Float32frombits(0x000000000), Below}, // rounded down to even 860 {"0x0.9p-149", math.Float32frombits(0x000000001), Above}, // rounded up to smallest denormal 861 {"0x0.ap-149", math.Float32frombits(0x000000001), Above}, // rounded up to smallest denormal 862 {"0x0.bp-149", math.Float32frombits(0x000000001), Above}, // rounded up to smallest denormal 863 {"0x0.cp-149", math.Float32frombits(0x000000001), Above}, // rounded up to smallest denormal 864 865 {"0x1.0p-149", math.Float32frombits(0x000000001), Exact}, // smallest denormal 866 {"0x1.7p-149", math.Float32frombits(0x000000001), Below}, 867 {"0x1.8p-149", math.Float32frombits(0x000000002), Above}, 868 {"0x1.9p-149", math.Float32frombits(0x000000002), Above}, 869 870 {"0x2.0p-149", math.Float32frombits(0x000000002), Exact}, 871 {"0x2.8p-149", math.Float32frombits(0x000000002), Below}, // rounded down to even 872 {"0x2.9p-149", math.Float32frombits(0x000000003), Above}, 873 874 {"0x3.0p-149", math.Float32frombits(0x000000003), Exact}, 875 {"0x3.7p-149", math.Float32frombits(0x000000003), Below}, 876 {"0x3.8p-149", math.Float32frombits(0x000000004), Above}, // rounded up to even 877 878 {"0x4.0p-149", math.Float32frombits(0x000000004), Exact}, 879 {"0x4.8p-149", math.Float32frombits(0x000000004), Below}, // rounded down to even 880 {"0x4.9p-149", math.Float32frombits(0x000000005), Above}, 881 882 // specific case from issue 14553 883 {"0x7.7p-149", math.Float32frombits(0x000000007), Below}, 884 {"0x7.8p-149", math.Float32frombits(0x000000008), Above}, 885 {"0x7.9p-149", math.Float32frombits(0x000000008), Above}, 886 887 // normals 888 {"0x.ffffffp-126", math.Float32frombits(0x00800000), Above}, // rounded up to smallest normal 889 {"1p-126", math.Float32frombits(0x00800000), Exact}, // smallest normal 890 {"0x1.fffffep-126", math.Float32frombits(0x00ffffff), Exact}, 891 {"0x1.ffffffp-126", math.Float32frombits(0x01000000), Above}, // rounded up 892 {"1", 1, Exact}, 893 {"1.000000000000000000001", 1, Below}, 894 {"12345.0", 12345, Exact}, 895 {"12345.000000000000000000001", 12345, Below}, 896 {"0x1.fffffe0p127", math.MaxFloat32, Exact}, 897 {"0x1.fffffe8p127", math.MaxFloat32, Below}, 898 899 // overflow 900 {"0x1.ffffff0p127", float32(math.Inf(+1)), Above}, 901 {"0x1p128", float32(math.Inf(+1)), Above}, 902 {"1e10000", float32(math.Inf(+1)), Above}, 903 {"0x1.ffffff0p2147483646", float32(math.Inf(+1)), Above}, // overflow in rounding 904 905 // inf 906 {"Inf", float32(math.Inf(+1)), Exact}, 907 } { 908 for i := 0; i < 2; i++ { 909 // test both signs 910 tx, tout, tacc := test.x, test.out, test.acc 911 if i != 0 { 912 tx = "-" + tx 913 tout = -tout 914 tacc = -tacc 915 } 916 917 // conversion should match strconv where syntax is agreeable 918 if f, err := strconv.ParseFloat(tx, 32); err == nil && !alike32(float32(f), tout) { 919 t.Errorf("%s: got %g; want %g (incorrect test data)", tx, f, tout) 920 } 921 922 x := makeFloat(tx) 923 out, acc := x.Float32() 924 if !alike32(out, tout) || acc != tacc { 925 t.Errorf("%s: got %g (%#08x, %s); want %g (%#08x, %s)", tx, out, math.Float32bits(out), acc, test.out, math.Float32bits(test.out), tacc) 926 } 927 928 // test that x.SetFloat64(float64(f)).Float32() == f 929 var x2 Float 930 out2, acc2 := x2.SetFloat64(float64(out)).Float32() 931 if !alike32(out2, out) || acc2 != Exact { 932 t.Errorf("idempotency test: got %g (%s); want %g (Exact)", out2, acc2, out) 933 } 934 } 935 } 936 } 937 938 func TestFloatFloat64(t *testing.T) { 939 const smallestNormalFloat64 = 2.2250738585072014e-308 // 1p-1022 940 for _, test := range []struct { 941 x string 942 out float64 943 acc Accuracy 944 }{ 945 {"0", 0, Exact}, 946 947 // underflow to zero 948 {"1e-1000", 0, Below}, 949 {"0x0.0000000000001p-1023", 0, Below}, 950 {"0x0.00000000000008p-1022", 0, Below}, 951 952 // denormals 953 {"0x0.0000000000000cp-1022", math.SmallestNonzeroFloat64, Above}, // rounded up to smallest denormal 954 {"0x0.00000000000010p-1022", math.SmallestNonzeroFloat64, Exact}, // smallest denormal 955 {"0x.8p-1073", math.SmallestNonzeroFloat64, Exact}, 956 {"1p-1074", math.SmallestNonzeroFloat64, Exact}, 957 {"0x.fffffffffffffp-1022", math.Float64frombits(0x000fffffffffffff), Exact}, // largest denormal 958 959 // special denormal cases (see issues 14553, 14651) 960 {"0x0.00000000000001p-1022", math.Float64frombits(0x00000000000000000), Below}, // underflow to zero 961 {"0x0.00000000000004p-1022", math.Float64frombits(0x00000000000000000), Below}, // underflow to zero 962 {"0x0.00000000000008p-1022", math.Float64frombits(0x00000000000000000), Below}, // rounded down to even 963 {"0x0.00000000000009p-1022", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal 964 {"0x0.0000000000000ap-1022", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal 965 966 {"0x0.8p-1074", math.Float64frombits(0x00000000000000000), Below}, // rounded down to even 967 {"0x0.9p-1074", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal 968 {"0x0.ap-1074", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal 969 {"0x0.bp-1074", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal 970 {"0x0.cp-1074", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal 971 972 {"0x1.0p-1074", math.Float64frombits(0x00000000000000001), Exact}, 973 {"0x1.7p-1074", math.Float64frombits(0x00000000000000001), Below}, 974 {"0x1.8p-1074", math.Float64frombits(0x00000000000000002), Above}, 975 {"0x1.9p-1074", math.Float64frombits(0x00000000000000002), Above}, 976 977 {"0x2.0p-1074", math.Float64frombits(0x00000000000000002), Exact}, 978 {"0x2.8p-1074", math.Float64frombits(0x00000000000000002), Below}, // rounded down to even 979 {"0x2.9p-1074", math.Float64frombits(0x00000000000000003), Above}, 980 981 {"0x3.0p-1074", math.Float64frombits(0x00000000000000003), Exact}, 982 {"0x3.7p-1074", math.Float64frombits(0x00000000000000003), Below}, 983 {"0x3.8p-1074", math.Float64frombits(0x00000000000000004), Above}, // rounded up to even 984 985 {"0x4.0p-1074", math.Float64frombits(0x00000000000000004), Exact}, 986 {"0x4.8p-1074", math.Float64frombits(0x00000000000000004), Below}, // rounded down to even 987 {"0x4.9p-1074", math.Float64frombits(0x00000000000000005), Above}, 988 989 // normals 990 {"0x.fffffffffffff8p-1022", math.Float64frombits(0x0010000000000000), Above}, // rounded up to smallest normal 991 {"1p-1022", math.Float64frombits(0x0010000000000000), Exact}, // smallest normal 992 {"1", 1, Exact}, 993 {"1.000000000000000000001", 1, Below}, 994 {"12345.0", 12345, Exact}, 995 {"12345.000000000000000000001", 12345, Below}, 996 {"0x1.fffffffffffff0p1023", math.MaxFloat64, Exact}, 997 {"0x1.fffffffffffff4p1023", math.MaxFloat64, Below}, 998 999 // overflow 1000 {"0x1.fffffffffffff8p1023", math.Inf(+1), Above}, 1001 {"0x1p1024", math.Inf(+1), Above}, 1002 {"1e10000", math.Inf(+1), Above}, 1003 {"0x1.fffffffffffff8p2147483646", math.Inf(+1), Above}, // overflow in rounding 1004 {"Inf", math.Inf(+1), Exact}, 1005 1006 // selected denormalized values that were handled incorrectly in the past 1007 {"0x.fffffffffffffp-1022", smallestNormalFloat64 - math.SmallestNonzeroFloat64, Exact}, 1008 {"4503599627370495p-1074", smallestNormalFloat64 - math.SmallestNonzeroFloat64, Exact}, 1009 1010 // http://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/ 1011 {"2.2250738585072011e-308", 2.225073858507201e-308, Below}, 1012 // http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/ 1013 {"2.2250738585072012e-308", 2.2250738585072014e-308, Above}, 1014 } { 1015 for i := 0; i < 2; i++ { 1016 // test both signs 1017 tx, tout, tacc := test.x, test.out, test.acc 1018 if i != 0 { 1019 tx = "-" + tx 1020 tout = -tout 1021 tacc = -tacc 1022 } 1023 1024 // conversion should match strconv where syntax is agreeable 1025 if f, err := strconv.ParseFloat(tx, 64); err == nil && !alike64(f, tout) { 1026 t.Errorf("%s: got %g; want %g (incorrect test data)", tx, f, tout) 1027 } 1028 1029 x := makeFloat(tx) 1030 out, acc := x.Float64() 1031 if !alike64(out, tout) || acc != tacc { 1032 t.Errorf("%s: got %g (%#016x, %s); want %g (%#016x, %s)", tx, out, math.Float64bits(out), acc, test.out, math.Float64bits(test.out), tacc) 1033 } 1034 1035 // test that x.SetFloat64(f).Float64() == f 1036 var x2 Float 1037 out2, acc2 := x2.SetFloat64(out).Float64() 1038 if !alike64(out2, out) || acc2 != Exact { 1039 t.Errorf("idempotency test: got %g (%s); want %g (Exact)", out2, acc2, out) 1040 } 1041 } 1042 } 1043 } 1044 1045 func TestFloatInt(t *testing.T) { 1046 for _, test := range []struct { 1047 x string 1048 want string 1049 acc Accuracy 1050 }{ 1051 {"0", "0", Exact}, 1052 {"+0", "0", Exact}, 1053 {"-0", "0", Exact}, 1054 {"Inf", "nil", Below}, 1055 {"+Inf", "nil", Below}, 1056 {"-Inf", "nil", Above}, 1057 {"1", "1", Exact}, 1058 {"-1", "-1", Exact}, 1059 {"1.23", "1", Below}, 1060 {"-1.23", "-1", Above}, 1061 {"123e-2", "1", Below}, 1062 {"123e-3", "0", Below}, 1063 {"123e-4", "0", Below}, 1064 {"1e-1000", "0", Below}, 1065 {"-1e-1000", "0", Above}, 1066 {"1e+10", "10000000000", Exact}, 1067 {"1e+100", "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", Exact}, 1068 } { 1069 x := makeFloat(test.x) 1070 res, acc := x.Int(nil) 1071 got := "nil" 1072 if res != nil { 1073 got = res.String() 1074 } 1075 if got != test.want || acc != test.acc { 1076 t.Errorf("%s: got %s (%s); want %s (%s)", test.x, got, acc, test.want, test.acc) 1077 } 1078 } 1079 1080 // check that supplied *Int is used 1081 for _, f := range []string{"0", "1", "-1", "1234"} { 1082 x := makeFloat(f) 1083 i := new(Int) 1084 if res, _ := x.Int(i); res != i { 1085 t.Errorf("(%s).Int is not using supplied *Int", f) 1086 } 1087 } 1088 } 1089 1090 func TestFloatRat(t *testing.T) { 1091 for _, test := range []struct { 1092 x, want string 1093 acc Accuracy 1094 }{ 1095 {"0", "0/1", Exact}, 1096 {"+0", "0/1", Exact}, 1097 {"-0", "0/1", Exact}, 1098 {"Inf", "nil", Below}, 1099 {"+Inf", "nil", Below}, 1100 {"-Inf", "nil", Above}, 1101 {"1", "1/1", Exact}, 1102 {"-1", "-1/1", Exact}, 1103 {"1.25", "5/4", Exact}, 1104 {"-1.25", "-5/4", Exact}, 1105 {"1e10", "10000000000/1", Exact}, 1106 {"1p10", "1024/1", Exact}, 1107 {"-1p-10", "-1/1024", Exact}, 1108 {"3.14159265", "7244019449799623199/2305843009213693952", Exact}, 1109 } { 1110 x := makeFloat(test.x).SetPrec(64) 1111 res, acc := x.Rat(nil) 1112 got := "nil" 1113 if res != nil { 1114 got = res.String() 1115 } 1116 if got != test.want { 1117 t.Errorf("%s: got %s; want %s", test.x, got, test.want) 1118 continue 1119 } 1120 if acc != test.acc { 1121 t.Errorf("%s: got %s; want %s", test.x, acc, test.acc) 1122 continue 1123 } 1124 1125 // inverse conversion 1126 if res != nil { 1127 got := new(Float).SetPrec(64).SetRat(res) 1128 if got.Cmp(x) != 0 { 1129 t.Errorf("%s: got %s; want %s", test.x, got, x) 1130 } 1131 } 1132 } 1133 1134 // check that supplied *Rat is used 1135 for _, f := range []string{"0", "1", "-1", "1234"} { 1136 x := makeFloat(f) 1137 r := new(Rat) 1138 if res, _ := x.Rat(r); res != r { 1139 t.Errorf("(%s).Rat is not using supplied *Rat", f) 1140 } 1141 } 1142 } 1143 1144 func TestFloatAbs(t *testing.T) { 1145 for _, test := range []string{ 1146 "0", 1147 "1", 1148 "1234", 1149 "1.23e-2", 1150 "1e-1000", 1151 "1e1000", 1152 "Inf", 1153 } { 1154 p := makeFloat(test) 1155 a := new(Float).Abs(p) 1156 if !alike(a, p) { 1157 t.Errorf("%s: got %s; want %s", test, a.Text('g', 10), test) 1158 } 1159 1160 n := makeFloat("-" + test) 1161 a.Abs(n) 1162 if !alike(a, p) { 1163 t.Errorf("-%s: got %s; want %s", test, a.Text('g', 10), test) 1164 } 1165 } 1166 } 1167 1168 func TestFloatNeg(t *testing.T) { 1169 for _, test := range []string{ 1170 "0", 1171 "1", 1172 "1234", 1173 "1.23e-2", 1174 "1e-1000", 1175 "1e1000", 1176 "Inf", 1177 } { 1178 p1 := makeFloat(test) 1179 n1 := makeFloat("-" + test) 1180 n2 := new(Float).Neg(p1) 1181 p2 := new(Float).Neg(n2) 1182 if !alike(n2, n1) { 1183 t.Errorf("%s: got %s; want %s", test, n2.Text('g', 10), n1.Text('g', 10)) 1184 } 1185 if !alike(p2, p1) { 1186 t.Errorf("%s: got %s; want %s", test, p2.Text('g', 10), p1.Text('g', 10)) 1187 } 1188 } 1189 } 1190 1191 func TestFloatInc(t *testing.T) { 1192 const n = 10 1193 for _, prec := range precList { 1194 if 1<<prec < n { 1195 continue // prec must be large enough to hold all numbers from 0 to n 1196 } 1197 var x, one Float 1198 x.SetPrec(prec) 1199 one.SetInt64(1) 1200 for i := 0; i < n; i++ { 1201 x.Add(&x, &one) 1202 } 1203 if x.Cmp(new(Float).SetInt64(n)) != 0 { 1204 t.Errorf("prec = %d: got %s; want %d", prec, &x, n) 1205 } 1206 } 1207 } 1208 1209 // Selected precisions with which to run various tests. 1210 var precList = [...]uint{1, 2, 5, 8, 10, 16, 23, 24, 32, 50, 53, 64, 100, 128, 500, 511, 512, 513, 1000, 10000} 1211 1212 // Selected bits with which to run various tests. 1213 // Each entry is a list of bits representing a floating-point number (see fromBits). 1214 var bitsList = [...]Bits{ 1215 {}, // = 0 1216 {0}, // = 1 1217 {1}, // = 2 1218 {-1}, // = 1/2 1219 {10}, // = 2**10 == 1024 1220 {-10}, // = 2**-10 == 1/1024 1221 {100, 10, 1}, // = 2**100 + 2**10 + 2**1 1222 {0, -1, -2, -10}, 1223 // TODO(gri) add more test cases 1224 } 1225 1226 // TestFloatAdd tests Float.Add/Sub by comparing the result of a "manual" 1227 // addition/subtraction of arguments represented by Bits values with the 1228 // respective Float addition/subtraction for a variety of precisions 1229 // and rounding modes. 1230 func TestFloatAdd(t *testing.T) { 1231 for _, xbits := range bitsList { 1232 for _, ybits := range bitsList { 1233 // exact values 1234 x := xbits.Float() 1235 y := ybits.Float() 1236 zbits := xbits.add(ybits) 1237 z := zbits.Float() 1238 1239 for i, mode := range [...]RoundingMode{ToZero, ToNearestEven, AwayFromZero} { 1240 for _, prec := range precList { 1241 got := new(Float).SetPrec(prec).SetMode(mode) 1242 got.Add(x, y) 1243 want := zbits.round(prec, mode) 1244 if got.Cmp(want) != 0 { 1245 t.Errorf("i = %d, prec = %d, %s:\n\t %s %v\n\t+ %s %v\n\t= %s\n\twant %s", 1246 i, prec, mode, x, xbits, y, ybits, got, want) 1247 } 1248 1249 got.Sub(z, x) 1250 want = ybits.round(prec, mode) 1251 if got.Cmp(want) != 0 { 1252 t.Errorf("i = %d, prec = %d, %s:\n\t %s %v\n\t- %s %v\n\t= %s\n\twant %s", 1253 i, prec, mode, z, zbits, x, xbits, got, want) 1254 } 1255 } 1256 } 1257 } 1258 } 1259 } 1260 1261 // TestFloatAdd32 tests that Float.Add/Sub of numbers with 1262 // 24bit mantissa behaves like float32 addition/subtraction 1263 // (excluding denormal numbers). 1264 func TestFloatAdd32(t *testing.T) { 1265 // chose base such that we cross the mantissa precision limit 1266 const base = 1<<26 - 0x10 // 11...110000 (26 bits) 1267 for d := 0; d <= 0x10; d++ { 1268 for i := range [2]int{} { 1269 x0, y0 := float64(base), float64(d) 1270 if i&1 != 0 { 1271 x0, y0 = y0, x0 1272 } 1273 1274 x := NewFloat(x0) 1275 y := NewFloat(y0) 1276 z := new(Float).SetPrec(24) 1277 1278 z.Add(x, y) 1279 got, acc := z.Float32() 1280 want := float32(y0) + float32(x0) 1281 if got != want || acc != Exact { 1282 t.Errorf("d = %d: %g + %g = %g (%s); want %g (Exact)", d, x0, y0, got, acc, want) 1283 } 1284 1285 z.Sub(z, y) 1286 got, acc = z.Float32() 1287 want = float32(want) - float32(y0) 1288 if got != want || acc != Exact { 1289 t.Errorf("d = %d: %g - %g = %g (%s); want %g (Exact)", d, x0+y0, y0, got, acc, want) 1290 } 1291 } 1292 } 1293 } 1294 1295 // TestFloatAdd64 tests that Float.Add/Sub of numbers with 1296 // 53bit mantissa behaves like float64 addition/subtraction. 1297 func TestFloatAdd64(t *testing.T) { 1298 // chose base such that we cross the mantissa precision limit 1299 const base = 1<<55 - 0x10 // 11...110000 (55 bits) 1300 for d := 0; d <= 0x10; d++ { 1301 for i := range [2]int{} { 1302 x0, y0 := float64(base), float64(d) 1303 if i&1 != 0 { 1304 x0, y0 = y0, x0 1305 } 1306 1307 x := NewFloat(x0) 1308 y := NewFloat(y0) 1309 z := new(Float).SetPrec(53) 1310 1311 z.Add(x, y) 1312 got, acc := z.Float64() 1313 want := x0 + y0 1314 if got != want || acc != Exact { 1315 t.Errorf("d = %d: %g + %g = %g (%s); want %g (Exact)", d, x0, y0, got, acc, want) 1316 } 1317 1318 z.Sub(z, y) 1319 got, acc = z.Float64() 1320 want -= y0 1321 if got != want || acc != Exact { 1322 t.Errorf("d = %d: %g - %g = %g (%s); want %g (Exact)", d, x0+y0, y0, got, acc, want) 1323 } 1324 } 1325 } 1326 } 1327 1328 // TestFloatMul tests Float.Mul/Quo by comparing the result of a "manual" 1329 // multiplication/division of arguments represented by Bits values with the 1330 // respective Float multiplication/division for a variety of precisions 1331 // and rounding modes. 1332 func TestFloatMul(t *testing.T) { 1333 for _, xbits := range bitsList { 1334 for _, ybits := range bitsList { 1335 // exact values 1336 x := xbits.Float() 1337 y := ybits.Float() 1338 zbits := xbits.mul(ybits) 1339 z := zbits.Float() 1340 1341 for i, mode := range [...]RoundingMode{ToZero, ToNearestEven, AwayFromZero} { 1342 for _, prec := range precList { 1343 got := new(Float).SetPrec(prec).SetMode(mode) 1344 got.Mul(x, y) 1345 want := zbits.round(prec, mode) 1346 if got.Cmp(want) != 0 { 1347 t.Errorf("i = %d, prec = %d, %s:\n\t %s %v\n\t* %s %v\n\t= %s\n\twant %s", 1348 i, prec, mode, x, xbits, y, ybits, got, want) 1349 } 1350 1351 if x.Sign() == 0 { 1352 continue // ignore div-0 case (not invertable) 1353 } 1354 got.Quo(z, x) 1355 want = ybits.round(prec, mode) 1356 if got.Cmp(want) != 0 { 1357 t.Errorf("i = %d, prec = %d, %s:\n\t %s %v\n\t/ %s %v\n\t= %s\n\twant %s", 1358 i, prec, mode, z, zbits, x, xbits, got, want) 1359 } 1360 } 1361 } 1362 } 1363 } 1364 } 1365 1366 // TestFloatMul64 tests that Float.Mul/Quo of numbers with 1367 // 53bit mantissa behaves like float64 multiplication/division. 1368 func TestFloatMul64(t *testing.T) { 1369 for _, test := range []struct { 1370 x, y float64 1371 }{ 1372 {0, 0}, 1373 {0, 1}, 1374 {1, 1}, 1375 {1, 1.5}, 1376 {1.234, 0.5678}, 1377 {2.718281828, 3.14159265358979}, 1378 {2.718281828e10, 3.14159265358979e-32}, 1379 {1.0 / 3, 1e200}, 1380 } { 1381 for i := range [8]int{} { 1382 x0, y0 := test.x, test.y 1383 if i&1 != 0 { 1384 x0 = -x0 1385 } 1386 if i&2 != 0 { 1387 y0 = -y0 1388 } 1389 if i&4 != 0 { 1390 x0, y0 = y0, x0 1391 } 1392 1393 x := NewFloat(x0) 1394 y := NewFloat(y0) 1395 z := new(Float).SetPrec(53) 1396 1397 z.Mul(x, y) 1398 got, _ := z.Float64() 1399 want := x0 * y0 1400 if got != want { 1401 t.Errorf("%g * %g = %g; want %g", x0, y0, got, want) 1402 } 1403 1404 if y0 == 0 { 1405 continue // avoid division-by-zero 1406 } 1407 z.Quo(z, y) 1408 got, _ = z.Float64() 1409 want /= y0 1410 if got != want { 1411 t.Errorf("%g / %g = %g; want %g", x0*y0, y0, got, want) 1412 } 1413 } 1414 } 1415 } 1416 1417 func TestIssue6866(t *testing.T) { 1418 for _, prec := range precList { 1419 two := new(Float).SetPrec(prec).SetInt64(2) 1420 one := new(Float).SetPrec(prec).SetInt64(1) 1421 three := new(Float).SetPrec(prec).SetInt64(3) 1422 msix := new(Float).SetPrec(prec).SetInt64(-6) 1423 psix := new(Float).SetPrec(prec).SetInt64(+6) 1424 1425 p := new(Float).SetPrec(prec) 1426 z1 := new(Float).SetPrec(prec) 1427 z2 := new(Float).SetPrec(prec) 1428 1429 // z1 = 2 + 1.0/3*-6 1430 p.Quo(one, three) 1431 p.Mul(p, msix) 1432 z1.Add(two, p) 1433 1434 // z2 = 2 - 1.0/3*+6 1435 p.Quo(one, three) 1436 p.Mul(p, psix) 1437 z2.Sub(two, p) 1438 1439 if z1.Cmp(z2) != 0 { 1440 t.Fatalf("prec %d: got z1 = %s != z2 = %s; want z1 == z2\n", prec, z1, z2) 1441 } 1442 if z1.Sign() != 0 { 1443 t.Errorf("prec %d: got z1 = %s; want 0", prec, z1) 1444 } 1445 if z2.Sign() != 0 { 1446 t.Errorf("prec %d: got z2 = %s; want 0", prec, z2) 1447 } 1448 } 1449 } 1450 1451 func TestFloatQuo(t *testing.T) { 1452 // TODO(gri) make the test vary these precisions 1453 preci := 200 // precision of integer part 1454 precf := 20 // precision of fractional part 1455 1456 for i := 0; i < 8; i++ { 1457 // compute accurate (not rounded) result z 1458 bits := Bits{preci - 1} 1459 if i&3 != 0 { 1460 bits = append(bits, 0) 1461 } 1462 if i&2 != 0 { 1463 bits = append(bits, -1) 1464 } 1465 if i&1 != 0 { 1466 bits = append(bits, -precf) 1467 } 1468 z := bits.Float() 1469 1470 // compute accurate x as z*y 1471 y := NewFloat(3.14159265358979323e123) 1472 1473 x := new(Float).SetPrec(z.Prec() + y.Prec()).SetMode(ToZero) 1474 x.Mul(z, y) 1475 1476 // leave for debugging 1477 // fmt.Printf("x = %s\ny = %s\nz = %s\n", x, y, z) 1478 1479 if got := x.Acc(); got != Exact { 1480 t.Errorf("got acc = %s; want exact", got) 1481 } 1482 1483 // round accurate z for a variety of precisions and 1484 // modes and compare against result of x / y. 1485 for _, mode := range [...]RoundingMode{ToZero, ToNearestEven, AwayFromZero} { 1486 for d := -5; d < 5; d++ { 1487 prec := uint(preci + d) 1488 got := new(Float).SetPrec(prec).SetMode(mode).Quo(x, y) 1489 want := bits.round(prec, mode) 1490 if got.Cmp(want) != 0 { 1491 t.Errorf("i = %d, prec = %d, %s:\n\t %s\n\t/ %s\n\t= %s\n\twant %s", 1492 i, prec, mode, x, y, got, want) 1493 } 1494 } 1495 } 1496 } 1497 } 1498 1499 var long = flag.Bool("long", false, "run very long tests") 1500 1501 // TestFloatQuoSmoke tests all divisions x/y for values x, y in the range [-n, +n]; 1502 // it serves as a smoke test for basic correctness of division. 1503 func TestFloatQuoSmoke(t *testing.T) { 1504 n := 10 1505 if *long { 1506 n = 1000 1507 } 1508 1509 const dprec = 3 // max. precision variation 1510 const prec = 10 + dprec // enough bits to hold n precisely 1511 for x := -n; x <= n; x++ { 1512 for y := -n; y < n; y++ { 1513 if y == 0 { 1514 continue 1515 } 1516 1517 a := float64(x) 1518 b := float64(y) 1519 c := a / b 1520 1521 // vary operand precision (only ok as long as a, b can be represented correctly) 1522 for ad := -dprec; ad <= dprec; ad++ { 1523 for bd := -dprec; bd <= dprec; bd++ { 1524 A := new(Float).SetPrec(uint(prec + ad)).SetFloat64(a) 1525 B := new(Float).SetPrec(uint(prec + bd)).SetFloat64(b) 1526 C := new(Float).SetPrec(53).Quo(A, B) // C has float64 mantissa width 1527 1528 cc, acc := C.Float64() 1529 if cc != c { 1530 t.Errorf("%g/%g = %s; want %.5g\n", a, b, C.Text('g', 5), c) 1531 continue 1532 } 1533 if acc != Exact { 1534 t.Errorf("%g/%g got %s result; want exact result", a, b, acc) 1535 } 1536 } 1537 } 1538 } 1539 } 1540 } 1541 1542 // TestFloatArithmeticSpecialValues tests that Float operations produce the 1543 // correct results for combinations of zero (0), finite (1 and 2.71828), 1544 // and infinite (Inf) operands. 1545 func TestFloatArithmeticSpecialValues(t *testing.T) { 1546 zero := 0.0 1547 args := []float64{math.Inf(-1), -2.71828, -1, -zero, zero, 1, 2.71828, math.Inf(1)} 1548 xx := new(Float) 1549 yy := new(Float) 1550 got := new(Float) 1551 want := new(Float) 1552 for i := 0; i < 4; i++ { 1553 for _, x := range args { 1554 xx.SetFloat64(x) 1555 // check conversion is correct 1556 // (no need to do this for y, since we see exactly the 1557 // same values there) 1558 if got, acc := xx.Float64(); got != x || acc != Exact { 1559 t.Errorf("Float(%g) == %g (%s)", x, got, acc) 1560 } 1561 for _, y := range args { 1562 yy.SetFloat64(y) 1563 var ( 1564 op string 1565 z float64 1566 f func(z, x, y *Float) *Float 1567 ) 1568 switch i { 1569 case 0: 1570 op = "+" 1571 z = x + y 1572 f = (*Float).Add 1573 case 1: 1574 op = "-" 1575 z = x - y 1576 f = (*Float).Sub 1577 case 2: 1578 op = "*" 1579 z = x * y 1580 f = (*Float).Mul 1581 case 3: 1582 op = "/" 1583 z = x / y 1584 f = (*Float).Quo 1585 default: 1586 panic("unreachable") 1587 } 1588 var errnan bool // set if execution of f panicked with ErrNaN 1589 // protect execution of f 1590 func() { 1591 defer func() { 1592 if p := recover(); p != nil { 1593 _ = p.(ErrNaN) // re-panic if not ErrNaN 1594 errnan = true 1595 } 1596 }() 1597 f(got, xx, yy) 1598 }() 1599 if math.IsNaN(z) { 1600 if !errnan { 1601 t.Errorf("%5g %s %5g = %5s; want ErrNaN panic", x, op, y, got) 1602 } 1603 continue 1604 } 1605 if errnan { 1606 t.Errorf("%5g %s %5g panicked with ErrNan; want %5s", x, op, y, want) 1607 continue 1608 } 1609 want.SetFloat64(z) 1610 if !alike(got, want) { 1611 t.Errorf("%5g %s %5g = %5s; want %5s", x, op, y, got, want) 1612 } 1613 } 1614 } 1615 } 1616 } 1617 1618 func TestFloatArithmeticOverflow(t *testing.T) { 1619 for _, test := range []struct { 1620 prec uint 1621 mode RoundingMode 1622 op byte 1623 x, y, want string 1624 acc Accuracy 1625 }{ 1626 {4, ToNearestEven, '+', "0", "0", "0", Exact}, // smoke test 1627 {4, ToNearestEven, '+', "0x.8p+0", "0x.8p+0", "0x.8p+1", Exact}, // smoke test 1628 1629 {4, ToNearestEven, '+', "0", "0x.8p2147483647", "0x.8p+2147483647", Exact}, 1630 {4, ToNearestEven, '+', "0x.8p2147483500", "0x.8p2147483647", "0x.8p+2147483647", Below}, // rounded to zero 1631 {4, ToNearestEven, '+', "0x.8p2147483647", "0x.8p2147483647", "+Inf", Above}, // exponent overflow in + 1632 {4, ToNearestEven, '+', "-0x.8p2147483647", "-0x.8p2147483647", "-Inf", Below}, // exponent overflow in + 1633 {4, ToNearestEven, '-', "-0x.8p2147483647", "0x.8p2147483647", "-Inf", Below}, // exponent overflow in - 1634 1635 {4, ToZero, '+', "0x.fp2147483647", "0x.8p2147483643", "0x.fp+2147483647", Below}, // rounded to zero 1636 {4, ToNearestEven, '+', "0x.fp2147483647", "0x.8p2147483643", "+Inf", Above}, // exponent overflow in rounding 1637 {4, AwayFromZero, '+', "0x.fp2147483647", "0x.8p2147483643", "+Inf", Above}, // exponent overflow in rounding 1638 1639 {4, AwayFromZero, '-', "-0x.fp2147483647", "0x.8p2147483644", "-Inf", Below}, // exponent overflow in rounding 1640 {4, ToNearestEven, '-', "-0x.fp2147483647", "0x.8p2147483643", "-Inf", Below}, // exponent overflow in rounding 1641 {4, ToZero, '-', "-0x.fp2147483647", "0x.8p2147483643", "-0x.fp+2147483647", Above}, // rounded to zero 1642 1643 {4, ToNearestEven, '+', "0", "0x.8p-2147483648", "0x.8p-2147483648", Exact}, 1644 {4, ToNearestEven, '+', "0x.8p-2147483648", "0x.8p-2147483648", "0x.8p-2147483647", Exact}, 1645 1646 {4, ToNearestEven, '*', "1", "0x.8p2147483647", "0x.8p+2147483647", Exact}, 1647 {4, ToNearestEven, '*', "2", "0x.8p2147483647", "+Inf", Above}, // exponent overflow in * 1648 {4, ToNearestEven, '*', "-2", "0x.8p2147483647", "-Inf", Below}, // exponent overflow in * 1649 1650 {4, ToNearestEven, '/', "0.5", "0x.8p2147483647", "0x.8p-2147483646", Exact}, 1651 {4, ToNearestEven, '/', "0x.8p+0", "0x.8p2147483647", "0x.8p-2147483646", Exact}, 1652 {4, ToNearestEven, '/', "0x.8p-1", "0x.8p2147483647", "0x.8p-2147483647", Exact}, 1653 {4, ToNearestEven, '/', "0x.8p-2", "0x.8p2147483647", "0x.8p-2147483648", Exact}, 1654 {4, ToNearestEven, '/', "0x.8p-3", "0x.8p2147483647", "0", Below}, // exponent underflow in / 1655 } { 1656 x := makeFloat(test.x) 1657 y := makeFloat(test.y) 1658 z := new(Float).SetPrec(test.prec).SetMode(test.mode) 1659 switch test.op { 1660 case '+': 1661 z.Add(x, y) 1662 case '-': 1663 z.Sub(x, y) 1664 case '*': 1665 z.Mul(x, y) 1666 case '/': 1667 z.Quo(x, y) 1668 default: 1669 panic("unreachable") 1670 } 1671 if got := z.Text('p', 0); got != test.want || z.Acc() != test.acc { 1672 t.Errorf( 1673 "prec = %d (%s): %s %c %s = %s (%s); want %s (%s)", 1674 test.prec, test.mode, x.Text('p', 0), test.op, y.Text('p', 0), got, z.Acc(), test.want, test.acc, 1675 ) 1676 } 1677 } 1678 } 1679 1680 // TODO(gri) Add tests that check correctness in the presence of aliasing. 1681 1682 // For rounding modes ToNegativeInf and ToPositiveInf, rounding is affected 1683 // by the sign of the value to be rounded. Test that rounding happens after 1684 // the sign of a result has been set. 1685 // This test uses specific values that are known to fail if rounding is 1686 // "factored" out before setting the result sign. 1687 func TestFloatArithmeticRounding(t *testing.T) { 1688 for _, test := range []struct { 1689 mode RoundingMode 1690 prec uint 1691 x, y, want int64 1692 op byte 1693 }{ 1694 {ToZero, 3, -0x8, -0x1, -0x8, '+'}, 1695 {AwayFromZero, 3, -0x8, -0x1, -0xa, '+'}, 1696 {ToNegativeInf, 3, -0x8, -0x1, -0xa, '+'}, 1697 1698 {ToZero, 3, -0x8, 0x1, -0x8, '-'}, 1699 {AwayFromZero, 3, -0x8, 0x1, -0xa, '-'}, 1700 {ToNegativeInf, 3, -0x8, 0x1, -0xa, '-'}, 1701 1702 {ToZero, 3, -0x9, 0x1, -0x8, '*'}, 1703 {AwayFromZero, 3, -0x9, 0x1, -0xa, '*'}, 1704 {ToNegativeInf, 3, -0x9, 0x1, -0xa, '*'}, 1705 1706 {ToZero, 3, -0x9, 0x1, -0x8, '/'}, 1707 {AwayFromZero, 3, -0x9, 0x1, -0xa, '/'}, 1708 {ToNegativeInf, 3, -0x9, 0x1, -0xa, '/'}, 1709 } { 1710 var x, y, z Float 1711 x.SetInt64(test.x) 1712 y.SetInt64(test.y) 1713 z.SetPrec(test.prec).SetMode(test.mode) 1714 switch test.op { 1715 case '+': 1716 z.Add(&x, &y) 1717 case '-': 1718 z.Sub(&x, &y) 1719 case '*': 1720 z.Mul(&x, &y) 1721 case '/': 1722 z.Quo(&x, &y) 1723 default: 1724 panic("unreachable") 1725 } 1726 if got, acc := z.Int64(); got != test.want || acc != Exact { 1727 t.Errorf("%s, %d bits: %d %c %d = %d (%s); want %d (Exact)", 1728 test.mode, test.prec, test.x, test.op, test.y, got, acc, test.want, 1729 ) 1730 } 1731 } 1732 } 1733 1734 // TestFloatCmpSpecialValues tests that Cmp produces the correct results for 1735 // combinations of zero (0), finite (1 and 2.71828), and infinite (Inf) 1736 // operands. 1737 func TestFloatCmpSpecialValues(t *testing.T) { 1738 zero := 0.0 1739 args := []float64{math.Inf(-1), -2.71828, -1, -zero, zero, 1, 2.71828, math.Inf(1)} 1740 xx := new(Float) 1741 yy := new(Float) 1742 for i := 0; i < 4; i++ { 1743 for _, x := range args { 1744 xx.SetFloat64(x) 1745 // check conversion is correct 1746 // (no need to do this for y, since we see exactly the 1747 // same values there) 1748 if got, acc := xx.Float64(); got != x || acc != Exact { 1749 t.Errorf("Float(%g) == %g (%s)", x, got, acc) 1750 } 1751 for _, y := range args { 1752 yy.SetFloat64(y) 1753 got := xx.Cmp(yy) 1754 want := 0 1755 switch { 1756 case x < y: 1757 want = -1 1758 case x > y: 1759 want = +1 1760 } 1761 if got != want { 1762 t.Errorf("(%g).Cmp(%g) = %v; want %v", x, y, got, want) 1763 } 1764 } 1765 } 1766 } 1767 } 1768 1769 func BenchmarkFloatAdd(b *testing.B) { 1770 x := new(Float) 1771 y := new(Float) 1772 z := new(Float) 1773 1774 for _, prec := range []uint{10, 1e2, 1e3, 1e4, 1e5} { 1775 x.SetPrec(prec).SetRat(NewRat(1, 3)) 1776 y.SetPrec(prec).SetRat(NewRat(1, 6)) 1777 z.SetPrec(prec) 1778 1779 b.Run(fmt.Sprintf("%v", prec), func(b *testing.B) { 1780 b.ReportAllocs() 1781 for i := 0; i < b.N; i++ { 1782 z.Add(x, y) 1783 } 1784 }) 1785 } 1786 } 1787 1788 func BenchmarkFloatSub(b *testing.B) { 1789 x := new(Float) 1790 y := new(Float) 1791 z := new(Float) 1792 1793 for _, prec := range []uint{10, 1e2, 1e3, 1e4, 1e5} { 1794 x.SetPrec(prec).SetRat(NewRat(1, 3)) 1795 y.SetPrec(prec).SetRat(NewRat(1, 6)) 1796 z.SetPrec(prec) 1797 1798 b.Run(fmt.Sprintf("%v", prec), func(b *testing.B) { 1799 b.ReportAllocs() 1800 for i := 0; i < b.N; i++ { 1801 z.Sub(x, y) 1802 } 1803 }) 1804 } 1805 } 1806