libgo: update to Go 1.11
[official-gcc.git] / libgo / go / math / big / float_test.go
blob7d6bf034dff8103605f919eb003a2144fefd5167
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.
5 package big
7 import (
8 "flag"
9 "fmt"
10 "math"
11 "strconv"
12 "strings"
13 "testing"
16 // Verify that ErrNaN implements the error interface.
17 var _ error = ErrNaN{}
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)))
24 return u
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)))
32 return i
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)
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 {
49 var f Float
50 if x != 0 {
51 f.SetInt64(int64(x))
53 // x == 0 translates into the zero value
54 return &f
56 for _, test := range []struct {
57 z, x, y, want int
58 opname rune
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},
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())
87 if got != test.want {
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)
97 if err != nil {
98 panic(err)
100 return x
103 func TestFloatSetPrec(t *testing.T) {
104 for _, test := range []struct {
105 x string
106 prec uint
107 want string
108 acc Accuracy
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},
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)
131 prec := test.prec
132 if prec > MaxPrec {
133 prec = MaxPrec
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) {
145 const max = 100
146 for _, test := range []struct {
147 x string
148 want uint
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},
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 {
171 x string
172 s int
174 {"-Inf", -1},
175 {"-1", -1},
176 {"-0", 0},
177 {"+0", 0},
178 {"+1", +1},
179 {"+Inf", +1},
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)
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 {
208 x string
209 mant string
210 exp int
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},
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)
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 {
244 frac string
245 exp int
246 z string
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"},
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)
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)
280 func TestFloatPredicates(t *testing.T) {
281 for _, test := range []struct {
282 x string
283 sign int
284 signbit, inf bool
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},
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{
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",
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)
331 func fromBinary(s string) int64 {
332 x, err := strconv.ParseInt(s, 2, 64)
333 if err != nil {
334 panic(err)
336 return x
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) {
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
355 case AwayFromZero:
356 if x < 0 {
357 ok = r <= x
358 } else {
359 ok = r >= x
361 case ToNegativeInf:
362 ok = r <= x
363 case ToPositiveInf:
364 ok = r >= x
365 default:
366 panic("unreachable")
368 if !ok {
369 t.Fatalf("incorrect test data for prec = %d, %s: x = %s, r = %s", prec, mode, toBinary(x), toBinary(r))
372 // compute expected accuracy
373 a := Exact
374 switch {
375 case r < x:
376 a = Below
377 case r > x:
378 a = Above
381 // round
382 f := new(Float).SetMode(mode).SetInt64(x).SetPrec(prec)
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
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),
408 return
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),
421 return
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
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)
508 prec := test.prec
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++ {
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)
539 func TestFloatSetUint64(t *testing.T) {
540 for _, want := range []uint64{
545 100,
546 1<<32 - 1,
547 1 << 32,
548 1<<64 - 1,
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)
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)
569 func TestFloatSetInt64(t *testing.T) {
570 for _, want := range []int64{
575 100,
576 1<<32 - 1,
577 1 << 32,
578 1<<63 - 1,
580 for i := range [2]int{} {
581 if i&1 != 0 {
582 want = -want
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)
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)
604 func TestFloatSetFloat64(t *testing.T) {
605 for _, want := range []float64{
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),
623 for i := range [2]int{} {
624 if i&1 != 0 {
625 want = -want
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)
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)
646 // test NaN
647 defer func() {
648 if p, ok := recover().(ErrNaN); !ok {
649 t.Errorf("got %v; want ErrNaN panic", p)
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))
658 func TestFloatSetInt(t *testing.T) {
659 for _, want := range []string{
660 "0",
661 "1",
662 "-1",
663 "1234567890",
664 "123456789012345678901234567890",
665 "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
667 var x Int
668 _, ok := x.SetString(want, 0)
669 if !ok {
670 t.Errorf("invalid integer %s", want)
671 continue
673 n := x.BitLen()
675 var f Float
676 f.SetInt(&x)
678 // check precision
679 if n < 64 {
680 n = 64
682 if prec := f.Prec(); prec != uint(n) {
683 t.Errorf("got prec = %d; want %d", prec, n)
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)
693 // TODO(gri) test basic rounding behavior
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
708 var x Rat
709 _, ok := x.SetString(want)
710 if !ok {
711 t.Errorf("invalid fraction %s", want)
712 continue
714 n := max(x.Num().BitLen(), x.Denom().BitLen())
716 var f1, f2 Float
717 f2.SetPrec(1000)
718 f1.SetRat(&x)
719 f2.SetRat(&x)
721 // check precision when set automatically
722 if n < 64 {
723 n = 64
725 if prec := f1.Prec(); prec != uint(n) {
726 t.Errorf("got prec = %d; want %d", prec, n)
729 got := f2.Text('g', 100)
730 if got != want {
731 t.Errorf("got %s (%s); want %s", got, f2.Text('p', 0), want)
736 func TestFloatSetInf(t *testing.T) {
737 var f Float
738 for _, test := range []struct {
739 signbit bool
740 prec uint
741 want string
743 {false, 0, "+Inf"},
744 {true, 0, "-Inf"},
745 {false, 10, "+Inf"},
746 {true, 30, "-Inf"},
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 {
757 x string
758 out uint64
759 acc Accuracy
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},
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 {
787 x string
788 out int64
789 acc Accuracy
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},
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 {
827 x string
828 out float32
829 acc Accuracy
831 {"0", 0, Exact},
833 // underflow to zero
834 {"1e-1000", 0, Below},
835 {"0x0.000002p-127", 0, Below},
836 {"0x.0000010p-126", 0, Below},
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
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},
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},
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
905 // inf
906 {"Inf", float32(math.Inf(+1)), Exact},
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
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)
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)
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)
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
945 {"0", 0, Exact},
947 // underflow to zero
948 {"1e-1000", 0, Below},
949 {"0x0.0000000000001p-1023", 0, Below},
950 {"0x0.00000000000008p-1022", 0, Below},
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
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},
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},
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},
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++ {
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
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)
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)
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)
1045 func TestFloatInt(t *testing.T) {
1046 for _, test := range []struct {
1047 x string
1048 want string
1049 acc Accuracy
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},
1069 x := makeFloat(test.x)
1070 res, acc := x.Int(nil)
1071 got := "nil"
1072 if res != nil {
1073 got = res.String()
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"} {
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)
1090 func TestFloatRat(t *testing.T) {
1091 for _, test := range []struct {
1092 x, want string
1093 acc Accuracy
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)
1112 got := "nil"
1113 if res != nil {
1114 got = res.String()
1116 if got != test.want {
1117 t.Errorf("%s: got %s; want %s", test.x, got, test.want)
1118 continue
1120 if acc != test.acc {
1121 t.Errorf("%s: got %s; want %s", test.x, acc, test.acc)
1122 continue
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)
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)
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",
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)
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)
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",
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))
1185 if !alike(p2, p1) {
1186 t.Errorf("%s: got %s; want %s", test, p2.Text('g', 10), p1.Text('g', 10))
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
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)
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{
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
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()
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)
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)
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} {
1266 x := NewFloat(5.0)
1267 y := new(Float).Neg(x)
1268 want := NewFloat(0.0)
1269 if mode == ToNegativeInf {
1270 want.Neg(want)
1272 got := new(Float).SetMode(mode)
1273 got.Add(x, y)
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)
1278 got.Sub(x, x)
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)
1295 if i&1 != 0 {
1296 x0, y0 = y0, x0
1299 x := NewFloat(x0)
1300 y := NewFloat(y0)
1301 z := new(Float).SetPrec(24)
1303 z.Add(x, y)
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)
1310 z.Sub(z, y)
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)
1328 if i&1 != 0 {
1329 x0, y0 = y0, x0
1332 x := NewFloat(x0)
1333 y := NewFloat(y0)
1334 z := new(Float).SetPrec(53)
1336 z.Add(x, y)
1337 got, acc := z.Float64()
1338 want := x0 + y0
1339 if got != want || acc != Exact {
1340 t.Errorf("d = %d: %g + %g = %g (%s); want %g (Exact)", d, x0, y0, got, acc, want)
1343 z.Sub(z, y)
1344 got, acc = z.Float64()
1345 want -= y0
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 {
1355 a, b float64
1357 {4, 1},
1358 {-4, 1},
1359 {4, -1},
1360 {-4, -1},
1363 for _, test := range tests {
1364 a, b := NewFloat(test.a), NewFloat(test.b)
1365 diff := new(Float).Sub(a, b)
1366 b.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)
1373 b.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 {
1388 // exact values
1389 x := xbits.Float()
1390 y := ybits.Float()
1391 zbits := xbits.mul(ybits)
1392 z := zbits.Float()
1394 for i, mode := range [...]RoundingMode{ToZero, ToNearestEven, AwayFromZero} {
1395 for _, prec := range precList {
1396 got := new(Float).SetPrec(prec).SetMode(mode)
1397 got.Mul(x, y)
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)
1404 if x.Sign() == 0 {
1405 continue // ignore div-0 case (not invertable)
1407 got.Quo(z, x)
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 {
1423 x, y float64
1425 {0, 0},
1426 {0, 1},
1427 {1, 1},
1428 {1, 1.5},
1429 {1.234, 0.5678},
1430 {2.718281828, 3.14159265358979},
1431 {2.718281828e10, 3.14159265358979e-32},
1432 {1.0 / 3, 1e200},
1434 for i := range [8]int{} {
1435 x0, y0 := test.x, test.y
1436 if i&1 != 0 {
1437 x0 = -x0
1439 if i&2 != 0 {
1440 y0 = -y0
1442 if i&4 != 0 {
1443 x0, y0 = y0, x0
1446 x := NewFloat(x0)
1447 y := NewFloat(y0)
1448 z := new(Float).SetPrec(53)
1450 z.Mul(x, y)
1451 got, _ := z.Float64()
1452 want := x0 * y0
1453 if got != want {
1454 t.Errorf("%g * %g = %g; want %g", x0, y0, got, want)
1457 if y0 == 0 {
1458 continue // avoid division-by-zero
1460 z.Quo(z, y)
1461 got, _ = z.Float64()
1462 want /= y0
1463 if got != want {
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
1483 p.Quo(one, three)
1484 p.Mul(p, msix)
1485 z1.Add(two, p)
1487 // z2 = 2 - 1.0/3*+6
1488 p.Quo(one, three)
1489 p.Mul(p, psix)
1490 z2.Sub(two, p)
1492 if z1.Cmp(z2) != 0 {
1493 t.Fatalf("prec %d: got z1 = %v != z2 = %v; want z1 == z2\n", prec, z1, z2)
1495 if z1.Sign() != 0 {
1496 t.Errorf("prec %d: got z1 = %v; want 0", prec, z1)
1498 if z2.Sign() != 0 {
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}
1512 if i&3 != 0 {
1513 bits = append(bits, 0)
1515 if i&2 != 0 {
1516 bits = append(bits, -1)
1518 if i&1 != 0 {
1519 bits = append(bits, -precf)
1521 z := bits.Float()
1523 // compute accurate x as z*y
1524 y := NewFloat(3.14159265358979323e123)
1526 x := new(Float).SetPrec(z.Prec() + y.Prec()).SetMode(ToZero)
1527 x.Mul(z, y)
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) {
1557 n := 10
1558 if *long {
1559 n = 1000
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++ {
1566 if y == 0 {
1567 continue
1570 a := float64(x)
1571 b := float64(y)
1572 c := a / b
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()
1582 if cc != c {
1583 t.Errorf("%g/%g = %s; want %.5g\n", a, b, C.Text('g', 5), c)
1584 continue
1586 if acc != Exact {
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) {
1599 zero := 0.0
1600 args := []float64{math.Inf(-1), -2.71828, -1, -zero, zero, 1, 2.71828, math.Inf(1)}
1601 xx := new(Float)
1602 yy := new(Float)
1603 got := new(Float)
1604 want := new(Float)
1605 for i := 0; i < 4; i++ {
1606 for _, x := range args {
1607 xx.SetFloat64(x)
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 {
1615 yy.SetFloat64(y)
1616 var (
1617 op string
1618 z float64
1619 f func(z, x, y *Float) *Float
1621 switch i {
1622 case 0:
1623 op = "+"
1624 z = x + y
1625 f = (*Float).Add
1626 case 1:
1627 op = "-"
1628 z = x - y
1629 f = (*Float).Sub
1630 case 2:
1631 op = "*"
1632 z = x * y
1633 f = (*Float).Mul
1634 case 3:
1635 op = "/"
1636 z = x / y
1637 f = (*Float).Quo
1638 default:
1639 panic("unreachable")
1641 var errnan bool // set if execution of f panicked with ErrNaN
1642 // protect execution of f
1643 func() {
1644 defer func() {
1645 if p := recover(); p != nil {
1646 _ = p.(ErrNaN) // re-panic if not ErrNaN
1647 errnan = true
1650 f(got, xx, yy)
1652 if math.IsNaN(z) {
1653 if !errnan {
1654 t.Errorf("%5g %s %5g = %5s; want ErrNaN panic", x, op, y, got)
1656 continue
1658 if errnan {
1659 t.Errorf("%5g %s %5g panicked with ErrNan; want %5s", x, op, y, want)
1660 continue
1662 want.SetFloat64(z)
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 {
1673 prec uint
1674 mode RoundingMode
1675 op byte
1676 x, y, want string
1677 acc Accuracy
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)
1712 switch test.op {
1713 case '+':
1714 z.Add(x, y)
1715 case '-':
1716 z.Sub(x, y)
1717 case '*':
1718 z.Mul(x, y)
1719 case '/':
1720 z.Quo(x, y)
1721 default:
1722 panic("unreachable")
1724 if got := z.Text('p', 0); got != test.want || z.Acc() != test.acc {
1725 t.Errorf(
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 {
1742 mode RoundingMode
1743 prec uint
1744 x, y, want int64
1745 op byte
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, '/'},
1763 var x, y, z Float
1764 x.SetInt64(test.x)
1765 y.SetInt64(test.y)
1766 z.SetPrec(test.prec).SetMode(test.mode)
1767 switch test.op {
1768 case '+':
1769 z.Add(&x, &y)
1770 case '-':
1771 z.Sub(&x, &y)
1772 case '*':
1773 z.Mul(&x, &y)
1774 case '/':
1775 z.Quo(&x, &y)
1776 default:
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)
1789 // operands.
1790 func TestFloatCmpSpecialValues(t *testing.T) {
1791 zero := 0.0
1792 args := []float64{math.Inf(-1), -2.71828, -1, -zero, zero, 1, 2.71828, math.Inf(1)}
1793 xx := new(Float)
1794 yy := new(Float)
1795 for i := 0; i < 4; i++ {
1796 for _, x := range args {
1797 xx.SetFloat64(x)
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 {
1805 yy.SetFloat64(y)
1806 got := xx.Cmp(yy)
1807 want := 0
1808 switch {
1809 case x < y:
1810 want = -1
1811 case x > y:
1812 want = +1
1814 if got != want {
1815 t.Errorf("(%g).Cmp(%g) = %v; want %v", x, y, got, want)
1822 func BenchmarkFloatAdd(b *testing.B) {
1823 x := new(Float)
1824 y := new(Float)
1825 z := new(Float)
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))
1830 z.SetPrec(prec)
1832 b.Run(fmt.Sprintf("%v", prec), func(b *testing.B) {
1833 b.ReportAllocs()
1834 for i := 0; i < b.N; i++ {
1835 z.Add(x, y)
1841 func BenchmarkFloatSub(b *testing.B) {
1842 x := new(Float)
1843 y := new(Float)
1844 z := new(Float)
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))
1849 z.SetPrec(prec)
1851 b.Run(fmt.Sprintf("%v", prec), func(b *testing.B) {
1852 b.ReportAllocs()
1853 for i := 0; i < b.N; i++ {
1854 z.Sub(x, y)