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.
16 // Verify that ErrNaN implements the error interface.
17 var _ error
= ErrNaN
{}
19 func (x
*Float
) uint64() uint64 {
22 panic(fmt
.Sprintf("%s is not a uint64", x
.Text('g', 10)))
27 func (x
*Float
) int64() int64 {
30 panic(fmt
.Sprintf("%s is not an int64", x
.Text('g', 10)))
35 func TestFloatZeroValue(t
*testing
.T
) {
36 // zero (uninitialized) value is a ready-to-use 0.0
38 if s
:= x
.Text('f', 1); s
!= "0.0" {
39 t
.Errorf("zero value = %s; want 0.0", s
)
42 // zero value has precision 0
43 if prec
:= x
.Prec(); prec
!= 0 {
44 t
.Errorf("prec = %d; want 0", prec
)
47 // zero value can be used in any and all positions of binary operations
48 make := func(x
int) *Float
{
53 // x == 0 translates into the zero value
56 for _
, test
:= range []struct {
59 op
func(z
, x
, y
*Float
) *Float
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
},
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
},
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
},
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
},
82 test
.op(z
, make(test
.x
), make(test
.y
))
88 t
.Errorf("%d %c %d = %d; want %d", test
.x
, test
.opname
, test
.y
, got
, test
.want
)
92 // TODO(gri) test how precision is set for zero value results
95 func makeFloat(s
string) *Float
{
96 x
, _
, err
:= ParseFloat(s
, 0, 1000, ToNearestEven
)
103 func TestFloatSetPrec(t
*testing
.T
) {
104 for _
, test
:= range []struct {
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
},
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
},
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
},
130 x
:= makeFloat(test
.x
).SetPrec(test
.prec
)
135 if got
:= x
.Prec(); got
!= prec
{
136 t
.Errorf("%s.SetPrec(%d).Prec() == %d; want %d", test
.x
, test
.prec
, got
, prec
)
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
)
144 func TestFloatMinPrec(t
*testing
.T
) {
146 for _
, test
:= range []struct {
158 {"0x8001p-1000", 16},
159 {"0x8001p+1000", 16},
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
)
169 func TestFloatSign(t
*testing
.T
) {
170 for _
, test
:= range []struct {
181 x
:= makeFloat(test
.x
)
184 t
.Errorf("%s.Sign() = %d; want %d", test
.x
, s
, test
.s
)
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()
194 func alike32(x
, y
float32) bool {
195 // we can ignore NaNs
196 return x
== y
&& math
.Signbit(float64(x
)) == math
.Signbit(float64(y
))
200 func alike64(x
, y
float64) bool {
201 // we can ignore NaNs
202 return x
== y
&& math
.Signbit(x
) == math
.Signbit(y
)
206 func TestFloatMantExp(t
*testing
.T
) {
207 for _
, test
:= range []struct {
219 {"1.024e3", "0.5", 11},
220 {"-0.125", "-0.5", -2},
222 x
:= makeFloat(test
.x
)
223 mant
:= makeFloat(test
.mant
)
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
)
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
)
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))
242 func TestFloatSetMantExp(t
*testing
.T
) {
243 for _
, test
:= range []struct {
251 {"Inf", 1234, "+Inf"},
252 {"+Inf", -1234, "+Inf"},
253 {"-Inf", -1234, "-Inf"},
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
261 {"-0.5", -2, "-0.125"},
265 frac
:= makeFloat(test
.frac
)
266 want
:= makeFloat(test
.z
)
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
)
272 // test inverse property
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
)
280 func TestFloatPredicates(t
*testing
.T
) {
281 for _
, test
:= range []struct {
286 {x
: "-Inf", sign
: -1, signbit
: true, inf
: true},
287 {x
: "-1", sign
: -1, signbit
: true},
288 {x
: "-0", signbit
: true},
291 {x
: "+Inf", sign
: 1, inf
: true},
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
)
297 if got
:= x
.Sign(); got
!= test
.sign
{
298 t
.Errorf("(%s).Sign() = %d; want %d", test
.x
, got
, test
.sign
)
300 if got
:= x
.IsInf(); got
!= test
.inf
{
301 t
.Errorf("(%s).IsInf() = %v; want %v", test
.x
, got
, test
.inf
)
306 func TestFloatIsInt(t
*testing
.T
) {
307 for _
, test
:= range []string{
317 "0.000000001e+9 int",
323 s
:= strings
.TrimSuffix(test
, " int")
325 if got
:= makeFloat(s
).IsInt(); got
!= want
{
326 t
.Errorf("%s.IsInt() == %t", s
, got
)
331 func fromBinary(s
string) int64 {
332 x
, err
:= strconv
.ParseInt(s
, 2, 64)
339 func toBinary(x
int64) string {
340 return strconv
.FormatInt(x
, 2)
343 func testFloatRound(t
*testing
.T
, x
, r
int64, prec
uint, mode RoundingMode
) {
347 case ToNearestEven
, ToNearestAway
:
348 ok
= true // nothing to do for now
369 t
.Fatalf("incorrect test data for prec = %d, %s: x = %s, r = %s", prec
, mode
, toBinary(x
), toBinary(r
))
372 // compute expected accuracy
382 f
:= new(Float
).SetMode(mode
).SetInt64(x
).SetPrec(prec
)
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
)
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
400 g
:= new(Float
).SetMode(mode
).SetPrec(prec
).SetInt64(x
)
402 t
.Errorf("round %s (%d bits, %s) not symmetric: got %s and %s; want %s",
403 toBinary(x
), prec
, mode
,
411 // h and f should be the same
412 // (repeated rounding should be idempotent)
413 h
:= new(Float
).SetMode(mode
).SetPrec(prec
).Set(f
)
415 t
.Errorf("round %s (%d bits, %s) not idempotent: got %s and %s; want %s",
416 toBinary(x
), prec
, mode
,
425 // TestFloatRound tests basic rounding.
426 func TestFloatRound(t
*testing
.T
) {
427 for _
, test
:= range []struct {
429 x
, zero
, neven
, naway
, away
string // input, results rounded to prec bits
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"},
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"},
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"},
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"},
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"},
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"},
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"},
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"},
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
)
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
)
515 testFloatRound(t
, x
, z
, prec
, ToNegativeInf
)
516 testFloatRound(t
, x
, a
, prec
, ToPositiveInf
)
518 testFloatRound(t
, -x
, -a
, prec
, ToNegativeInf
)
519 testFloatRound(t
, -x
, -z
, prec
, ToPositiveInf
)
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
++ {
530 f
:= new(Float
).SetPrec(24).SetFloat64(x
)
531 got
, _
:= f
.Float32()
534 t
.Errorf("Round(%g, 24) = %g; want %g", x
, got
, want
)
539 func TestFloatSetUint64(t
*testing
.T
) {
540 for _
, want
:= range []uint64{
552 if got
:= f
.uint64(); got
!= want
{
553 t
.Errorf("got %#x (%s); want %#x", got
, f
.Text('p', 0), want
)
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
)
562 want
:= x
&^ (1<<(64-prec
) - 1) // cut off (round to zero) low 64-prec bits
564 t
.Errorf("got %#x (%s); want %#x", got
, f
.Text('p', 0), want
)
569 func TestFloatSetInt64(t
*testing
.T
) {
570 for _
, want
:= range []int64{
580 for i
:= range [2]int{} {
586 if got
:= f
.int64(); got
!= want
{
587 t
.Errorf("got %#x (%s); want %#x", got
, f
.Text('p', 0), want
)
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
)
597 want
:= x
&^ (1<<(63-prec
) - 1) // cut off (round to zero) low 63-prec bits
599 t
.Errorf("got %#x (%s); want %#x", got
, f
.Text('p', 0), want
)
604 func TestFloatSetFloat64(t
*testing
.T
) {
605 for _
, want
:= range []float64{
617 math
.SmallestNonzeroFloat32
,
618 math
.SmallestNonzeroFloat64
,
623 for i
:= range [2]int{} {
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
)
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
642 t
.Errorf("got %g (%s); want %g", got
, f
.Text('p', 0), want
)
648 if p
, ok
:= recover().(ErrNaN
); !ok
{
649 t
.Errorf("got %v; want ErrNaN panic", p
)
653 f
.SetFloat64(math
.NaN())
654 // should not reach here
655 t
.Errorf("got %s; want ErrNaN panic", f
.Text('p', 0))
658 func TestFloatSetInt(t
*testing
.T
) {
659 for _
, want
:= range []string{
664 "123456789012345678901234567890",
665 "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
668 _
, ok
:= x
.SetString(want
, 0)
670 t
.Errorf("invalid integer %s", want
)
682 if prec
:= f
.Prec(); prec
!= uint(n
) {
683 t
.Errorf("got prec = %d; want %d", prec
, n
)
687 got
:= f
.Text('g', 100)
689 t
.Errorf("got %s (%s); want %s", got
, f
.Text('p', 0), want
)
693 // TODO(gri) test basic rounding behavior
696 func TestFloatSetRat(t
*testing
.T
) {
697 for _
, want
:= range []string{
702 "123456789012345678901234567890",
703 "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
709 _
, ok
:= x
.SetString(want
)
711 t
.Errorf("invalid fraction %s", want
)
714 n
:= max(x
.Num().BitLen(), x
.Denom().BitLen())
721 // check precision when set automatically
725 if prec
:= f1
.Prec(); prec
!= uint(n
) {
726 t
.Errorf("got prec = %d; want %d", prec
, n
)
729 got
:= f2
.Text('g', 100)
731 t
.Errorf("got %s (%s); want %s", got
, f2
.Text('p', 0), want
)
736 func TestFloatSetInf(t
*testing
.T
) {
738 for _
, test
:= range []struct {
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
)
755 func TestFloatUint64(t
*testing
.T
) {
756 for _
, test
:= range []struct {
763 {"-1e-1000", 0, Above
},
766 {"1e-1000", 0, Below
},
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
},
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
)
785 func TestFloatInt64(t
*testing
.T
) {
786 for _
, test
:= range []struct {
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
},
803 {"-1e-1000", 0, Above
},
805 {"1e-1000", 0, Below
},
807 {"1.000000000000000000001", 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
},
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
)
825 func TestFloatFloat32(t
*testing
.T
) {
826 for _
, test
:= range []struct {
834 {"1e-1000", 0, Below
},
835 {"0x0.000002p-127", 0, Below
},
836 {"0x.0000010p-126", 0, Below
},
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
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
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
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
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
},
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
},
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
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
},
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
},
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
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
},
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
906 {"Inf", float32(math
.Inf(+1)), Exact
},
908 for i
:= 0; i
< 2; i
++ {
910 tx
, tout
, tacc
:= test
.x
, test
.out
, test
.acc
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
)
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
)
928 // test that x.SetFloat64(float64(f)).Float32() == f
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
)
938 func TestFloatFloat64(t
*testing
.T
) {
939 const smallestNormalFloat64
= 2.2250738585072014e-308 // 1p-1022
940 for _
, test
:= range []struct {
948 {"1e-1000", 0, Below
},
949 {"0x0.0000000000001p-1023", 0, Below
},
950 {"0x0.00000000000008p-1022", 0, Below
},
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
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
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
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
},
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
},
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
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
},
990 {"0x.fffffffffffff8p-1022", math
.Float64frombits(0x0010000000000000), Above
}, // rounded up to smallest normal
991 {"1p-1022", math
.Float64frombits(0x0010000000000000), Exact
}, // smallest normal
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
},
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
},
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
},
1010 // https://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
1011 {"2.2250738585072011e-308", 2.225073858507201e-308, Below
},
1012 // https://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
1013 {"2.2250738585072012e-308", 2.2250738585072014e-308, Above
},
1015 for i
:= 0; i
< 2; i
++ {
1017 tx
, tout
, tacc
:= test
.x
, test
.out
, test
.acc
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
)
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
)
1035 // test that x.SetFloat64(f).Float64() == f
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
)
1045 func TestFloatInt(t
*testing
.T
) {
1046 for _
, test
:= range []struct {
1054 {"Inf", "nil", Below
},
1055 {"+Inf", "nil", Below
},
1056 {"-Inf", "nil", Above
},
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
},
1069 x
:= makeFloat(test
.x
)
1070 res
, acc
:= x
.Int(nil)
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
)
1080 // check that supplied *Int is used
1081 for _
, f
:= range []string{"0", "1", "-1", "1234"} {
1084 if res
, _
:= x
.Int(i
); res
!= i
{
1085 t
.Errorf("(%s).Int is not using supplied *Int", f
)
1090 func TestFloatRat(t
*testing
.T
) {
1091 for _
, test
:= range []struct {
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
},
1110 x
:= makeFloat(test
.x
).SetPrec(64)
1111 res
, acc
:= x
.Rat(nil)
1116 if got
!= test
.want
{
1117 t
.Errorf("%s: got %s; want %s", test
.x
, got
, test
.want
)
1120 if acc
!= test
.acc
{
1121 t
.Errorf("%s: got %s; want %s", test
.x
, acc
, test
.acc
)
1125 // inverse conversion
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
)
1134 // check that supplied *Rat is used
1135 for _
, f
:= range []string{"0", "1", "-1", "1234"} {
1138 if res
, _
:= x
.Rat(r
); res
!= r
{
1139 t
.Errorf("(%s).Rat is not using supplied *Rat", f
)
1144 func TestFloatAbs(t
*testing
.T
) {
1145 for _
, test
:= range []string{
1154 p
:= makeFloat(test
)
1155 a
:= new(Float
).Abs(p
)
1157 t
.Errorf("%s: got %s; want %s", test
, a
.Text('g', 10), test
)
1160 n
:= makeFloat("-" + test
)
1163 t
.Errorf("-%s: got %s; want %s", test
, a
.Text('g', 10), test
)
1168 func TestFloatNeg(t
*testing
.T
) {
1169 for _
, test
:= range []string{
1178 p1
:= makeFloat(test
)
1179 n1
:= makeFloat("-" + test
)
1180 n2
:= new(Float
).Neg(p1
)
1181 p2
:= new(Float
).Neg(n2
)
1183 t
.Errorf("%s: got %s; want %s", test
, n2
.Text('g', 10), n1
.Text('g', 10))
1186 t
.Errorf("%s: got %s; want %s", test
, p2
.Text('g', 10), p1
.Text('g', 10))
1191 func TestFloatInc(t
*testing
.T
) {
1193 for _
, prec
:= range precList
{
1195 continue // prec must be large enough to hold all numbers from 0 to n
1200 for i
:= 0; i
< n
; i
++ {
1203 if x
.Cmp(new(Float
).SetInt64(n
)) != 0 {
1204 t
.Errorf("prec = %d: got %s; want %d", prec
, &x
, n
)
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}
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
{
1219 {10}, // = 2**10 == 1024
1220 {-10}, // = 2**-10 == 1/1024
1221 {100, 10, 1}, // = 2**100 + 2**10 + 2**1
1223 // TODO(gri) add more test cases
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
{
1236 zbits
:= xbits
.add(ybits
)
1239 for i
, mode
:= range [...]RoundingMode
{ToZero
, ToNearestEven
, AwayFromZero
} {
1240 for _
, prec
:= range precList
{
1241 got
:= new(Float
).SetPrec(prec
).SetMode(mode
)
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
)
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
)
1261 // TestFloatAddRoundZero tests Float.Add/Sub rounding when the result is exactly zero.
1262 // x + (-x) or x - x for non-zero x should be +0 in all cases except when
1263 // the rounding mode is ToNegativeInf in which case it should be -0.
1264 func TestFloatAddRoundZero(t
*testing
.T
) {
1265 for _
, mode
:= range [...]RoundingMode
{ToNearestEven
, ToNearestAway
, ToZero
, AwayFromZero
, ToPositiveInf
, ToNegativeInf
} {
1267 y
:= new(Float
).Neg(x
)
1268 want
:= NewFloat(0.0)
1269 if mode
== ToNegativeInf
{
1272 got
:= new(Float
).SetMode(mode
)
1274 if got
.Cmp(want
) != 0 || got
.neg
!= (mode
== ToNegativeInf
) {
1275 t
.Errorf("%s:\n\t %v\n\t+ %v\n\t= %v\n\twant %v",
1276 mode
, x
, y
, got
, want
)
1279 if got
.Cmp(want
) != 0 || got
.neg
!= (mode
== ToNegativeInf
) {
1280 t
.Errorf("%v:\n\t %v\n\t- %v\n\t= %v\n\twant %v",
1281 mode
, x
, x
, got
, want
)
1286 // TestFloatAdd32 tests that Float.Add/Sub of numbers with
1287 // 24bit mantissa behaves like float32 addition/subtraction
1288 // (excluding denormal numbers).
1289 func TestFloatAdd32(t
*testing
.T
) {
1290 // chose base such that we cross the mantissa precision limit
1291 const base
= 1<<26 - 0x10 // 11...110000 (26 bits)
1292 for d
:= 0; d
<= 0x10; d
++ {
1293 for i
:= range [2]int{} {
1294 x0
, y0
:= float64(base
), float64(d
)
1301 z
:= new(Float
).SetPrec(24)
1304 got
, acc
:= z
.Float32()
1305 want
:= float32(y0
) + float32(x0
)
1306 if got
!= want || acc
!= Exact
{
1307 t
.Errorf("d = %d: %g + %g = %g (%s); want %g (Exact)", d
, x0
, y0
, got
, acc
, want
)
1311 got
, acc
= z
.Float32()
1312 want
= float32(want
) - float32(y0
)
1313 if got
!= want || acc
!= Exact
{
1314 t
.Errorf("d = %d: %g - %g = %g (%s); want %g (Exact)", d
, x0
+y0
, y0
, got
, acc
, want
)
1320 // TestFloatAdd64 tests that Float.Add/Sub of numbers with
1321 // 53bit mantissa behaves like float64 addition/subtraction.
1322 func TestFloatAdd64(t
*testing
.T
) {
1323 // chose base such that we cross the mantissa precision limit
1324 const base
= 1<<55 - 0x10 // 11...110000 (55 bits)
1325 for d
:= 0; d
<= 0x10; d
++ {
1326 for i
:= range [2]int{} {
1327 x0
, y0
:= float64(base
), float64(d
)
1334 z
:= new(Float
).SetPrec(53)
1337 got
, acc
:= z
.Float64()
1339 if got
!= want || acc
!= Exact
{
1340 t
.Errorf("d = %d: %g + %g = %g (%s); want %g (Exact)", d
, x0
, y0
, got
, acc
, want
)
1344 got
, acc
= z
.Float64()
1346 if got
!= want || acc
!= Exact
{
1347 t
.Errorf("d = %d: %g - %g = %g (%s); want %g (Exact)", d
, x0
+y0
, y0
, got
, acc
, want
)
1353 func TestIssue20490(t
*testing
.T
) {
1354 var tests
= []struct {
1363 for _
, test
:= range tests
{
1364 a
, b
:= NewFloat(test
.a
), NewFloat(test
.b
)
1365 diff
:= new(Float
).Sub(a
, b
)
1367 if b
.Cmp(diff
) != 0 {
1368 t
.Errorf("got %g - %g = %g; want %g\n", a
, NewFloat(test
.b
), b
, diff
)
1371 b
= NewFloat(test
.b
)
1372 sum
:= new(Float
).Add(a
, b
)
1374 if b
.Cmp(sum
) != 0 {
1375 t
.Errorf("got %g + %g = %g; want %g\n", a
, NewFloat(test
.b
), b
, sum
)
1381 // TestFloatMul tests Float.Mul/Quo by comparing the result of a "manual"
1382 // multiplication/division of arguments represented by Bits values with the
1383 // respective Float multiplication/division for a variety of precisions
1384 // and rounding modes.
1385 func TestFloatMul(t
*testing
.T
) {
1386 for _
, xbits
:= range bitsList
{
1387 for _
, ybits
:= range bitsList
{
1391 zbits
:= xbits
.mul(ybits
)
1394 for i
, mode
:= range [...]RoundingMode
{ToZero
, ToNearestEven
, AwayFromZero
} {
1395 for _
, prec
:= range precList
{
1396 got
:= new(Float
).SetPrec(prec
).SetMode(mode
)
1398 want
:= zbits
.round(prec
, mode
)
1399 if got
.Cmp(want
) != 0 {
1400 t
.Errorf("i = %d, prec = %d, %s:\n\t %v %v\n\t* %v %v\n\t= %v\n\twant %v",
1401 i
, prec
, mode
, x
, xbits
, y
, ybits
, got
, want
)
1405 continue // ignore div-0 case (not invertable)
1408 want
= ybits
.round(prec
, mode
)
1409 if got
.Cmp(want
) != 0 {
1410 t
.Errorf("i = %d, prec = %d, %s:\n\t %v %v\n\t/ %v %v\n\t= %v\n\twant %v",
1411 i
, prec
, mode
, z
, zbits
, x
, xbits
, got
, want
)
1419 // TestFloatMul64 tests that Float.Mul/Quo of numbers with
1420 // 53bit mantissa behaves like float64 multiplication/division.
1421 func TestFloatMul64(t
*testing
.T
) {
1422 for _
, test
:= range []struct {
1430 {2.718281828, 3.14159265358979},
1431 {2.718281828e10
, 3.14159265358979e-32},
1434 for i
:= range [8]int{} {
1435 x0
, y0
:= test
.x
, test
.y
1448 z
:= new(Float
).SetPrec(53)
1451 got
, _
:= z
.Float64()
1454 t
.Errorf("%g * %g = %g; want %g", x0
, y0
, got
, want
)
1458 continue // avoid division-by-zero
1461 got
, _
= z
.Float64()
1464 t
.Errorf("%g / %g = %g; want %g", x0
*y0
, y0
, got
, want
)
1470 func TestIssue6866(t
*testing
.T
) {
1471 for _
, prec
:= range precList
{
1472 two
:= new(Float
).SetPrec(prec
).SetInt64(2)
1473 one
:= new(Float
).SetPrec(prec
).SetInt64(1)
1474 three
:= new(Float
).SetPrec(prec
).SetInt64(3)
1475 msix
:= new(Float
).SetPrec(prec
).SetInt64(-6)
1476 psix
:= new(Float
).SetPrec(prec
).SetInt64(+6)
1478 p
:= new(Float
).SetPrec(prec
)
1479 z1
:= new(Float
).SetPrec(prec
)
1480 z2
:= new(Float
).SetPrec(prec
)
1482 // z1 = 2 + 1.0/3*-6
1487 // z2 = 2 - 1.0/3*+6
1492 if z1
.Cmp(z2
) != 0 {
1493 t
.Fatalf("prec %d: got z1 = %v != z2 = %v; want z1 == z2\n", prec
, z1
, z2
)
1496 t
.Errorf("prec %d: got z1 = %v; want 0", prec
, z1
)
1499 t
.Errorf("prec %d: got z2 = %v; want 0", prec
, z2
)
1504 func TestFloatQuo(t
*testing
.T
) {
1505 // TODO(gri) make the test vary these precisions
1506 preci
:= 200 // precision of integer part
1507 precf
:= 20 // precision of fractional part
1509 for i
:= 0; i
< 8; i
++ {
1510 // compute accurate (not rounded) result z
1511 bits
:= Bits
{preci
- 1}
1513 bits
= append(bits
, 0)
1516 bits
= append(bits
, -1)
1519 bits
= append(bits
, -precf
)
1523 // compute accurate x as z*y
1524 y
:= NewFloat(3.14159265358979323e123
)
1526 x
:= new(Float
).SetPrec(z
.Prec() + y
.Prec()).SetMode(ToZero
)
1529 // leave for debugging
1530 // fmt.Printf("x = %s\ny = %s\nz = %s\n", x, y, z)
1532 if got
:= x
.Acc(); got
!= Exact
{
1533 t
.Errorf("got acc = %s; want exact", got
)
1536 // round accurate z for a variety of precisions and
1537 // modes and compare against result of x / y.
1538 for _
, mode
:= range [...]RoundingMode
{ToZero
, ToNearestEven
, AwayFromZero
} {
1539 for d
:= -5; d
< 5; d
++ {
1540 prec
:= uint(preci
+ d
)
1541 got
:= new(Float
).SetPrec(prec
).SetMode(mode
).Quo(x
, y
)
1542 want
:= bits
.round(prec
, mode
)
1543 if got
.Cmp(want
) != 0 {
1544 t
.Errorf("i = %d, prec = %d, %s:\n\t %s\n\t/ %s\n\t= %s\n\twant %s",
1545 i
, prec
, mode
, x
, y
, got
, want
)
1552 var long
= flag
.Bool("long", false, "run very long tests")
1554 // TestFloatQuoSmoke tests all divisions x/y for values x, y in the range [-n, +n];
1555 // it serves as a smoke test for basic correctness of division.
1556 func TestFloatQuoSmoke(t
*testing
.T
) {
1562 const dprec
= 3 // max. precision variation
1563 const prec
= 10 + dprec
// enough bits to hold n precisely
1564 for x
:= -n
; x
<= n
; x
++ {
1565 for y
:= -n
; y
< n
; y
++ {
1574 // vary operand precision (only ok as long as a, b can be represented correctly)
1575 for ad
:= -dprec
; ad
<= dprec
; ad
++ {
1576 for bd
:= -dprec
; bd
<= dprec
; bd
++ {
1577 A
:= new(Float
).SetPrec(uint(prec
+ ad
)).SetFloat64(a
)
1578 B
:= new(Float
).SetPrec(uint(prec
+ bd
)).SetFloat64(b
)
1579 C
:= new(Float
).SetPrec(53).Quo(A
, B
) // C has float64 mantissa width
1581 cc
, acc
:= C
.Float64()
1583 t
.Errorf("%g/%g = %s; want %.5g\n", a
, b
, C
.Text('g', 5), c
)
1587 t
.Errorf("%g/%g got %s result; want exact result", a
, b
, acc
)
1595 // TestFloatArithmeticSpecialValues tests that Float operations produce the
1596 // correct results for combinations of zero (±0), finite (±1 and ±2.71828),
1597 // and infinite (±Inf) operands.
1598 func TestFloatArithmeticSpecialValues(t
*testing
.T
) {
1600 args
:= []float64{math
.Inf(-1), -2.71828, -1, -zero
, zero
, 1, 2.71828, math
.Inf(1)}
1605 for i
:= 0; i
< 4; i
++ {
1606 for _
, x
:= range args
{
1608 // check conversion is correct
1609 // (no need to do this for y, since we see exactly the
1610 // same values there)
1611 if got
, acc
:= xx
.Float64(); got
!= x || acc
!= Exact
{
1612 t
.Errorf("Float(%g) == %g (%s)", x
, got
, acc
)
1614 for _
, y
:= range args
{
1619 f
func(z
, x
, y
*Float
) *Float
1639 panic("unreachable")
1641 var errnan
bool // set if execution of f panicked with ErrNaN
1642 // protect execution of f
1645 if p
:= recover(); p
!= nil {
1646 _
= p
.(ErrNaN
) // re-panic if not ErrNaN
1654 t
.Errorf("%5g %s %5g = %5s; want ErrNaN panic", x
, op
, y
, got
)
1659 t
.Errorf("%5g %s %5g panicked with ErrNan; want %5s", x
, op
, y
, want
)
1663 if !alike(got
, want
) {
1664 t
.Errorf("%5g %s %5g = %5s; want %5s", x
, op
, y
, got
, want
)
1671 func TestFloatArithmeticOverflow(t
*testing
.T
) {
1672 for _
, test
:= range []struct {
1679 {4, ToNearestEven
, '+', "0", "0", "0", Exact
}, // smoke test
1680 {4, ToNearestEven
, '+', "0x.8p+0", "0x.8p+0", "0x.8p+1", Exact
}, // smoke test
1682 {4, ToNearestEven
, '+', "0", "0x.8p2147483647", "0x.8p+2147483647", Exact
},
1683 {4, ToNearestEven
, '+', "0x.8p2147483500", "0x.8p2147483647", "0x.8p+2147483647", Below
}, // rounded to zero
1684 {4, ToNearestEven
, '+', "0x.8p2147483647", "0x.8p2147483647", "+Inf", Above
}, // exponent overflow in +
1685 {4, ToNearestEven
, '+', "-0x.8p2147483647", "-0x.8p2147483647", "-Inf", Below
}, // exponent overflow in +
1686 {4, ToNearestEven
, '-', "-0x.8p2147483647", "0x.8p2147483647", "-Inf", Below
}, // exponent overflow in -
1688 {4, ToZero
, '+', "0x.fp2147483647", "0x.8p2147483643", "0x.fp+2147483647", Below
}, // rounded to zero
1689 {4, ToNearestEven
, '+', "0x.fp2147483647", "0x.8p2147483643", "+Inf", Above
}, // exponent overflow in rounding
1690 {4, AwayFromZero
, '+', "0x.fp2147483647", "0x.8p2147483643", "+Inf", Above
}, // exponent overflow in rounding
1692 {4, AwayFromZero
, '-', "-0x.fp2147483647", "0x.8p2147483644", "-Inf", Below
}, // exponent overflow in rounding
1693 {4, ToNearestEven
, '-', "-0x.fp2147483647", "0x.8p2147483643", "-Inf", Below
}, // exponent overflow in rounding
1694 {4, ToZero
, '-', "-0x.fp2147483647", "0x.8p2147483643", "-0x.fp+2147483647", Above
}, // rounded to zero
1696 {4, ToNearestEven
, '+', "0", "0x.8p-2147483648", "0x.8p-2147483648", Exact
},
1697 {4, ToNearestEven
, '+', "0x.8p-2147483648", "0x.8p-2147483648", "0x.8p-2147483647", Exact
},
1699 {4, ToNearestEven
, '*', "1", "0x.8p2147483647", "0x.8p+2147483647", Exact
},
1700 {4, ToNearestEven
, '*', "2", "0x.8p2147483647", "+Inf", Above
}, // exponent overflow in *
1701 {4, ToNearestEven
, '*', "-2", "0x.8p2147483647", "-Inf", Below
}, // exponent overflow in *
1703 {4, ToNearestEven
, '/', "0.5", "0x.8p2147483647", "0x.8p-2147483646", Exact
},
1704 {4, ToNearestEven
, '/', "0x.8p+0", "0x.8p2147483647", "0x.8p-2147483646", Exact
},
1705 {4, ToNearestEven
, '/', "0x.8p-1", "0x.8p2147483647", "0x.8p-2147483647", Exact
},
1706 {4, ToNearestEven
, '/', "0x.8p-2", "0x.8p2147483647", "0x.8p-2147483648", Exact
},
1707 {4, ToNearestEven
, '/', "0x.8p-3", "0x.8p2147483647", "0", Below
}, // exponent underflow in /
1709 x
:= makeFloat(test
.x
)
1710 y
:= makeFloat(test
.y
)
1711 z
:= new(Float
).SetPrec(test
.prec
).SetMode(test
.mode
)
1722 panic("unreachable")
1724 if got
:= z
.Text('p', 0); got
!= test
.want || z
.Acc() != test
.acc
{
1726 "prec = %d (%s): %s %c %s = %s (%s); want %s (%s)",
1727 test
.prec
, test
.mode
, x
.Text('p', 0), test
.op
, y
.Text('p', 0), got
, z
.Acc(), test
.want
, test
.acc
,
1733 // TODO(gri) Add tests that check correctness in the presence of aliasing.
1735 // For rounding modes ToNegativeInf and ToPositiveInf, rounding is affected
1736 // by the sign of the value to be rounded. Test that rounding happens after
1737 // the sign of a result has been set.
1738 // This test uses specific values that are known to fail if rounding is
1739 // "factored" out before setting the result sign.
1740 func TestFloatArithmeticRounding(t
*testing
.T
) {
1741 for _
, test
:= range []struct {
1747 {ToZero
, 3, -0x8, -0x1, -0x8, '+'},
1748 {AwayFromZero
, 3, -0x8, -0x1, -0xa, '+'},
1749 {ToNegativeInf
, 3, -0x8, -0x1, -0xa, '+'},
1751 {ToZero
, 3, -0x8, 0x1, -0x8, '-'},
1752 {AwayFromZero
, 3, -0x8, 0x1, -0xa, '-'},
1753 {ToNegativeInf
, 3, -0x8, 0x1, -0xa, '-'},
1755 {ToZero
, 3, -0x9, 0x1, -0x8, '*'},
1756 {AwayFromZero
, 3, -0x9, 0x1, -0xa, '*'},
1757 {ToNegativeInf
, 3, -0x9, 0x1, -0xa, '*'},
1759 {ToZero
, 3, -0x9, 0x1, -0x8, '/'},
1760 {AwayFromZero
, 3, -0x9, 0x1, -0xa, '/'},
1761 {ToNegativeInf
, 3, -0x9, 0x1, -0xa, '/'},
1766 z
.SetPrec(test
.prec
).SetMode(test
.mode
)
1777 panic("unreachable")
1779 if got
, acc
:= z
.Int64(); got
!= test
.want || acc
!= Exact
{
1780 t
.Errorf("%s, %d bits: %d %c %d = %d (%s); want %d (Exact)",
1781 test
.mode
, test
.prec
, test
.x
, test
.op
, test
.y
, got
, acc
, test
.want
,
1787 // TestFloatCmpSpecialValues tests that Cmp produces the correct results for
1788 // combinations of zero (±0), finite (±1 and ±2.71828), and infinite (±Inf)
1790 func TestFloatCmpSpecialValues(t
*testing
.T
) {
1792 args
:= []float64{math
.Inf(-1), -2.71828, -1, -zero
, zero
, 1, 2.71828, math
.Inf(1)}
1795 for i
:= 0; i
< 4; i
++ {
1796 for _
, x
:= range args
{
1798 // check conversion is correct
1799 // (no need to do this for y, since we see exactly the
1800 // same values there)
1801 if got
, acc
:= xx
.Float64(); got
!= x || acc
!= Exact
{
1802 t
.Errorf("Float(%g) == %g (%s)", x
, got
, acc
)
1804 for _
, y
:= range args
{
1815 t
.Errorf("(%g).Cmp(%g) = %v; want %v", x
, y
, got
, want
)
1822 func BenchmarkFloatAdd(b
*testing
.B
) {
1827 for _
, prec
:= range []uint{10, 1e2
, 1e3
, 1e4
, 1e5
} {
1828 x
.SetPrec(prec
).SetRat(NewRat(1, 3))
1829 y
.SetPrec(prec
).SetRat(NewRat(1, 6))
1832 b
.Run(fmt
.Sprintf("%v", prec
), func(b
*testing
.B
) {
1834 for i
:= 0; i
< b
.N
; i
++ {
1841 func BenchmarkFloatSub(b
*testing
.B
) {
1846 for _
, prec
:= range []uint{10, 1e2
, 1e3
, 1e4
, 1e5
} {
1847 x
.SetPrec(prec
).SetRat(NewRat(1, 3))
1848 y
.SetPrec(prec
).SetRat(NewRat(1, 6))
1851 b
.Run(fmt
.Sprintf("%v", prec
), func(b
*testing
.B
) {
1853 for i
:= 0; i
< b
.N
; i
++ {