1// Copyright 2014 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package big
6
7import (
8	"flag"
9	"fmt"
10	"math"
11	"strconv"
12	"strings"
13	"testing"
14)
15
16// Verify that ErrNaN implements the error interface.
17var _ error = ErrNaN{}
18
19func (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
27func (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
35func 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
95func 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
103func 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
144func 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
169func 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).
190func alike(x, y *Float) bool {
191	return x.Cmp(y) == 0 && x.Signbit() == y.Signbit()
192}
193
194func 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
200func alike64(x, y float64) bool {
201	// we can ignore NaNs
202	return x == y && math.Signbit(x) == math.Signbit(y)
203
204}
205
206func 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
232func 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
242func 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
280func 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
306func 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
331func 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
339func toBinary(x int64) string {
340	return strconv.FormatInt(x, 2)
341}
342
343func 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.
426func 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).
526func 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
539func 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
569func 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
604func 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
658func 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
696func 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
736func 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
755func 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
785func 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
825func 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
938func TestFloatFloat64(t *testing.T) {
939	const smallestNormalFloat64 = 2.2250738585072014e-308 // 1p-1022
940	for _, test := range []struct {
941		x   string
942		out float64
943		acc Accuracy
944	}{
945		{"0", 0, Exact},
946
947		// underflow to zero
948		{"1e-1000", 0, Below},
949		{"0x0.0000000000001p-1023", 0, Below},
950		{"0x0.00000000000008p-1022", 0, Below},
951
952		// denormals
953		{"0x0.0000000000000cp-1022", math.SmallestNonzeroFloat64, Above}, // rounded up to smallest denormal
954		{"0x0.00000000000010p-1022", math.SmallestNonzeroFloat64, Exact}, // smallest denormal
955		{"0x.8p-1073", math.SmallestNonzeroFloat64, Exact},
956		{"1p-1074", math.SmallestNonzeroFloat64, Exact},
957		{"0x.fffffffffffffp-1022", math.Float64frombits(0x000fffffffffffff), Exact}, // largest denormal
958
959		// special denormal cases (see issues 14553, 14651)
960		{"0x0.00000000000001p-1022", math.Float64frombits(0x00000000000000000), Below}, // underflow to zero
961		{"0x0.00000000000004p-1022", math.Float64frombits(0x00000000000000000), Below}, // underflow to zero
962		{"0x0.00000000000008p-1022", math.Float64frombits(0x00000000000000000), Below}, // rounded down to even
963		{"0x0.00000000000009p-1022", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal
964		{"0x0.0000000000000ap-1022", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal
965
966		{"0x0.8p-1074", math.Float64frombits(0x00000000000000000), Below}, // rounded down to even
967		{"0x0.9p-1074", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal
968		{"0x0.ap-1074", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal
969		{"0x0.bp-1074", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal
970		{"0x0.cp-1074", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal
971
972		{"0x1.0p-1074", math.Float64frombits(0x00000000000000001), Exact},
973		{"0x1.7p-1074", math.Float64frombits(0x00000000000000001), Below},
974		{"0x1.8p-1074", math.Float64frombits(0x00000000000000002), Above},
975		{"0x1.9p-1074", math.Float64frombits(0x00000000000000002), Above},
976
977		{"0x2.0p-1074", math.Float64frombits(0x00000000000000002), Exact},
978		{"0x2.8p-1074", math.Float64frombits(0x00000000000000002), Below}, // rounded down to even
979		{"0x2.9p-1074", math.Float64frombits(0x00000000000000003), Above},
980
981		{"0x3.0p-1074", math.Float64frombits(0x00000000000000003), Exact},
982		{"0x3.7p-1074", math.Float64frombits(0x00000000000000003), Below},
983		{"0x3.8p-1074", math.Float64frombits(0x00000000000000004), Above}, // rounded up to even
984
985		{"0x4.0p-1074", math.Float64frombits(0x00000000000000004), Exact},
986		{"0x4.8p-1074", math.Float64frombits(0x00000000000000004), Below}, // rounded down to even
987		{"0x4.9p-1074", math.Float64frombits(0x00000000000000005), Above},
988
989		// normals
990		{"0x.fffffffffffff8p-1022", math.Float64frombits(0x0010000000000000), Above}, // rounded up to smallest normal
991		{"1p-1022", math.Float64frombits(0x0010000000000000), Exact},                 // smallest normal
992		{"1", 1, Exact},
993		{"1.000000000000000000001", 1, Below},
994		{"12345.0", 12345, Exact},
995		{"12345.000000000000000000001", 12345, Below},
996		{"0x1.fffffffffffff0p1023", math.MaxFloat64, Exact},
997		{"0x1.fffffffffffff4p1023", math.MaxFloat64, Below},
998
999		// overflow
1000		{"0x1.fffffffffffff8p1023", math.Inf(+1), Above},
1001		{"0x1p1024", math.Inf(+1), Above},
1002		{"1e10000", math.Inf(+1), Above},
1003		{"0x1.fffffffffffff8p2147483646", math.Inf(+1), Above}, // overflow in rounding
1004		{"Inf", math.Inf(+1), Exact},
1005
1006		// selected denormalized values that were handled incorrectly in the past
1007		{"0x.fffffffffffffp-1022", smallestNormalFloat64 - math.SmallestNonzeroFloat64, Exact},
1008		{"4503599627370495p-1074", smallestNormalFloat64 - math.SmallestNonzeroFloat64, Exact},
1009
1010		// http://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
1011		{"2.2250738585072011e-308", 2.225073858507201e-308, Below},
1012		// http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
1013		{"2.2250738585072012e-308", 2.2250738585072014e-308, Above},
1014	} {
1015		for i := 0; i < 2; i++ {
1016			// test both signs
1017			tx, tout, tacc := test.x, test.out, test.acc
1018			if i != 0 {
1019				tx = "-" + tx
1020				tout = -tout
1021				tacc = -tacc
1022			}
1023
1024			// conversion should match strconv where syntax is agreeable
1025			if f, err := strconv.ParseFloat(tx, 64); err == nil && !alike64(f, tout) {
1026				t.Errorf("%s: got %g; want %g (incorrect test data)", tx, f, tout)
1027			}
1028
1029			x := makeFloat(tx)
1030			out, acc := x.Float64()
1031			if !alike64(out, tout) || acc != tacc {
1032				t.Errorf("%s: got %g (%#016x, %s); want %g (%#016x, %s)", tx, out, math.Float64bits(out), acc, test.out, math.Float64bits(test.out), tacc)
1033			}
1034
1035			// test that x.SetFloat64(f).Float64() == f
1036			var x2 Float
1037			out2, acc2 := x2.SetFloat64(out).Float64()
1038			if !alike64(out2, out) || acc2 != Exact {
1039				t.Errorf("idempotency test: got %g (%s); want %g (Exact)", out2, acc2, out)
1040			}
1041		}
1042	}
1043}
1044
1045func 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
1090func 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
1144func 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
1168func 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
1191func TestFloatInc(t *testing.T) {
1192	const n = 10
1193	for _, prec := range precList {
1194		if 1<<prec < n {
1195			continue // prec must be large enough to hold all numbers from 0 to n
1196		}
1197		var x, one Float
1198		x.SetPrec(prec)
1199		one.SetInt64(1)
1200		for i := 0; i < n; i++ {
1201			x.Add(&x, &one)
1202		}
1203		if x.Cmp(new(Float).SetInt64(n)) != 0 {
1204			t.Errorf("prec = %d: got %s; want %d", prec, &x, n)
1205		}
1206	}
1207}
1208
1209// Selected precisions with which to run various tests.
1210var 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).
1214var 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.
1230func TestFloatAdd(t *testing.T) {
1231	for _, xbits := range bitsList {
1232		for _, ybits := range bitsList {
1233			// exact values
1234			x := xbits.Float()
1235			y := ybits.Float()
1236			zbits := xbits.add(ybits)
1237			z := zbits.Float()
1238
1239			for i, mode := range [...]RoundingMode{ToZero, ToNearestEven, AwayFromZero} {
1240				for _, prec := range precList {
1241					got := new(Float).SetPrec(prec).SetMode(mode)
1242					got.Add(x, y)
1243					want := zbits.round(prec, mode)
1244					if got.Cmp(want) != 0 {
1245						t.Errorf("i = %d, prec = %d, %s:\n\t     %s %v\n\t+    %s %v\n\t=    %s\n\twant %s",
1246							i, prec, mode, x, xbits, y, ybits, got, want)
1247					}
1248
1249					got.Sub(z, x)
1250					want = ybits.round(prec, mode)
1251					if got.Cmp(want) != 0 {
1252						t.Errorf("i = %d, prec = %d, %s:\n\t     %s %v\n\t-    %s %v\n\t=    %s\n\twant %s",
1253							i, prec, mode, z, zbits, x, xbits, got, want)
1254					}
1255				}
1256			}
1257		}
1258	}
1259}
1260
1261// TestFloatAdd32 tests that Float.Add/Sub of numbers with
1262// 24bit mantissa behaves like float32 addition/subtraction
1263// (excluding denormal numbers).
1264func TestFloatAdd32(t *testing.T) {
1265	// chose base such that we cross the mantissa precision limit
1266	const base = 1<<26 - 0x10 // 11...110000 (26 bits)
1267	for d := 0; d <= 0x10; d++ {
1268		for i := range [2]int{} {
1269			x0, y0 := float64(base), float64(d)
1270			if i&1 != 0 {
1271				x0, y0 = y0, x0
1272			}
1273
1274			x := NewFloat(x0)
1275			y := NewFloat(y0)
1276			z := new(Float).SetPrec(24)
1277
1278			z.Add(x, y)
1279			got, acc := z.Float32()
1280			want := float32(y0) + float32(x0)
1281			if got != want || acc != Exact {
1282				t.Errorf("d = %d: %g + %g = %g (%s); want %g (Exact)", d, x0, y0, got, acc, want)
1283			}
1284
1285			z.Sub(z, y)
1286			got, acc = z.Float32()
1287			want = float32(want) - float32(y0)
1288			if got != want || acc != Exact {
1289				t.Errorf("d = %d: %g - %g = %g (%s); want %g (Exact)", d, x0+y0, y0, got, acc, want)
1290			}
1291		}
1292	}
1293}
1294
1295// TestFloatAdd64 tests that Float.Add/Sub of numbers with
1296// 53bit mantissa behaves like float64 addition/subtraction.
1297func TestFloatAdd64(t *testing.T) {
1298	// chose base such that we cross the mantissa precision limit
1299	const base = 1<<55 - 0x10 // 11...110000 (55 bits)
1300	for d := 0; d <= 0x10; d++ {
1301		for i := range [2]int{} {
1302			x0, y0 := float64(base), float64(d)
1303			if i&1 != 0 {
1304				x0, y0 = y0, x0
1305			}
1306
1307			x := NewFloat(x0)
1308			y := NewFloat(y0)
1309			z := new(Float).SetPrec(53)
1310
1311			z.Add(x, y)
1312			got, acc := z.Float64()
1313			want := x0 + y0
1314			if got != want || acc != Exact {
1315				t.Errorf("d = %d: %g + %g = %g (%s); want %g (Exact)", d, x0, y0, got, acc, want)
1316			}
1317
1318			z.Sub(z, y)
1319			got, acc = z.Float64()
1320			want -= y0
1321			if got != want || acc != Exact {
1322				t.Errorf("d = %d: %g - %g = %g (%s); want %g (Exact)", d, x0+y0, y0, got, acc, want)
1323			}
1324		}
1325	}
1326}
1327
1328func TestIssue20490(t *testing.T) {
1329	var tests = []struct {
1330		a, b float64
1331	}{
1332		{4, 1},
1333		{-4, 1},
1334		{4, -1},
1335		{-4, -1},
1336	}
1337
1338	for _, test := range tests {
1339		a, b := NewFloat(test.a), NewFloat(test.b)
1340		diff := new(Float).Sub(a, b)
1341		b.Sub(a, b)
1342		if b.Cmp(diff) != 0 {
1343			t.Errorf("got %g - %g = %g; want %g\n", a, NewFloat(test.b), b, diff)
1344		}
1345
1346		b = NewFloat(test.b)
1347		sum := new(Float).Add(a, b)
1348		b.Add(a, b)
1349		if b.Cmp(sum) != 0 {
1350			t.Errorf("got %g + %g = %g; want %g\n", a, NewFloat(test.b), b, sum)
1351		}
1352
1353	}
1354}
1355
1356// TestFloatMul tests Float.Mul/Quo by comparing the result of a "manual"
1357// multiplication/division of arguments represented by Bits values with the
1358// respective Float multiplication/division for a variety of precisions
1359// and rounding modes.
1360func TestFloatMul(t *testing.T) {
1361	for _, xbits := range bitsList {
1362		for _, ybits := range bitsList {
1363			// exact values
1364			x := xbits.Float()
1365			y := ybits.Float()
1366			zbits := xbits.mul(ybits)
1367			z := zbits.Float()
1368
1369			for i, mode := range [...]RoundingMode{ToZero, ToNearestEven, AwayFromZero} {
1370				for _, prec := range precList {
1371					got := new(Float).SetPrec(prec).SetMode(mode)
1372					got.Mul(x, y)
1373					want := zbits.round(prec, mode)
1374					if got.Cmp(want) != 0 {
1375						t.Errorf("i = %d, prec = %d, %s:\n\t     %s %v\n\t*    %s %v\n\t=    %s\n\twant %s",
1376							i, prec, mode, x, xbits, y, ybits, got, want)
1377					}
1378
1379					if x.Sign() == 0 {
1380						continue // ignore div-0 case (not invertable)
1381					}
1382					got.Quo(z, x)
1383					want = ybits.round(prec, mode)
1384					if got.Cmp(want) != 0 {
1385						t.Errorf("i = %d, prec = %d, %s:\n\t     %s %v\n\t/    %s %v\n\t=    %s\n\twant %s",
1386							i, prec, mode, z, zbits, x, xbits, got, want)
1387					}
1388				}
1389			}
1390		}
1391	}
1392}
1393
1394// TestFloatMul64 tests that Float.Mul/Quo of numbers with
1395// 53bit mantissa behaves like float64 multiplication/division.
1396func TestFloatMul64(t *testing.T) {
1397	for _, test := range []struct {
1398		x, y float64
1399	}{
1400		{0, 0},
1401		{0, 1},
1402		{1, 1},
1403		{1, 1.5},
1404		{1.234, 0.5678},
1405		{2.718281828, 3.14159265358979},
1406		{2.718281828e10, 3.14159265358979e-32},
1407		{1.0 / 3, 1e200},
1408	} {
1409		for i := range [8]int{} {
1410			x0, y0 := test.x, test.y
1411			if i&1 != 0 {
1412				x0 = -x0
1413			}
1414			if i&2 != 0 {
1415				y0 = -y0
1416			}
1417			if i&4 != 0 {
1418				x0, y0 = y0, x0
1419			}
1420
1421			x := NewFloat(x0)
1422			y := NewFloat(y0)
1423			z := new(Float).SetPrec(53)
1424
1425			z.Mul(x, y)
1426			got, _ := z.Float64()
1427			want := x0 * y0
1428			if got != want {
1429				t.Errorf("%g * %g = %g; want %g", x0, y0, got, want)
1430			}
1431
1432			if y0 == 0 {
1433				continue // avoid division-by-zero
1434			}
1435			z.Quo(z, y)
1436			got, _ = z.Float64()
1437			want /= y0
1438			if got != want {
1439				t.Errorf("%g / %g = %g; want %g", x0*y0, y0, got, want)
1440			}
1441		}
1442	}
1443}
1444
1445func TestIssue6866(t *testing.T) {
1446	for _, prec := range precList {
1447		two := new(Float).SetPrec(prec).SetInt64(2)
1448		one := new(Float).SetPrec(prec).SetInt64(1)
1449		three := new(Float).SetPrec(prec).SetInt64(3)
1450		msix := new(Float).SetPrec(prec).SetInt64(-6)
1451		psix := new(Float).SetPrec(prec).SetInt64(+6)
1452
1453		p := new(Float).SetPrec(prec)
1454		z1 := new(Float).SetPrec(prec)
1455		z2 := new(Float).SetPrec(prec)
1456
1457		// z1 = 2 + 1.0/3*-6
1458		p.Quo(one, three)
1459		p.Mul(p, msix)
1460		z1.Add(two, p)
1461
1462		// z2 = 2 - 1.0/3*+6
1463		p.Quo(one, three)
1464		p.Mul(p, psix)
1465		z2.Sub(two, p)
1466
1467		if z1.Cmp(z2) != 0 {
1468			t.Fatalf("prec %d: got z1 = %s != z2 = %s; want z1 == z2\n", prec, z1, z2)
1469		}
1470		if z1.Sign() != 0 {
1471			t.Errorf("prec %d: got z1 = %s; want 0", prec, z1)
1472		}
1473		if z2.Sign() != 0 {
1474			t.Errorf("prec %d: got z2 = %s; want 0", prec, z2)
1475		}
1476	}
1477}
1478
1479func TestFloatQuo(t *testing.T) {
1480	// TODO(gri) make the test vary these precisions
1481	preci := 200 // precision of integer part
1482	precf := 20  // precision of fractional part
1483
1484	for i := 0; i < 8; i++ {
1485		// compute accurate (not rounded) result z
1486		bits := Bits{preci - 1}
1487		if i&3 != 0 {
1488			bits = append(bits, 0)
1489		}
1490		if i&2 != 0 {
1491			bits = append(bits, -1)
1492		}
1493		if i&1 != 0 {
1494			bits = append(bits, -precf)
1495		}
1496		z := bits.Float()
1497
1498		// compute accurate x as z*y
1499		y := NewFloat(3.14159265358979323e123)
1500
1501		x := new(Float).SetPrec(z.Prec() + y.Prec()).SetMode(ToZero)
1502		x.Mul(z, y)
1503
1504		// leave for debugging
1505		// fmt.Printf("x = %s\ny = %s\nz = %s\n", x, y, z)
1506
1507		if got := x.Acc(); got != Exact {
1508			t.Errorf("got acc = %s; want exact", got)
1509		}
1510
1511		// round accurate z for a variety of precisions and
1512		// modes and compare against result of x / y.
1513		for _, mode := range [...]RoundingMode{ToZero, ToNearestEven, AwayFromZero} {
1514			for d := -5; d < 5; d++ {
1515				prec := uint(preci + d)
1516				got := new(Float).SetPrec(prec).SetMode(mode).Quo(x, y)
1517				want := bits.round(prec, mode)
1518				if got.Cmp(want) != 0 {
1519					t.Errorf("i = %d, prec = %d, %s:\n\t     %s\n\t/    %s\n\t=    %s\n\twant %s",
1520						i, prec, mode, x, y, got, want)
1521				}
1522			}
1523		}
1524	}
1525}
1526
1527var long = flag.Bool("long", false, "run very long tests")
1528
1529// TestFloatQuoSmoke tests all divisions x/y for values x, y in the range [-n, +n];
1530// it serves as a smoke test for basic correctness of division.
1531func TestFloatQuoSmoke(t *testing.T) {
1532	n := 10
1533	if *long {
1534		n = 1000
1535	}
1536
1537	const dprec = 3         // max. precision variation
1538	const prec = 10 + dprec // enough bits to hold n precisely
1539	for x := -n; x <= n; x++ {
1540		for y := -n; y < n; y++ {
1541			if y == 0 {
1542				continue
1543			}
1544
1545			a := float64(x)
1546			b := float64(y)
1547			c := a / b
1548
1549			// vary operand precision (only ok as long as a, b can be represented correctly)
1550			for ad := -dprec; ad <= dprec; ad++ {
1551				for bd := -dprec; bd <= dprec; bd++ {
1552					A := new(Float).SetPrec(uint(prec + ad)).SetFloat64(a)
1553					B := new(Float).SetPrec(uint(prec + bd)).SetFloat64(b)
1554					C := new(Float).SetPrec(53).Quo(A, B) // C has float64 mantissa width
1555
1556					cc, acc := C.Float64()
1557					if cc != c {
1558						t.Errorf("%g/%g = %s; want %.5g\n", a, b, C.Text('g', 5), c)
1559						continue
1560					}
1561					if acc != Exact {
1562						t.Errorf("%g/%g got %s result; want exact result", a, b, acc)
1563					}
1564				}
1565			}
1566		}
1567	}
1568}
1569
1570// TestFloatArithmeticSpecialValues tests that Float operations produce the
1571// correct results for combinations of zero (±0), finite (±1 and ±2.71828),
1572// and infinite (±Inf) operands.
1573func TestFloatArithmeticSpecialValues(t *testing.T) {
1574	zero := 0.0
1575	args := []float64{math.Inf(-1), -2.71828, -1, -zero, zero, 1, 2.71828, math.Inf(1)}
1576	xx := new(Float)
1577	yy := new(Float)
1578	got := new(Float)
1579	want := new(Float)
1580	for i := 0; i < 4; i++ {
1581		for _, x := range args {
1582			xx.SetFloat64(x)
1583			// check conversion is correct
1584			// (no need to do this for y, since we see exactly the
1585			// same values there)
1586			if got, acc := xx.Float64(); got != x || acc != Exact {
1587				t.Errorf("Float(%g) == %g (%s)", x, got, acc)
1588			}
1589			for _, y := range args {
1590				yy.SetFloat64(y)
1591				var (
1592					op string
1593					z  float64
1594					f  func(z, x, y *Float) *Float
1595				)
1596				switch i {
1597				case 0:
1598					op = "+"
1599					z = x + y
1600					f = (*Float).Add
1601				case 1:
1602					op = "-"
1603					z = x - y
1604					f = (*Float).Sub
1605				case 2:
1606					op = "*"
1607					z = x * y
1608					f = (*Float).Mul
1609				case 3:
1610					op = "/"
1611					z = x / y
1612					f = (*Float).Quo
1613				default:
1614					panic("unreachable")
1615				}
1616				var errnan bool // set if execution of f panicked with ErrNaN
1617				// protect execution of f
1618				func() {
1619					defer func() {
1620						if p := recover(); p != nil {
1621							_ = p.(ErrNaN) // re-panic if not ErrNaN
1622							errnan = true
1623						}
1624					}()
1625					f(got, xx, yy)
1626				}()
1627				if math.IsNaN(z) {
1628					if !errnan {
1629						t.Errorf("%5g %s %5g = %5s; want ErrNaN panic", x, op, y, got)
1630					}
1631					continue
1632				}
1633				if errnan {
1634					t.Errorf("%5g %s %5g panicked with ErrNan; want %5s", x, op, y, want)
1635					continue
1636				}
1637				want.SetFloat64(z)
1638				if !alike(got, want) {
1639					t.Errorf("%5g %s %5g = %5s; want %5s", x, op, y, got, want)
1640				}
1641			}
1642		}
1643	}
1644}
1645
1646func TestFloatArithmeticOverflow(t *testing.T) {
1647	for _, test := range []struct {
1648		prec       uint
1649		mode       RoundingMode
1650		op         byte
1651		x, y, want string
1652		acc        Accuracy
1653	}{
1654		{4, ToNearestEven, '+', "0", "0", "0", Exact},                   // smoke test
1655		{4, ToNearestEven, '+', "0x.8p+0", "0x.8p+0", "0x.8p+1", Exact}, // smoke test
1656
1657		{4, ToNearestEven, '+', "0", "0x.8p2147483647", "0x.8p+2147483647", Exact},
1658		{4, ToNearestEven, '+', "0x.8p2147483500", "0x.8p2147483647", "0x.8p+2147483647", Below}, // rounded to zero
1659		{4, ToNearestEven, '+', "0x.8p2147483647", "0x.8p2147483647", "+Inf", Above},             // exponent overflow in +
1660		{4, ToNearestEven, '+', "-0x.8p2147483647", "-0x.8p2147483647", "-Inf", Below},           // exponent overflow in +
1661		{4, ToNearestEven, '-', "-0x.8p2147483647", "0x.8p2147483647", "-Inf", Below},            // exponent overflow in -
1662
1663		{4, ToZero, '+', "0x.fp2147483647", "0x.8p2147483643", "0x.fp+2147483647", Below}, // rounded to zero
1664		{4, ToNearestEven, '+', "0x.fp2147483647", "0x.8p2147483643", "+Inf", Above},      // exponent overflow in rounding
1665		{4, AwayFromZero, '+', "0x.fp2147483647", "0x.8p2147483643", "+Inf", Above},       // exponent overflow in rounding
1666
1667		{4, AwayFromZero, '-', "-0x.fp2147483647", "0x.8p2147483644", "-Inf", Below},        // exponent overflow in rounding
1668		{4, ToNearestEven, '-', "-0x.fp2147483647", "0x.8p2147483643", "-Inf", Below},       // exponent overflow in rounding
1669		{4, ToZero, '-', "-0x.fp2147483647", "0x.8p2147483643", "-0x.fp+2147483647", Above}, // rounded to zero
1670
1671		{4, ToNearestEven, '+', "0", "0x.8p-2147483648", "0x.8p-2147483648", Exact},
1672		{4, ToNearestEven, '+', "0x.8p-2147483648", "0x.8p-2147483648", "0x.8p-2147483647", Exact},
1673
1674		{4, ToNearestEven, '*', "1", "0x.8p2147483647", "0x.8p+2147483647", Exact},
1675		{4, ToNearestEven, '*', "2", "0x.8p2147483647", "+Inf", Above},  // exponent overflow in *
1676		{4, ToNearestEven, '*', "-2", "0x.8p2147483647", "-Inf", Below}, // exponent overflow in *
1677
1678		{4, ToNearestEven, '/', "0.5", "0x.8p2147483647", "0x.8p-2147483646", Exact},
1679		{4, ToNearestEven, '/', "0x.8p+0", "0x.8p2147483647", "0x.8p-2147483646", Exact},
1680		{4, ToNearestEven, '/', "0x.8p-1", "0x.8p2147483647", "0x.8p-2147483647", Exact},
1681		{4, ToNearestEven, '/', "0x.8p-2", "0x.8p2147483647", "0x.8p-2147483648", Exact},
1682		{4, ToNearestEven, '/', "0x.8p-3", "0x.8p2147483647", "0", Below}, // exponent underflow in /
1683	} {
1684		x := makeFloat(test.x)
1685		y := makeFloat(test.y)
1686		z := new(Float).SetPrec(test.prec).SetMode(test.mode)
1687		switch test.op {
1688		case '+':
1689			z.Add(x, y)
1690		case '-':
1691			z.Sub(x, y)
1692		case '*':
1693			z.Mul(x, y)
1694		case '/':
1695			z.Quo(x, y)
1696		default:
1697			panic("unreachable")
1698		}
1699		if got := z.Text('p', 0); got != test.want || z.Acc() != test.acc {
1700			t.Errorf(
1701				"prec = %d (%s): %s %c %s = %s (%s); want %s (%s)",
1702				test.prec, test.mode, x.Text('p', 0), test.op, y.Text('p', 0), got, z.Acc(), test.want, test.acc,
1703			)
1704		}
1705	}
1706}
1707
1708// TODO(gri) Add tests that check correctness in the presence of aliasing.
1709
1710// For rounding modes ToNegativeInf and ToPositiveInf, rounding is affected
1711// by the sign of the value to be rounded. Test that rounding happens after
1712// the sign of a result has been set.
1713// This test uses specific values that are known to fail if rounding is
1714// "factored" out before setting the result sign.
1715func TestFloatArithmeticRounding(t *testing.T) {
1716	for _, test := range []struct {
1717		mode       RoundingMode
1718		prec       uint
1719		x, y, want int64
1720		op         byte
1721	}{
1722		{ToZero, 3, -0x8, -0x1, -0x8, '+'},
1723		{AwayFromZero, 3, -0x8, -0x1, -0xa, '+'},
1724		{ToNegativeInf, 3, -0x8, -0x1, -0xa, '+'},
1725
1726		{ToZero, 3, -0x8, 0x1, -0x8, '-'},
1727		{AwayFromZero, 3, -0x8, 0x1, -0xa, '-'},
1728		{ToNegativeInf, 3, -0x8, 0x1, -0xa, '-'},
1729
1730		{ToZero, 3, -0x9, 0x1, -0x8, '*'},
1731		{AwayFromZero, 3, -0x9, 0x1, -0xa, '*'},
1732		{ToNegativeInf, 3, -0x9, 0x1, -0xa, '*'},
1733
1734		{ToZero, 3, -0x9, 0x1, -0x8, '/'},
1735		{AwayFromZero, 3, -0x9, 0x1, -0xa, '/'},
1736		{ToNegativeInf, 3, -0x9, 0x1, -0xa, '/'},
1737	} {
1738		var x, y, z Float
1739		x.SetInt64(test.x)
1740		y.SetInt64(test.y)
1741		z.SetPrec(test.prec).SetMode(test.mode)
1742		switch test.op {
1743		case '+':
1744			z.Add(&x, &y)
1745		case '-':
1746			z.Sub(&x, &y)
1747		case '*':
1748			z.Mul(&x, &y)
1749		case '/':
1750			z.Quo(&x, &y)
1751		default:
1752			panic("unreachable")
1753		}
1754		if got, acc := z.Int64(); got != test.want || acc != Exact {
1755			t.Errorf("%s, %d bits: %d %c %d = %d (%s); want %d (Exact)",
1756				test.mode, test.prec, test.x, test.op, test.y, got, acc, test.want,
1757			)
1758		}
1759	}
1760}
1761
1762// TestFloatCmpSpecialValues tests that Cmp produces the correct results for
1763// combinations of zero (±0), finite (±1 and ±2.71828), and infinite (±Inf)
1764// operands.
1765func TestFloatCmpSpecialValues(t *testing.T) {
1766	zero := 0.0
1767	args := []float64{math.Inf(-1), -2.71828, -1, -zero, zero, 1, 2.71828, math.Inf(1)}
1768	xx := new(Float)
1769	yy := new(Float)
1770	for i := 0; i < 4; i++ {
1771		for _, x := range args {
1772			xx.SetFloat64(x)
1773			// check conversion is correct
1774			// (no need to do this for y, since we see exactly the
1775			// same values there)
1776			if got, acc := xx.Float64(); got != x || acc != Exact {
1777				t.Errorf("Float(%g) == %g (%s)", x, got, acc)
1778			}
1779			for _, y := range args {
1780				yy.SetFloat64(y)
1781				got := xx.Cmp(yy)
1782				want := 0
1783				switch {
1784				case x < y:
1785					want = -1
1786				case x > y:
1787					want = +1
1788				}
1789				if got != want {
1790					t.Errorf("(%g).Cmp(%g) = %v; want %v", x, y, got, want)
1791				}
1792			}
1793		}
1794	}
1795}
1796
1797func BenchmarkFloatAdd(b *testing.B) {
1798	x := new(Float)
1799	y := new(Float)
1800	z := new(Float)
1801
1802	for _, prec := range []uint{10, 1e2, 1e3, 1e4, 1e5} {
1803		x.SetPrec(prec).SetRat(NewRat(1, 3))
1804		y.SetPrec(prec).SetRat(NewRat(1, 6))
1805		z.SetPrec(prec)
1806
1807		b.Run(fmt.Sprintf("%v", prec), func(b *testing.B) {
1808			b.ReportAllocs()
1809			for i := 0; i < b.N; i++ {
1810				z.Add(x, y)
1811			}
1812		})
1813	}
1814}
1815
1816func BenchmarkFloatSub(b *testing.B) {
1817	x := new(Float)
1818	y := new(Float)
1819	z := new(Float)
1820
1821	for _, prec := range []uint{10, 1e2, 1e3, 1e4, 1e5} {
1822		x.SetPrec(prec).SetRat(NewRat(1, 3))
1823		y.SetPrec(prec).SetRat(NewRat(1, 6))
1824		z.SetPrec(prec)
1825
1826		b.Run(fmt.Sprintf("%v", prec), func(b *testing.B) {
1827			b.ReportAllocs()
1828			for i := 0; i < b.N; i++ {
1829				z.Sub(x, y)
1830			}
1831		})
1832	}
1833}
1834