github.com/slayercat/go@v0.0.0-20170428012452-c51559813f61/src/math/big/float_test.go (about)

     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  }