Black Lives Matter. Support the Equal Justice Initiative.

# Source file src/math/big/float_test.go

## Documentation: math/big

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

View as plain text