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