...

Source file src/math/big/float_test.go

Documentation: math/big

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

View as plain text