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