github.com/flyinox/gosm@v0.0.0-20171117061539-16768cb62077/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  func TestIssue20490(t *testing.T) {
  1329  	var tests = []struct {
  1330  		a, b float64
  1331  	}{
  1332  		{4, 1},
  1333  		{-4, 1},
  1334  		{4, -1},
  1335  		{-4, -1},
  1336  	}
  1337  
  1338  	for _, test := range tests {
  1339  		a, b := NewFloat(test.a), NewFloat(test.b)
  1340  		diff := new(Float).Sub(a, b)
  1341  		b.Sub(a, b)
  1342  		if b.Cmp(diff) != 0 {
  1343  			t.Errorf("got %g - %g = %g; want %g\n", a, NewFloat(test.b), b, diff)
  1344  		}
  1345  
  1346  		b = NewFloat(test.b)
  1347  		sum := new(Float).Add(a, b)
  1348  		b.Add(a, b)
  1349  		if b.Cmp(sum) != 0 {
  1350  			t.Errorf("got %g + %g = %g; want %g\n", a, NewFloat(test.b), b, sum)
  1351  		}
  1352  
  1353  	}
  1354  }
  1355  
  1356  // TestFloatMul tests Float.Mul/Quo by comparing the result of a "manual"
  1357  // multiplication/division of arguments represented by Bits values with the
  1358  // respective Float multiplication/division for a variety of precisions
  1359  // and rounding modes.
  1360  func TestFloatMul(t *testing.T) {
  1361  	for _, xbits := range bitsList {
  1362  		for _, ybits := range bitsList {
  1363  			// exact values
  1364  			x := xbits.Float()
  1365  			y := ybits.Float()
  1366  			zbits := xbits.mul(ybits)
  1367  			z := zbits.Float()
  1368  
  1369  			for i, mode := range [...]RoundingMode{ToZero, ToNearestEven, AwayFromZero} {
  1370  				for _, prec := range precList {
  1371  					got := new(Float).SetPrec(prec).SetMode(mode)
  1372  					got.Mul(x, y)
  1373  					want := zbits.round(prec, mode)
  1374  					if got.Cmp(want) != 0 {
  1375  						t.Errorf("i = %d, prec = %d, %s:\n\t     %s %v\n\t*    %s %v\n\t=    %s\n\twant %s",
  1376  							i, prec, mode, x, xbits, y, ybits, got, want)
  1377  					}
  1378  
  1379  					if x.Sign() == 0 {
  1380  						continue // ignore div-0 case (not invertable)
  1381  					}
  1382  					got.Quo(z, x)
  1383  					want = ybits.round(prec, mode)
  1384  					if got.Cmp(want) != 0 {
  1385  						t.Errorf("i = %d, prec = %d, %s:\n\t     %s %v\n\t/    %s %v\n\t=    %s\n\twant %s",
  1386  							i, prec, mode, z, zbits, x, xbits, got, want)
  1387  					}
  1388  				}
  1389  			}
  1390  		}
  1391  	}
  1392  }
  1393  
  1394  // TestFloatMul64 tests that Float.Mul/Quo of numbers with
  1395  // 53bit mantissa behaves like float64 multiplication/division.
  1396  func TestFloatMul64(t *testing.T) {
  1397  	for _, test := range []struct {
  1398  		x, y float64
  1399  	}{
  1400  		{0, 0},
  1401  		{0, 1},
  1402  		{1, 1},
  1403  		{1, 1.5},
  1404  		{1.234, 0.5678},
  1405  		{2.718281828, 3.14159265358979},
  1406  		{2.718281828e10, 3.14159265358979e-32},
  1407  		{1.0 / 3, 1e200},
  1408  	} {
  1409  		for i := range [8]int{} {
  1410  			x0, y0 := test.x, test.y
  1411  			if i&1 != 0 {
  1412  				x0 = -x0
  1413  			}
  1414  			if i&2 != 0 {
  1415  				y0 = -y0
  1416  			}
  1417  			if i&4 != 0 {
  1418  				x0, y0 = y0, x0
  1419  			}
  1420  
  1421  			x := NewFloat(x0)
  1422  			y := NewFloat(y0)
  1423  			z := new(Float).SetPrec(53)
  1424  
  1425  			z.Mul(x, y)
  1426  			got, _ := z.Float64()
  1427  			want := x0 * y0
  1428  			if got != want {
  1429  				t.Errorf("%g * %g = %g; want %g", x0, y0, got, want)
  1430  			}
  1431  
  1432  			if y0 == 0 {
  1433  				continue // avoid division-by-zero
  1434  			}
  1435  			z.Quo(z, y)
  1436  			got, _ = z.Float64()
  1437  			want /= y0
  1438  			if got != want {
  1439  				t.Errorf("%g / %g = %g; want %g", x0*y0, y0, got, want)
  1440  			}
  1441  		}
  1442  	}
  1443  }
  1444  
  1445  func TestIssue6866(t *testing.T) {
  1446  	for _, prec := range precList {
  1447  		two := new(Float).SetPrec(prec).SetInt64(2)
  1448  		one := new(Float).SetPrec(prec).SetInt64(1)
  1449  		three := new(Float).SetPrec(prec).SetInt64(3)
  1450  		msix := new(Float).SetPrec(prec).SetInt64(-6)
  1451  		psix := new(Float).SetPrec(prec).SetInt64(+6)
  1452  
  1453  		p := new(Float).SetPrec(prec)
  1454  		z1 := new(Float).SetPrec(prec)
  1455  		z2 := new(Float).SetPrec(prec)
  1456  
  1457  		// z1 = 2 + 1.0/3*-6
  1458  		p.Quo(one, three)
  1459  		p.Mul(p, msix)
  1460  		z1.Add(two, p)
  1461  
  1462  		// z2 = 2 - 1.0/3*+6
  1463  		p.Quo(one, three)
  1464  		p.Mul(p, psix)
  1465  		z2.Sub(two, p)
  1466  
  1467  		if z1.Cmp(z2) != 0 {
  1468  			t.Fatalf("prec %d: got z1 = %s != z2 = %s; want z1 == z2\n", prec, z1, z2)
  1469  		}
  1470  		if z1.Sign() != 0 {
  1471  			t.Errorf("prec %d: got z1 = %s; want 0", prec, z1)
  1472  		}
  1473  		if z2.Sign() != 0 {
  1474  			t.Errorf("prec %d: got z2 = %s; want 0", prec, z2)
  1475  		}
  1476  	}
  1477  }
  1478  
  1479  func TestFloatQuo(t *testing.T) {
  1480  	// TODO(gri) make the test vary these precisions
  1481  	preci := 200 // precision of integer part
  1482  	precf := 20  // precision of fractional part
  1483  
  1484  	for i := 0; i < 8; i++ {
  1485  		// compute accurate (not rounded) result z
  1486  		bits := Bits{preci - 1}
  1487  		if i&3 != 0 {
  1488  			bits = append(bits, 0)
  1489  		}
  1490  		if i&2 != 0 {
  1491  			bits = append(bits, -1)
  1492  		}
  1493  		if i&1 != 0 {
  1494  			bits = append(bits, -precf)
  1495  		}
  1496  		z := bits.Float()
  1497  
  1498  		// compute accurate x as z*y
  1499  		y := NewFloat(3.14159265358979323e123)
  1500  
  1501  		x := new(Float).SetPrec(z.Prec() + y.Prec()).SetMode(ToZero)
  1502  		x.Mul(z, y)
  1503  
  1504  		// leave for debugging
  1505  		// fmt.Printf("x = %s\ny = %s\nz = %s\n", x, y, z)
  1506  
  1507  		if got := x.Acc(); got != Exact {
  1508  			t.Errorf("got acc = %s; want exact", got)
  1509  		}
  1510  
  1511  		// round accurate z for a variety of precisions and
  1512  		// modes and compare against result of x / y.
  1513  		for _, mode := range [...]RoundingMode{ToZero, ToNearestEven, AwayFromZero} {
  1514  			for d := -5; d < 5; d++ {
  1515  				prec := uint(preci + d)
  1516  				got := new(Float).SetPrec(prec).SetMode(mode).Quo(x, y)
  1517  				want := bits.round(prec, mode)
  1518  				if got.Cmp(want) != 0 {
  1519  					t.Errorf("i = %d, prec = %d, %s:\n\t     %s\n\t/    %s\n\t=    %s\n\twant %s",
  1520  						i, prec, mode, x, y, got, want)
  1521  				}
  1522  			}
  1523  		}
  1524  	}
  1525  }
  1526  
  1527  var long = flag.Bool("long", false, "run very long tests")
  1528  
  1529  // TestFloatQuoSmoke tests all divisions x/y for values x, y in the range [-n, +n];
  1530  // it serves as a smoke test for basic correctness of division.
  1531  func TestFloatQuoSmoke(t *testing.T) {
  1532  	n := 10
  1533  	if *long {
  1534  		n = 1000
  1535  	}
  1536  
  1537  	const dprec = 3         // max. precision variation
  1538  	const prec = 10 + dprec // enough bits to hold n precisely
  1539  	for x := -n; x <= n; x++ {
  1540  		for y := -n; y < n; y++ {
  1541  			if y == 0 {
  1542  				continue
  1543  			}
  1544  
  1545  			a := float64(x)
  1546  			b := float64(y)
  1547  			c := a / b
  1548  
  1549  			// vary operand precision (only ok as long as a, b can be represented correctly)
  1550  			for ad := -dprec; ad <= dprec; ad++ {
  1551  				for bd := -dprec; bd <= dprec; bd++ {
  1552  					A := new(Float).SetPrec(uint(prec + ad)).SetFloat64(a)
  1553  					B := new(Float).SetPrec(uint(prec + bd)).SetFloat64(b)
  1554  					C := new(Float).SetPrec(53).Quo(A, B) // C has float64 mantissa width
  1555  
  1556  					cc, acc := C.Float64()
  1557  					if cc != c {
  1558  						t.Errorf("%g/%g = %s; want %.5g\n", a, b, C.Text('g', 5), c)
  1559  						continue
  1560  					}
  1561  					if acc != Exact {
  1562  						t.Errorf("%g/%g got %s result; want exact result", a, b, acc)
  1563  					}
  1564  				}
  1565  			}
  1566  		}
  1567  	}
  1568  }
  1569  
  1570  // TestFloatArithmeticSpecialValues tests that Float operations produce the
  1571  // correct results for combinations of zero (±0), finite (±1 and ±2.71828),
  1572  // and infinite (±Inf) operands.
  1573  func TestFloatArithmeticSpecialValues(t *testing.T) {
  1574  	zero := 0.0
  1575  	args := []float64{math.Inf(-1), -2.71828, -1, -zero, zero, 1, 2.71828, math.Inf(1)}
  1576  	xx := new(Float)
  1577  	yy := new(Float)
  1578  	got := new(Float)
  1579  	want := new(Float)
  1580  	for i := 0; i < 4; i++ {
  1581  		for _, x := range args {
  1582  			xx.SetFloat64(x)
  1583  			// check conversion is correct
  1584  			// (no need to do this for y, since we see exactly the
  1585  			// same values there)
  1586  			if got, acc := xx.Float64(); got != x || acc != Exact {
  1587  				t.Errorf("Float(%g) == %g (%s)", x, got, acc)
  1588  			}
  1589  			for _, y := range args {
  1590  				yy.SetFloat64(y)
  1591  				var (
  1592  					op string
  1593  					z  float64
  1594  					f  func(z, x, y *Float) *Float
  1595  				)
  1596  				switch i {
  1597  				case 0:
  1598  					op = "+"
  1599  					z = x + y
  1600  					f = (*Float).Add
  1601  				case 1:
  1602  					op = "-"
  1603  					z = x - y
  1604  					f = (*Float).Sub
  1605  				case 2:
  1606  					op = "*"
  1607  					z = x * y
  1608  					f = (*Float).Mul
  1609  				case 3:
  1610  					op = "/"
  1611  					z = x / y
  1612  					f = (*Float).Quo
  1613  				default:
  1614  					panic("unreachable")
  1615  				}
  1616  				var errnan bool // set if execution of f panicked with ErrNaN
  1617  				// protect execution of f
  1618  				func() {
  1619  					defer func() {
  1620  						if p := recover(); p != nil {
  1621  							_ = p.(ErrNaN) // re-panic if not ErrNaN
  1622  							errnan = true
  1623  						}
  1624  					}()
  1625  					f(got, xx, yy)
  1626  				}()
  1627  				if math.IsNaN(z) {
  1628  					if !errnan {
  1629  						t.Errorf("%5g %s %5g = %5s; want ErrNaN panic", x, op, y, got)
  1630  					}
  1631  					continue
  1632  				}
  1633  				if errnan {
  1634  					t.Errorf("%5g %s %5g panicked with ErrNan; want %5s", x, op, y, want)
  1635  					continue
  1636  				}
  1637  				want.SetFloat64(z)
  1638  				if !alike(got, want) {
  1639  					t.Errorf("%5g %s %5g = %5s; want %5s", x, op, y, got, want)
  1640  				}
  1641  			}
  1642  		}
  1643  	}
  1644  }
  1645  
  1646  func TestFloatArithmeticOverflow(t *testing.T) {
  1647  	for _, test := range []struct {
  1648  		prec       uint
  1649  		mode       RoundingMode
  1650  		op         byte
  1651  		x, y, want string
  1652  		acc        Accuracy
  1653  	}{
  1654  		{4, ToNearestEven, '+', "0", "0", "0", Exact},                   // smoke test
  1655  		{4, ToNearestEven, '+', "0x.8p+0", "0x.8p+0", "0x.8p+1", Exact}, // smoke test
  1656  
  1657  		{4, ToNearestEven, '+', "0", "0x.8p2147483647", "0x.8p+2147483647", Exact},
  1658  		{4, ToNearestEven, '+', "0x.8p2147483500", "0x.8p2147483647", "0x.8p+2147483647", Below}, // rounded to zero
  1659  		{4, ToNearestEven, '+', "0x.8p2147483647", "0x.8p2147483647", "+Inf", Above},             // exponent overflow in +
  1660  		{4, ToNearestEven, '+', "-0x.8p2147483647", "-0x.8p2147483647", "-Inf", Below},           // exponent overflow in +
  1661  		{4, ToNearestEven, '-', "-0x.8p2147483647", "0x.8p2147483647", "-Inf", Below},            // exponent overflow in -
  1662  
  1663  		{4, ToZero, '+', "0x.fp2147483647", "0x.8p2147483643", "0x.fp+2147483647", Below}, // rounded to zero
  1664  		{4, ToNearestEven, '+', "0x.fp2147483647", "0x.8p2147483643", "+Inf", Above},      // exponent overflow in rounding
  1665  		{4, AwayFromZero, '+', "0x.fp2147483647", "0x.8p2147483643", "+Inf", Above},       // exponent overflow in rounding
  1666  
  1667  		{4, AwayFromZero, '-', "-0x.fp2147483647", "0x.8p2147483644", "-Inf", Below},        // exponent overflow in rounding
  1668  		{4, ToNearestEven, '-', "-0x.fp2147483647", "0x.8p2147483643", "-Inf", Below},       // exponent overflow in rounding
  1669  		{4, ToZero, '-', "-0x.fp2147483647", "0x.8p2147483643", "-0x.fp+2147483647", Above}, // rounded to zero
  1670  
  1671  		{4, ToNearestEven, '+', "0", "0x.8p-2147483648", "0x.8p-2147483648", Exact},
  1672  		{4, ToNearestEven, '+', "0x.8p-2147483648", "0x.8p-2147483648", "0x.8p-2147483647", Exact},
  1673  
  1674  		{4, ToNearestEven, '*', "1", "0x.8p2147483647", "0x.8p+2147483647", Exact},
  1675  		{4, ToNearestEven, '*', "2", "0x.8p2147483647", "+Inf", Above},  // exponent overflow in *
  1676  		{4, ToNearestEven, '*', "-2", "0x.8p2147483647", "-Inf", Below}, // exponent overflow in *
  1677  
  1678  		{4, ToNearestEven, '/', "0.5", "0x.8p2147483647", "0x.8p-2147483646", Exact},
  1679  		{4, ToNearestEven, '/', "0x.8p+0", "0x.8p2147483647", "0x.8p-2147483646", Exact},
  1680  		{4, ToNearestEven, '/', "0x.8p-1", "0x.8p2147483647", "0x.8p-2147483647", Exact},
  1681  		{4, ToNearestEven, '/', "0x.8p-2", "0x.8p2147483647", "0x.8p-2147483648", Exact},
  1682  		{4, ToNearestEven, '/', "0x.8p-3", "0x.8p2147483647", "0", Below}, // exponent underflow in /
  1683  	} {
  1684  		x := makeFloat(test.x)
  1685  		y := makeFloat(test.y)
  1686  		z := new(Float).SetPrec(test.prec).SetMode(test.mode)
  1687  		switch test.op {
  1688  		case '+':
  1689  			z.Add(x, y)
  1690  		case '-':
  1691  			z.Sub(x, y)
  1692  		case '*':
  1693  			z.Mul(x, y)
  1694  		case '/':
  1695  			z.Quo(x, y)
  1696  		default:
  1697  			panic("unreachable")
  1698  		}
  1699  		if got := z.Text('p', 0); got != test.want || z.Acc() != test.acc {
  1700  			t.Errorf(
  1701  				"prec = %d (%s): %s %c %s = %s (%s); want %s (%s)",
  1702  				test.prec, test.mode, x.Text('p', 0), test.op, y.Text('p', 0), got, z.Acc(), test.want, test.acc,
  1703  			)
  1704  		}
  1705  	}
  1706  }
  1707  
  1708  // TODO(gri) Add tests that check correctness in the presence of aliasing.
  1709  
  1710  // For rounding modes ToNegativeInf and ToPositiveInf, rounding is affected
  1711  // by the sign of the value to be rounded. Test that rounding happens after
  1712  // the sign of a result has been set.
  1713  // This test uses specific values that are known to fail if rounding is
  1714  // "factored" out before setting the result sign.
  1715  func TestFloatArithmeticRounding(t *testing.T) {
  1716  	for _, test := range []struct {
  1717  		mode       RoundingMode
  1718  		prec       uint
  1719  		x, y, want int64
  1720  		op         byte
  1721  	}{
  1722  		{ToZero, 3, -0x8, -0x1, -0x8, '+'},
  1723  		{AwayFromZero, 3, -0x8, -0x1, -0xa, '+'},
  1724  		{ToNegativeInf, 3, -0x8, -0x1, -0xa, '+'},
  1725  
  1726  		{ToZero, 3, -0x8, 0x1, -0x8, '-'},
  1727  		{AwayFromZero, 3, -0x8, 0x1, -0xa, '-'},
  1728  		{ToNegativeInf, 3, -0x8, 0x1, -0xa, '-'},
  1729  
  1730  		{ToZero, 3, -0x9, 0x1, -0x8, '*'},
  1731  		{AwayFromZero, 3, -0x9, 0x1, -0xa, '*'},
  1732  		{ToNegativeInf, 3, -0x9, 0x1, -0xa, '*'},
  1733  
  1734  		{ToZero, 3, -0x9, 0x1, -0x8, '/'},
  1735  		{AwayFromZero, 3, -0x9, 0x1, -0xa, '/'},
  1736  		{ToNegativeInf, 3, -0x9, 0x1, -0xa, '/'},
  1737  	} {
  1738  		var x, y, z Float
  1739  		x.SetInt64(test.x)
  1740  		y.SetInt64(test.y)
  1741  		z.SetPrec(test.prec).SetMode(test.mode)
  1742  		switch test.op {
  1743  		case '+':
  1744  			z.Add(&x, &y)
  1745  		case '-':
  1746  			z.Sub(&x, &y)
  1747  		case '*':
  1748  			z.Mul(&x, &y)
  1749  		case '/':
  1750  			z.Quo(&x, &y)
  1751  		default:
  1752  			panic("unreachable")
  1753  		}
  1754  		if got, acc := z.Int64(); got != test.want || acc != Exact {
  1755  			t.Errorf("%s, %d bits: %d %c %d = %d (%s); want %d (Exact)",
  1756  				test.mode, test.prec, test.x, test.op, test.y, got, acc, test.want,
  1757  			)
  1758  		}
  1759  	}
  1760  }
  1761  
  1762  // TestFloatCmpSpecialValues tests that Cmp produces the correct results for
  1763  // combinations of zero (±0), finite (±1 and ±2.71828), and infinite (±Inf)
  1764  // operands.
  1765  func TestFloatCmpSpecialValues(t *testing.T) {
  1766  	zero := 0.0
  1767  	args := []float64{math.Inf(-1), -2.71828, -1, -zero, zero, 1, 2.71828, math.Inf(1)}
  1768  	xx := new(Float)
  1769  	yy := new(Float)
  1770  	for i := 0; i < 4; i++ {
  1771  		for _, x := range args {
  1772  			xx.SetFloat64(x)
  1773  			// check conversion is correct
  1774  			// (no need to do this for y, since we see exactly the
  1775  			// same values there)
  1776  			if got, acc := xx.Float64(); got != x || acc != Exact {
  1777  				t.Errorf("Float(%g) == %g (%s)", x, got, acc)
  1778  			}
  1779  			for _, y := range args {
  1780  				yy.SetFloat64(y)
  1781  				got := xx.Cmp(yy)
  1782  				want := 0
  1783  				switch {
  1784  				case x < y:
  1785  					want = -1
  1786  				case x > y:
  1787  					want = +1
  1788  				}
  1789  				if got != want {
  1790  					t.Errorf("(%g).Cmp(%g) = %v; want %v", x, y, got, want)
  1791  				}
  1792  			}
  1793  		}
  1794  	}
  1795  }
  1796  
  1797  func BenchmarkFloatAdd(b *testing.B) {
  1798  	x := new(Float)
  1799  	y := new(Float)
  1800  	z := new(Float)
  1801  
  1802  	for _, prec := range []uint{10, 1e2, 1e3, 1e4, 1e5} {
  1803  		x.SetPrec(prec).SetRat(NewRat(1, 3))
  1804  		y.SetPrec(prec).SetRat(NewRat(1, 6))
  1805  		z.SetPrec(prec)
  1806  
  1807  		b.Run(fmt.Sprintf("%v", prec), func(b *testing.B) {
  1808  			b.ReportAllocs()
  1809  			for i := 0; i < b.N; i++ {
  1810  				z.Add(x, y)
  1811  			}
  1812  		})
  1813  	}
  1814  }
  1815  
  1816  func BenchmarkFloatSub(b *testing.B) {
  1817  	x := new(Float)
  1818  	y := new(Float)
  1819  	z := new(Float)
  1820  
  1821  	for _, prec := range []uint{10, 1e2, 1e3, 1e4, 1e5} {
  1822  		x.SetPrec(prec).SetRat(NewRat(1, 3))
  1823  		y.SetPrec(prec).SetRat(NewRat(1, 6))
  1824  		z.SetPrec(prec)
  1825  
  1826  		b.Run(fmt.Sprintf("%v", prec), func(b *testing.B) {
  1827  			b.ReportAllocs()
  1828  			for i := 0; i < b.N; i++ {
  1829  				z.Sub(x, y)
  1830  			}
  1831  		})
  1832  	}
  1833  }