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