github.com/q45/go@v0.0.0-20151101211701-a4fb8c13db3f/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
   833  		{"1e-1000", 0, Below},
   834  		{"0x0.000002p-127", 0, Below},
   835  		{"0x.0000010p-126", 0, Below},
   836  
   837  		// denormals
   838  		{"1.401298464e-45", math.SmallestNonzeroFloat32, Above}, // rounded up to smallest denormal
   839  		{"0x.ffffff8p-149", math.SmallestNonzeroFloat32, Above}, // rounded up to smallest denormal
   840  		{"0x.0000018p-126", math.SmallestNonzeroFloat32, Above}, // rounded up to smallest denormal
   841  		{"0x.0000020p-126", math.SmallestNonzeroFloat32, Exact},
   842  		{"0x.8p-148", math.SmallestNonzeroFloat32, Exact},
   843  		{"1p-149", math.SmallestNonzeroFloat32, Exact},
   844  		{"0x.fffffep-126", math.Float32frombits(0x7fffff), Exact}, // largest denormal
   845  
   846  		// normals
   847  		{"0x.ffffffp-126", math.Float32frombits(0x00800000), Above}, // rounded up to smallest normal
   848  		{"1p-126", math.Float32frombits(0x00800000), Exact},         // smallest normal
   849  		{"0x1.fffffep-126", math.Float32frombits(0x00ffffff), Exact},
   850  		{"0x1.ffffffp-126", math.Float32frombits(0x01000000), Above}, // rounded up
   851  		{"1", 1, Exact},
   852  		{"1.000000000000000000001", 1, Below},
   853  		{"12345.0", 12345, Exact},
   854  		{"12345.000000000000000000001", 12345, Below},
   855  		{"0x1.fffffe0p127", math.MaxFloat32, Exact},
   856  		{"0x1.fffffe8p127", math.MaxFloat32, Below},
   857  
   858  		// overflow
   859  		{"0x1.ffffff0p127", float32(math.Inf(+1)), Above},
   860  		{"0x1p128", float32(math.Inf(+1)), Above},
   861  		{"1e10000", float32(math.Inf(+1)), Above},
   862  		{"0x1.ffffff0p2147483646", float32(math.Inf(+1)), Above}, // overflow in rounding
   863  
   864  		// inf
   865  		{"Inf", float32(math.Inf(+1)), Exact},
   866  	} {
   867  		for i := 0; i < 2; i++ {
   868  			// test both signs
   869  			tx, tout, tacc := test.x, test.out, test.acc
   870  			if i != 0 {
   871  				tx = "-" + tx
   872  				tout = -tout
   873  				tacc = -tacc
   874  			}
   875  
   876  			// conversion should match strconv where syntax is agreeable
   877  			if f, err := strconv.ParseFloat(tx, 32); err == nil && !alike32(float32(f), tout) {
   878  				t.Errorf("%s: got %g; want %g (incorrect test data)", tx, f, tout)
   879  			}
   880  
   881  			x := makeFloat(tx)
   882  			out, acc := x.Float32()
   883  			if !alike32(out, tout) || acc != tacc {
   884  				t.Errorf("%s: got %g (%#x, %s); want %g (%#x, %s)", tx, out, math.Float32bits(out), acc, test.out, math.Float32bits(test.out), tacc)
   885  			}
   886  
   887  			// test that x.SetFloat64(float64(f)).Float32() == f
   888  			var x2 Float
   889  			out2, acc2 := x2.SetFloat64(float64(out)).Float32()
   890  			if !alike32(out2, out) || acc2 != Exact {
   891  				t.Errorf("idempotency test: got %g (%s); want %g (Exact)", out2, acc2, out)
   892  			}
   893  		}
   894  	}
   895  }
   896  
   897  func TestFloatFloat64(t *testing.T) {
   898  	const smallestNormalFloat64 = 2.2250738585072014e-308 // 1p-1022
   899  	for _, test := range []struct {
   900  		x   string
   901  		out float64
   902  		acc Accuracy
   903  	}{
   904  		{"0", 0, Exact},
   905  
   906  		// underflow
   907  		{"1e-1000", 0, Below},
   908  		{"0x0.0000000000001p-1023", 0, Below},
   909  		{"0x0.00000000000008p-1022", 0, Below},
   910  
   911  		// denormals
   912  		{"0x0.0000000000000cp-1022", math.SmallestNonzeroFloat64, Above}, // rounded up to smallest denormal
   913  		{"0x0.0000000000001p-1022", math.SmallestNonzeroFloat64, Exact},  // smallest denormal
   914  		{"0x.8p-1073", math.SmallestNonzeroFloat64, Exact},
   915  		{"1p-1074", math.SmallestNonzeroFloat64, Exact},
   916  		{"0x.fffffffffffffp-1022", math.Float64frombits(0x000fffffffffffff), Exact}, // largest denormal
   917  
   918  		// normals
   919  		{"0x.fffffffffffff8p-1022", math.Float64frombits(0x0010000000000000), Above}, // rounded up to smallest normal
   920  		{"1p-1022", math.Float64frombits(0x0010000000000000), Exact},                 // smallest normal
   921  		{"1", 1, Exact},
   922  		{"1.000000000000000000001", 1, Below},
   923  		{"12345.0", 12345, Exact},
   924  		{"12345.000000000000000000001", 12345, Below},
   925  		{"0x1.fffffffffffff0p1023", math.MaxFloat64, Exact},
   926  		{"0x1.fffffffffffff4p1023", math.MaxFloat64, Below},
   927  
   928  		// overflow
   929  		{"0x1.fffffffffffff8p1023", math.Inf(+1), Above},
   930  		{"0x1p1024", math.Inf(+1), Above},
   931  		{"1e10000", math.Inf(+1), Above},
   932  		{"0x1.fffffffffffff8p2147483646", math.Inf(+1), Above}, // overflow in rounding
   933  		{"Inf", math.Inf(+1), Exact},
   934  
   935  		// selected denormalized values that were handled incorrectly in the past
   936  		{"0x.fffffffffffffp-1022", smallestNormalFloat64 - math.SmallestNonzeroFloat64, Exact},
   937  		{"4503599627370495p-1074", smallestNormalFloat64 - math.SmallestNonzeroFloat64, Exact},
   938  
   939  		// http://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
   940  		{"2.2250738585072011e-308", 2.225073858507201e-308, Below},
   941  		// http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
   942  		{"2.2250738585072012e-308", 2.2250738585072014e-308, Above},
   943  	} {
   944  		for i := 0; i < 2; i++ {
   945  			// test both signs
   946  			tx, tout, tacc := test.x, test.out, test.acc
   947  			if i != 0 {
   948  				tx = "-" + tx
   949  				tout = -tout
   950  				tacc = -tacc
   951  			}
   952  
   953  			// conversion should match strconv where syntax is agreeable
   954  			if f, err := strconv.ParseFloat(tx, 64); err == nil && !alike64(f, tout) {
   955  				t.Errorf("%s: got %g; want %g (incorrect test data)", tx, f, tout)
   956  			}
   957  
   958  			x := makeFloat(tx)
   959  			out, acc := x.Float64()
   960  			if !alike64(out, tout) || acc != tacc {
   961  				t.Errorf("%s: got %g (%#x, %s); want %g (%#x, %s)", tx, out, math.Float64bits(out), acc, test.out, math.Float64bits(test.out), tacc)
   962  			}
   963  
   964  			// test that x.SetFloat64(f).Float64() == f
   965  			var x2 Float
   966  			out2, acc2 := x2.SetFloat64(out).Float64()
   967  			if !alike64(out2, out) || acc2 != Exact {
   968  				t.Errorf("idempotency test: got %g (%s); want %g (Exact)", out2, acc2, out)
   969  			}
   970  		}
   971  	}
   972  }
   973  
   974  func TestFloatInt(t *testing.T) {
   975  	for _, test := range []struct {
   976  		x    string
   977  		want string
   978  		acc  Accuracy
   979  	}{
   980  		{"0", "0", Exact},
   981  		{"+0", "0", Exact},
   982  		{"-0", "0", Exact},
   983  		{"Inf", "nil", Below},
   984  		{"+Inf", "nil", Below},
   985  		{"-Inf", "nil", Above},
   986  		{"1", "1", Exact},
   987  		{"-1", "-1", Exact},
   988  		{"1.23", "1", Below},
   989  		{"-1.23", "-1", Above},
   990  		{"123e-2", "1", Below},
   991  		{"123e-3", "0", Below},
   992  		{"123e-4", "0", Below},
   993  		{"1e-1000", "0", Below},
   994  		{"-1e-1000", "0", Above},
   995  		{"1e+10", "10000000000", Exact},
   996  		{"1e+100", "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", Exact},
   997  	} {
   998  		x := makeFloat(test.x)
   999  		res, acc := x.Int(nil)
  1000  		got := "nil"
  1001  		if res != nil {
  1002  			got = res.String()
  1003  		}
  1004  		if got != test.want || acc != test.acc {
  1005  			t.Errorf("%s: got %s (%s); want %s (%s)", test.x, got, acc, test.want, test.acc)
  1006  		}
  1007  	}
  1008  
  1009  	// check that supplied *Int is used
  1010  	for _, f := range []string{"0", "1", "-1", "1234"} {
  1011  		x := makeFloat(f)
  1012  		i := new(Int)
  1013  		if res, _ := x.Int(i); res != i {
  1014  			t.Errorf("(%s).Int is not using supplied *Int", f)
  1015  		}
  1016  	}
  1017  }
  1018  
  1019  func TestFloatRat(t *testing.T) {
  1020  	for _, test := range []struct {
  1021  		x, want string
  1022  		acc     Accuracy
  1023  	}{
  1024  		{"0", "0/1", Exact},
  1025  		{"+0", "0/1", Exact},
  1026  		{"-0", "0/1", Exact},
  1027  		{"Inf", "nil", Below},
  1028  		{"+Inf", "nil", Below},
  1029  		{"-Inf", "nil", Above},
  1030  		{"1", "1/1", Exact},
  1031  		{"-1", "-1/1", Exact},
  1032  		{"1.25", "5/4", Exact},
  1033  		{"-1.25", "-5/4", Exact},
  1034  		{"1e10", "10000000000/1", Exact},
  1035  		{"1p10", "1024/1", Exact},
  1036  		{"-1p-10", "-1/1024", Exact},
  1037  		{"3.14159265", "7244019449799623199/2305843009213693952", Exact},
  1038  	} {
  1039  		x := makeFloat(test.x).SetPrec(64)
  1040  		res, acc := x.Rat(nil)
  1041  		got := "nil"
  1042  		if res != nil {
  1043  			got = res.String()
  1044  		}
  1045  		if got != test.want {
  1046  			t.Errorf("%s: got %s; want %s", test.x, got, test.want)
  1047  			continue
  1048  		}
  1049  		if acc != test.acc {
  1050  			t.Errorf("%s: got %s; want %s", test.x, acc, test.acc)
  1051  			continue
  1052  		}
  1053  
  1054  		// inverse conversion
  1055  		if res != nil {
  1056  			got := new(Float).SetPrec(64).SetRat(res)
  1057  			if got.Cmp(x) != 0 {
  1058  				t.Errorf("%s: got %s; want %s", test.x, got, x)
  1059  			}
  1060  		}
  1061  	}
  1062  
  1063  	// check that supplied *Rat is used
  1064  	for _, f := range []string{"0", "1", "-1", "1234"} {
  1065  		x := makeFloat(f)
  1066  		r := new(Rat)
  1067  		if res, _ := x.Rat(r); res != r {
  1068  			t.Errorf("(%s).Rat is not using supplied *Rat", f)
  1069  		}
  1070  	}
  1071  }
  1072  
  1073  func TestFloatAbs(t *testing.T) {
  1074  	for _, test := range []string{
  1075  		"0",
  1076  		"1",
  1077  		"1234",
  1078  		"1.23e-2",
  1079  		"1e-1000",
  1080  		"1e1000",
  1081  		"Inf",
  1082  	} {
  1083  		p := makeFloat(test)
  1084  		a := new(Float).Abs(p)
  1085  		if !alike(a, p) {
  1086  			t.Errorf("%s: got %s; want %s", test, a.Text('g', 10), test)
  1087  		}
  1088  
  1089  		n := makeFloat("-" + test)
  1090  		a.Abs(n)
  1091  		if !alike(a, p) {
  1092  			t.Errorf("-%s: got %s; want %s", test, a.Text('g', 10), test)
  1093  		}
  1094  	}
  1095  }
  1096  
  1097  func TestFloatNeg(t *testing.T) {
  1098  	for _, test := range []string{
  1099  		"0",
  1100  		"1",
  1101  		"1234",
  1102  		"1.23e-2",
  1103  		"1e-1000",
  1104  		"1e1000",
  1105  		"Inf",
  1106  	} {
  1107  		p1 := makeFloat(test)
  1108  		n1 := makeFloat("-" + test)
  1109  		n2 := new(Float).Neg(p1)
  1110  		p2 := new(Float).Neg(n2)
  1111  		if !alike(n2, n1) {
  1112  			t.Errorf("%s: got %s; want %s", test, n2.Text('g', 10), n1.Text('g', 10))
  1113  		}
  1114  		if !alike(p2, p1) {
  1115  			t.Errorf("%s: got %s; want %s", test, p2.Text('g', 10), p1.Text('g', 10))
  1116  		}
  1117  	}
  1118  }
  1119  
  1120  func TestFloatInc(t *testing.T) {
  1121  	const n = 10
  1122  	for _, prec := range precList {
  1123  		if 1<<prec < n {
  1124  			continue // prec must be large enough to hold all numbers from 0 to n
  1125  		}
  1126  		var x, one Float
  1127  		x.SetPrec(prec)
  1128  		one.SetInt64(1)
  1129  		for i := 0; i < n; i++ {
  1130  			x.Add(&x, &one)
  1131  		}
  1132  		if x.Cmp(new(Float).SetInt64(n)) != 0 {
  1133  			t.Errorf("prec = %d: got %s; want %d", prec, &x, n)
  1134  		}
  1135  	}
  1136  }
  1137  
  1138  // Selected precisions with which to run various tests.
  1139  var precList = [...]uint{1, 2, 5, 8, 10, 16, 23, 24, 32, 50, 53, 64, 100, 128, 500, 511, 512, 513, 1000, 10000}
  1140  
  1141  // Selected bits with which to run various tests.
  1142  // Each entry is a list of bits representing a floating-point number (see fromBits).
  1143  var bitsList = [...]Bits{
  1144  	{},           // = 0
  1145  	{0},          // = 1
  1146  	{1},          // = 2
  1147  	{-1},         // = 1/2
  1148  	{10},         // = 2**10 == 1024
  1149  	{-10},        // = 2**-10 == 1/1024
  1150  	{100, 10, 1}, // = 2**100 + 2**10 + 2**1
  1151  	{0, -1, -2, -10},
  1152  	// TODO(gri) add more test cases
  1153  }
  1154  
  1155  // TestFloatAdd tests Float.Add/Sub by comparing the result of a "manual"
  1156  // addition/subtraction of arguments represented by Bits values with the
  1157  // respective Float addition/subtraction for a variety of precisions
  1158  // and rounding modes.
  1159  func TestFloatAdd(t *testing.T) {
  1160  	for _, xbits := range bitsList {
  1161  		for _, ybits := range bitsList {
  1162  			// exact values
  1163  			x := xbits.Float()
  1164  			y := ybits.Float()
  1165  			zbits := xbits.add(ybits)
  1166  			z := zbits.Float()
  1167  
  1168  			for i, mode := range [...]RoundingMode{ToZero, ToNearestEven, AwayFromZero} {
  1169  				for _, prec := range precList {
  1170  					got := new(Float).SetPrec(prec).SetMode(mode)
  1171  					got.Add(x, y)
  1172  					want := zbits.round(prec, mode)
  1173  					if got.Cmp(want) != 0 {
  1174  						t.Errorf("i = %d, prec = %d, %s:\n\t     %s %v\n\t+    %s %v\n\t=    %s\n\twant %s",
  1175  							i, prec, mode, x, xbits, y, ybits, got, want)
  1176  					}
  1177  
  1178  					got.Sub(z, x)
  1179  					want = ybits.round(prec, mode)
  1180  					if got.Cmp(want) != 0 {
  1181  						t.Errorf("i = %d, prec = %d, %s:\n\t     %s %v\n\t-    %s %v\n\t=    %s\n\twant %s",
  1182  							i, prec, mode, z, zbits, x, xbits, got, want)
  1183  					}
  1184  				}
  1185  			}
  1186  		}
  1187  	}
  1188  }
  1189  
  1190  // TestFloatAdd32 tests that Float.Add/Sub of numbers with
  1191  // 24bit mantissa behaves like float32 addition/subtraction
  1192  // (excluding denormal numbers).
  1193  func TestFloatAdd32(t *testing.T) {
  1194  	// chose base such that we cross the mantissa precision limit
  1195  	const base = 1<<26 - 0x10 // 11...110000 (26 bits)
  1196  	for d := 0; d <= 0x10; d++ {
  1197  		for i := range [2]int{} {
  1198  			x0, y0 := float64(base), float64(d)
  1199  			if i&1 != 0 {
  1200  				x0, y0 = y0, x0
  1201  			}
  1202  
  1203  			x := NewFloat(x0)
  1204  			y := NewFloat(y0)
  1205  			z := new(Float).SetPrec(24)
  1206  
  1207  			z.Add(x, y)
  1208  			got, acc := z.Float32()
  1209  			want := float32(y0) + float32(x0)
  1210  			if got != want || acc != Exact {
  1211  				t.Errorf("d = %d: %g + %g = %g (%s); want %g (Exact)", d, x0, y0, got, acc, want)
  1212  			}
  1213  
  1214  			z.Sub(z, y)
  1215  			got, acc = z.Float32()
  1216  			want = float32(want) - float32(y0)
  1217  			if got != want || acc != Exact {
  1218  				t.Errorf("d = %d: %g - %g = %g (%s); want %g (Exact)", d, x0+y0, y0, got, acc, want)
  1219  			}
  1220  		}
  1221  	}
  1222  }
  1223  
  1224  // TestFloatAdd64 tests that Float.Add/Sub of numbers with
  1225  // 53bit mantissa behaves like float64 addition/subtraction.
  1226  func TestFloatAdd64(t *testing.T) {
  1227  	// chose base such that we cross the mantissa precision limit
  1228  	const base = 1<<55 - 0x10 // 11...110000 (55 bits)
  1229  	for d := 0; d <= 0x10; d++ {
  1230  		for i := range [2]int{} {
  1231  			x0, y0 := float64(base), float64(d)
  1232  			if i&1 != 0 {
  1233  				x0, y0 = y0, x0
  1234  			}
  1235  
  1236  			x := NewFloat(x0)
  1237  			y := NewFloat(y0)
  1238  			z := new(Float).SetPrec(53)
  1239  
  1240  			z.Add(x, y)
  1241  			got, acc := z.Float64()
  1242  			want := x0 + y0
  1243  			if got != want || acc != Exact {
  1244  				t.Errorf("d = %d: %g + %g = %g (%s); want %g (Exact)", d, x0, y0, got, acc, want)
  1245  			}
  1246  
  1247  			z.Sub(z, y)
  1248  			got, acc = z.Float64()
  1249  			want -= y0
  1250  			if got != want || acc != Exact {
  1251  				t.Errorf("d = %d: %g - %g = %g (%s); want %g (Exact)", d, x0+y0, y0, got, acc, want)
  1252  			}
  1253  		}
  1254  	}
  1255  }
  1256  
  1257  // TestFloatMul tests Float.Mul/Quo by comparing the result of a "manual"
  1258  // multiplication/division of arguments represented by Bits values with the
  1259  // respective Float multiplication/division for a variety of precisions
  1260  // and rounding modes.
  1261  func TestFloatMul(t *testing.T) {
  1262  	for _, xbits := range bitsList {
  1263  		for _, ybits := range bitsList {
  1264  			// exact values
  1265  			x := xbits.Float()
  1266  			y := ybits.Float()
  1267  			zbits := xbits.mul(ybits)
  1268  			z := zbits.Float()
  1269  
  1270  			for i, mode := range [...]RoundingMode{ToZero, ToNearestEven, AwayFromZero} {
  1271  				for _, prec := range precList {
  1272  					got := new(Float).SetPrec(prec).SetMode(mode)
  1273  					got.Mul(x, y)
  1274  					want := zbits.round(prec, mode)
  1275  					if got.Cmp(want) != 0 {
  1276  						t.Errorf("i = %d, prec = %d, %s:\n\t     %s %v\n\t*    %s %v\n\t=    %s\n\twant %s",
  1277  							i, prec, mode, x, xbits, y, ybits, got, want)
  1278  					}
  1279  
  1280  					if x.Sign() == 0 {
  1281  						continue // ignore div-0 case (not invertable)
  1282  					}
  1283  					got.Quo(z, x)
  1284  					want = ybits.round(prec, mode)
  1285  					if got.Cmp(want) != 0 {
  1286  						t.Errorf("i = %d, prec = %d, %s:\n\t     %s %v\n\t/    %s %v\n\t=    %s\n\twant %s",
  1287  							i, prec, mode, z, zbits, x, xbits, got, want)
  1288  					}
  1289  				}
  1290  			}
  1291  		}
  1292  	}
  1293  }
  1294  
  1295  // TestFloatMul64 tests that Float.Mul/Quo of numbers with
  1296  // 53bit mantissa behaves like float64 multiplication/division.
  1297  func TestFloatMul64(t *testing.T) {
  1298  	for _, test := range []struct {
  1299  		x, y float64
  1300  	}{
  1301  		{0, 0},
  1302  		{0, 1},
  1303  		{1, 1},
  1304  		{1, 1.5},
  1305  		{1.234, 0.5678},
  1306  		{2.718281828, 3.14159265358979},
  1307  		{2.718281828e10, 3.14159265358979e-32},
  1308  		{1.0 / 3, 1e200},
  1309  	} {
  1310  		for i := range [8]int{} {
  1311  			x0, y0 := test.x, test.y
  1312  			if i&1 != 0 {
  1313  				x0 = -x0
  1314  			}
  1315  			if i&2 != 0 {
  1316  				y0 = -y0
  1317  			}
  1318  			if i&4 != 0 {
  1319  				x0, y0 = y0, x0
  1320  			}
  1321  
  1322  			x := NewFloat(x0)
  1323  			y := NewFloat(y0)
  1324  			z := new(Float).SetPrec(53)
  1325  
  1326  			z.Mul(x, y)
  1327  			got, _ := z.Float64()
  1328  			want := x0 * y0
  1329  			if got != want {
  1330  				t.Errorf("%g * %g = %g; want %g", x0, y0, got, want)
  1331  			}
  1332  
  1333  			if y0 == 0 {
  1334  				continue // avoid division-by-zero
  1335  			}
  1336  			z.Quo(z, y)
  1337  			got, _ = z.Float64()
  1338  			want /= y0
  1339  			if got != want {
  1340  				t.Errorf("%g / %g = %g; want %g", x0*y0, y0, got, want)
  1341  			}
  1342  		}
  1343  	}
  1344  }
  1345  
  1346  func TestIssue6866(t *testing.T) {
  1347  	for _, prec := range precList {
  1348  		two := new(Float).SetPrec(prec).SetInt64(2)
  1349  		one := new(Float).SetPrec(prec).SetInt64(1)
  1350  		three := new(Float).SetPrec(prec).SetInt64(3)
  1351  		msix := new(Float).SetPrec(prec).SetInt64(-6)
  1352  		psix := new(Float).SetPrec(prec).SetInt64(+6)
  1353  
  1354  		p := new(Float).SetPrec(prec)
  1355  		z1 := new(Float).SetPrec(prec)
  1356  		z2 := new(Float).SetPrec(prec)
  1357  
  1358  		// z1 = 2 + 1.0/3*-6
  1359  		p.Quo(one, three)
  1360  		p.Mul(p, msix)
  1361  		z1.Add(two, p)
  1362  
  1363  		// z2 = 2 - 1.0/3*+6
  1364  		p.Quo(one, three)
  1365  		p.Mul(p, psix)
  1366  		z2.Sub(two, p)
  1367  
  1368  		if z1.Cmp(z2) != 0 {
  1369  			t.Fatalf("prec %d: got z1 = %s != z2 = %s; want z1 == z2\n", prec, z1, z2)
  1370  		}
  1371  		if z1.Sign() != 0 {
  1372  			t.Errorf("prec %d: got z1 = %s; want 0", prec, z1)
  1373  		}
  1374  		if z2.Sign() != 0 {
  1375  			t.Errorf("prec %d: got z2 = %s; want 0", prec, z2)
  1376  		}
  1377  	}
  1378  }
  1379  
  1380  func TestFloatQuo(t *testing.T) {
  1381  	// TODO(gri) make the test vary these precisions
  1382  	preci := 200 // precision of integer part
  1383  	precf := 20  // precision of fractional part
  1384  
  1385  	for i := 0; i < 8; i++ {
  1386  		// compute accurate (not rounded) result z
  1387  		bits := Bits{preci - 1}
  1388  		if i&3 != 0 {
  1389  			bits = append(bits, 0)
  1390  		}
  1391  		if i&2 != 0 {
  1392  			bits = append(bits, -1)
  1393  		}
  1394  		if i&1 != 0 {
  1395  			bits = append(bits, -precf)
  1396  		}
  1397  		z := bits.Float()
  1398  
  1399  		// compute accurate x as z*y
  1400  		y := NewFloat(3.14159265358979323e123)
  1401  
  1402  		x := new(Float).SetPrec(z.Prec() + y.Prec()).SetMode(ToZero)
  1403  		x.Mul(z, y)
  1404  
  1405  		// leave for debugging
  1406  		// fmt.Printf("x = %s\ny = %s\nz = %s\n", x, y, z)
  1407  
  1408  		if got := x.Acc(); got != Exact {
  1409  			t.Errorf("got acc = %s; want exact", got)
  1410  		}
  1411  
  1412  		// round accurate z for a variety of precisions and
  1413  		// modes and compare against result of x / y.
  1414  		for _, mode := range [...]RoundingMode{ToZero, ToNearestEven, AwayFromZero} {
  1415  			for d := -5; d < 5; d++ {
  1416  				prec := uint(preci + d)
  1417  				got := new(Float).SetPrec(prec).SetMode(mode).Quo(x, y)
  1418  				want := bits.round(prec, mode)
  1419  				if got.Cmp(want) != 0 {
  1420  					t.Errorf("i = %d, prec = %d, %s:\n\t     %s\n\t/    %s\n\t=    %s\n\twant %s",
  1421  						i, prec, mode, x, y, got, want)
  1422  				}
  1423  			}
  1424  		}
  1425  	}
  1426  }
  1427  
  1428  // TestFloatQuoSmoke tests all divisions x/y for values x, y in the range [-n, +n];
  1429  // it serves as a smoke test for basic correctness of division.
  1430  func TestFloatQuoSmoke(t *testing.T) {
  1431  	n := 1000
  1432  	if testing.Short() {
  1433  		n = 10
  1434  	}
  1435  
  1436  	const dprec = 3         // max. precision variation
  1437  	const prec = 10 + dprec // enough bits to hold n precisely
  1438  	for x := -n; x <= n; x++ {
  1439  		for y := -n; y < n; y++ {
  1440  			if y == 0 {
  1441  				continue
  1442  			}
  1443  
  1444  			a := float64(x)
  1445  			b := float64(y)
  1446  			c := a / b
  1447  
  1448  			// vary operand precision (only ok as long as a, b can be represented correctly)
  1449  			for ad := -dprec; ad <= dprec; ad++ {
  1450  				for bd := -dprec; bd <= dprec; bd++ {
  1451  					A := new(Float).SetPrec(uint(prec + ad)).SetFloat64(a)
  1452  					B := new(Float).SetPrec(uint(prec + bd)).SetFloat64(b)
  1453  					C := new(Float).SetPrec(53).Quo(A, B) // C has float64 mantissa width
  1454  
  1455  					cc, acc := C.Float64()
  1456  					if cc != c {
  1457  						t.Errorf("%g/%g = %s; want %.5g\n", a, b, C.Text('g', 5), c)
  1458  						continue
  1459  					}
  1460  					if acc != Exact {
  1461  						t.Errorf("%g/%g got %s result; want exact result", a, b, acc)
  1462  					}
  1463  				}
  1464  			}
  1465  		}
  1466  	}
  1467  }
  1468  
  1469  // TestFloatArithmeticSpecialValues tests that Float operations produce the
  1470  // correct results for combinations of zero (±0), finite (±1 and ±2.71828),
  1471  // and infinite (±Inf) operands.
  1472  func TestFloatArithmeticSpecialValues(t *testing.T) {
  1473  	zero := 0.0
  1474  	args := []float64{math.Inf(-1), -2.71828, -1, -zero, zero, 1, 2.71828, math.Inf(1)}
  1475  	xx := new(Float)
  1476  	yy := new(Float)
  1477  	got := new(Float)
  1478  	want := new(Float)
  1479  	for i := 0; i < 4; i++ {
  1480  		for _, x := range args {
  1481  			xx.SetFloat64(x)
  1482  			// check conversion is correct
  1483  			// (no need to do this for y, since we see exactly the
  1484  			// same values there)
  1485  			if got, acc := xx.Float64(); got != x || acc != Exact {
  1486  				t.Errorf("Float(%g) == %g (%s)", x, got, acc)
  1487  			}
  1488  			for _, y := range args {
  1489  				yy.SetFloat64(y)
  1490  				var (
  1491  					op string
  1492  					z  float64
  1493  					f  func(z, x, y *Float) *Float
  1494  				)
  1495  				switch i {
  1496  				case 0:
  1497  					op = "+"
  1498  					z = x + y
  1499  					f = (*Float).Add
  1500  				case 1:
  1501  					op = "-"
  1502  					z = x - y
  1503  					f = (*Float).Sub
  1504  				case 2:
  1505  					op = "*"
  1506  					z = x * y
  1507  					f = (*Float).Mul
  1508  				case 3:
  1509  					op = "/"
  1510  					z = x / y
  1511  					f = (*Float).Quo
  1512  				default:
  1513  					panic("unreachable")
  1514  				}
  1515  				var errnan bool // set if execution of f panicked with ErrNaN
  1516  				// protect execution of f
  1517  				func() {
  1518  					defer func() {
  1519  						if p := recover(); p != nil {
  1520  							_ = p.(ErrNaN) // re-panic if not ErrNaN
  1521  							errnan = true
  1522  						}
  1523  					}()
  1524  					f(got, xx, yy)
  1525  				}()
  1526  				if math.IsNaN(z) {
  1527  					if !errnan {
  1528  						t.Errorf("%5g %s %5g = %5s; want ErrNaN panic", x, op, y, got)
  1529  					}
  1530  					continue
  1531  				}
  1532  				if errnan {
  1533  					t.Errorf("%5g %s %5g panicked with ErrNan; want %5s", x, op, y, want)
  1534  					continue
  1535  				}
  1536  				want.SetFloat64(z)
  1537  				if !alike(got, want) {
  1538  					t.Errorf("%5g %s %5g = %5s; want %5s", x, op, y, got, want)
  1539  				}
  1540  			}
  1541  		}
  1542  	}
  1543  }
  1544  
  1545  func TestFloatArithmeticOverflow(t *testing.T) {
  1546  	for _, test := range []struct {
  1547  		prec       uint
  1548  		mode       RoundingMode
  1549  		op         byte
  1550  		x, y, want string
  1551  		acc        Accuracy
  1552  	}{
  1553  		{4, ToNearestEven, '+', "0", "0", "0", Exact},                   // smoke test
  1554  		{4, ToNearestEven, '+', "0x.8p+0", "0x.8p+0", "0x.8p+1", Exact}, // smoke test
  1555  
  1556  		{4, ToNearestEven, '+', "0", "0x.8p2147483647", "0x.8p+2147483647", Exact},
  1557  		{4, ToNearestEven, '+', "0x.8p2147483500", "0x.8p2147483647", "0x.8p+2147483647", Below}, // rounded to zero
  1558  		{4, ToNearestEven, '+', "0x.8p2147483647", "0x.8p2147483647", "+Inf", Above},             // exponent overflow in +
  1559  		{4, ToNearestEven, '+', "-0x.8p2147483647", "-0x.8p2147483647", "-Inf", Below},           // exponent overflow in +
  1560  		{4, ToNearestEven, '-', "-0x.8p2147483647", "0x.8p2147483647", "-Inf", Below},            // exponent overflow in -
  1561  
  1562  		{4, ToZero, '+', "0x.fp2147483647", "0x.8p2147483643", "0x.fp+2147483647", Below}, // rounded to zero
  1563  		{4, ToNearestEven, '+', "0x.fp2147483647", "0x.8p2147483643", "+Inf", Above},      // exponent overflow in rounding
  1564  		{4, AwayFromZero, '+', "0x.fp2147483647", "0x.8p2147483643", "+Inf", Above},       // exponent overflow in rounding
  1565  
  1566  		{4, AwayFromZero, '-', "-0x.fp2147483647", "0x.8p2147483644", "-Inf", Below},        // exponent overflow in rounding
  1567  		{4, ToNearestEven, '-', "-0x.fp2147483647", "0x.8p2147483643", "-Inf", Below},       // exponent overflow in rounding
  1568  		{4, ToZero, '-', "-0x.fp2147483647", "0x.8p2147483643", "-0x.fp+2147483647", Above}, // rounded to zero
  1569  
  1570  		{4, ToNearestEven, '+', "0", "0x.8p-2147483648", "0x.8p-2147483648", Exact},
  1571  		{4, ToNearestEven, '+', "0x.8p-2147483648", "0x.8p-2147483648", "0x.8p-2147483647", Exact},
  1572  
  1573  		{4, ToNearestEven, '*', "1", "0x.8p2147483647", "0x.8p+2147483647", Exact},
  1574  		{4, ToNearestEven, '*', "2", "0x.8p2147483647", "+Inf", Above},  // exponent overflow in *
  1575  		{4, ToNearestEven, '*', "-2", "0x.8p2147483647", "-Inf", Below}, // exponent overflow in *
  1576  
  1577  		{4, ToNearestEven, '/', "0.5", "0x.8p2147483647", "0x.8p-2147483646", Exact},
  1578  		{4, ToNearestEven, '/', "0x.8p+0", "0x.8p2147483647", "0x.8p-2147483646", Exact},
  1579  		{4, ToNearestEven, '/', "0x.8p-1", "0x.8p2147483647", "0x.8p-2147483647", Exact},
  1580  		{4, ToNearestEven, '/', "0x.8p-2", "0x.8p2147483647", "0x.8p-2147483648", Exact},
  1581  		{4, ToNearestEven, '/', "0x.8p-3", "0x.8p2147483647", "0", Below}, // exponent underflow in /
  1582  	} {
  1583  		x := makeFloat(test.x)
  1584  		y := makeFloat(test.y)
  1585  		z := new(Float).SetPrec(test.prec).SetMode(test.mode)
  1586  		switch test.op {
  1587  		case '+':
  1588  			z.Add(x, y)
  1589  		case '-':
  1590  			z.Sub(x, y)
  1591  		case '*':
  1592  			z.Mul(x, y)
  1593  		case '/':
  1594  			z.Quo(x, y)
  1595  		default:
  1596  			panic("unreachable")
  1597  		}
  1598  		if got := z.Text('p', 0); got != test.want || z.Acc() != test.acc {
  1599  			t.Errorf(
  1600  				"prec = %d (%s): %s %c %s = %s (%s); want %s (%s)",
  1601  				test.prec, test.mode, x.Text('p', 0), test.op, y.Text('p', 0), got, z.Acc(), test.want, test.acc,
  1602  			)
  1603  		}
  1604  	}
  1605  }
  1606  
  1607  // TODO(gri) Add tests that check correctness in the presence of aliasing.
  1608  
  1609  // For rounding modes ToNegativeInf and ToPositiveInf, rounding is affected
  1610  // by the sign of the value to be rounded. Test that rounding happens after
  1611  // the sign of a result has been set.
  1612  // This test uses specific values that are known to fail if rounding is
  1613  // "factored" out before setting the result sign.
  1614  func TestFloatArithmeticRounding(t *testing.T) {
  1615  	for _, test := range []struct {
  1616  		mode       RoundingMode
  1617  		prec       uint
  1618  		x, y, want int64
  1619  		op         byte
  1620  	}{
  1621  		{ToZero, 3, -0x8, -0x1, -0x8, '+'},
  1622  		{AwayFromZero, 3, -0x8, -0x1, -0xa, '+'},
  1623  		{ToNegativeInf, 3, -0x8, -0x1, -0xa, '+'},
  1624  
  1625  		{ToZero, 3, -0x8, 0x1, -0x8, '-'},
  1626  		{AwayFromZero, 3, -0x8, 0x1, -0xa, '-'},
  1627  		{ToNegativeInf, 3, -0x8, 0x1, -0xa, '-'},
  1628  
  1629  		{ToZero, 3, -0x9, 0x1, -0x8, '*'},
  1630  		{AwayFromZero, 3, -0x9, 0x1, -0xa, '*'},
  1631  		{ToNegativeInf, 3, -0x9, 0x1, -0xa, '*'},
  1632  
  1633  		{ToZero, 3, -0x9, 0x1, -0x8, '/'},
  1634  		{AwayFromZero, 3, -0x9, 0x1, -0xa, '/'},
  1635  		{ToNegativeInf, 3, -0x9, 0x1, -0xa, '/'},
  1636  	} {
  1637  		var x, y, z Float
  1638  		x.SetInt64(test.x)
  1639  		y.SetInt64(test.y)
  1640  		z.SetPrec(test.prec).SetMode(test.mode)
  1641  		switch test.op {
  1642  		case '+':
  1643  			z.Add(&x, &y)
  1644  		case '-':
  1645  			z.Sub(&x, &y)
  1646  		case '*':
  1647  			z.Mul(&x, &y)
  1648  		case '/':
  1649  			z.Quo(&x, &y)
  1650  		default:
  1651  			panic("unreachable")
  1652  		}
  1653  		if got, acc := z.Int64(); got != test.want || acc != Exact {
  1654  			t.Errorf("%s, %d bits: %d %c %d = %d (%s); want %d (Exact)",
  1655  				test.mode, test.prec, test.x, test.op, test.y, got, acc, test.want,
  1656  			)
  1657  		}
  1658  	}
  1659  }
  1660  
  1661  // TestFloatCmpSpecialValues tests that Cmp produces the correct results for
  1662  // combinations of zero (±0), finite (±1 and ±2.71828), and infinite (±Inf)
  1663  // operands.
  1664  func TestFloatCmpSpecialValues(t *testing.T) {
  1665  	zero := 0.0
  1666  	args := []float64{math.Inf(-1), -2.71828, -1, -zero, zero, 1, 2.71828, math.Inf(1)}
  1667  	xx := new(Float)
  1668  	yy := new(Float)
  1669  	for i := 0; i < 4; i++ {
  1670  		for _, x := range args {
  1671  			xx.SetFloat64(x)
  1672  			// check conversion is correct
  1673  			// (no need to do this for y, since we see exactly the
  1674  			// same values there)
  1675  			if got, acc := xx.Float64(); got != x || acc != Exact {
  1676  				t.Errorf("Float(%g) == %g (%s)", x, got, acc)
  1677  			}
  1678  			for _, y := range args {
  1679  				yy.SetFloat64(y)
  1680  				got := xx.Cmp(yy)
  1681  				want := 0
  1682  				switch {
  1683  				case x < y:
  1684  					want = -1
  1685  				case x > y:
  1686  					want = +1
  1687  				}
  1688  				if got != want {
  1689  					t.Errorf("(%g).Cmp(%g) = %v; want %v", x, y, got, want)
  1690  				}
  1691  			}
  1692  		}
  1693  	}
  1694  }