diff --git a/decimal.go b/decimal.go index 1473c2d..38f6ea7 100644 --- a/decimal.go +++ b/decimal.go @@ -5,8 +5,6 @@ package decimal import ( - "encoding" - "encoding/gob" "fmt" "math" "math/big" @@ -25,19 +23,6 @@ const debugDecimal = true // enable for debugging // the precision of IEEE-754 decimal128. const DefaultDecimalPrec = 34 -var decimalZero Decimal - -var ( - // required implemented interfaces - _ fmt.Stringer = &decimalZero - _ fmt.Scanner = &decimalZero - _ fmt.Formatter = &decimalZero - _ encoding.TextMarshaler = &decimalZero - _ encoding.TextUnmarshaler = &decimalZero - _ gob.GobEncoder = &decimalZero - _ gob.GobDecoder = &decimalZero -) - // A nonzero finite Decimal represents a multi-precision decimal floating point // number // @@ -1642,7 +1627,3 @@ func (z *Decimal) SetBitsExp(mant []Word, exp int64) *Decimal { } return z } - -func (x *Decimal) mantDigits() int64 { - return int64(len(x.mant)) * _DW -} diff --git a/decimal_test.go b/decimal_test.go index 7d22d8b..8e59c04 100644 --- a/decimal_test.go +++ b/decimal_test.go @@ -5,100 +5,15 @@ package decimal import ( - "math/big" + "encoding" + "encoding/gob" + "fmt" + "math" "math/rand" - "reflect" - "strconv" + "strings" "testing" ) -var benchU uint - -var intData = []struct { - s string - b int - p uint - d dec - pr uint - e int32 -}{ - {"00000000000000000001232", 10, 0, dec{1232000000000000000}, DefaultDecimalPrec, 4}, - {"1234567890123456789_0123456789012345678_9012345678901234567_8901234567890123456_78901234567890", 0, 90, - dec{7890123456789000000, 8901234567890123456, 9012345678901234567, 123456789012345678, 1234567890123456789}, - 90, 90}, - {"1235", 0, 0, dec{1235000000000000000}, DefaultDecimalPrec, 4}, - {"1235", 0, 3, dec{1240000000000000000}, 3, 4}, - {"1245", 0, 3, dec{1240000000000000000}, 3, 4}, - {"12451", 0, 3, dec{1250000000000000000}, 3, 5}, - {"0", 0, 0, nil, DefaultDecimalPrec, 0}, -} - -func TestDecimal_dnorm(t *testing.T) { - for i := 0; i < 10000; i++ { - again: - w := uint(rand.Uint64()) % _DB - e := uint(rand.Intn(_DW + 1)) - h, l := mulWW(Word(w), pow10(e)) - // convert h, l from base _B (2**64) to base _BD (10**19) or 2**32 -> 10**9 - h, l = div10W(h, l) - d := dec{Word(l), Word(h)}.norm() - if len(d) == 0 { - if w == 0 { - goto again - } - t.Fatalf("dec{%v, %v}).norm() returned dec{} for word %d", l, h, w) - } - dd := dec(nil).set(d) - s := dnorm(dd) - // d should now have a single element with e shifted left - ew := w * uint(pow10(_DW-decDigits(w))) - es := int64(uint(len(d)*_DW) - (decDigits(w) + e)) - if dd[len(dd)-1] != Word(ew) || s != es { - t.Fatalf("%ve%v => dnorm(%v) = %v, %v --- Expected %d, %d", - w, e, d, dd, s, w, es) - } - } -} - -func TestDecimal_SetInt(t *testing.T) { - for i, td := range intData { - t.Run(strconv.Itoa(i), func(t *testing.T) { - b, _ := new(big.Int).SetString(td.s, td.b) - d := new(Decimal).SetMode(ToNearestEven).SetPrec(td.p).SetInt(b) - ep := td.pr - if td.p == 0 && ep < DefaultDecimalPrec { - ep = DefaultDecimalPrec - } - if !reflect.DeepEqual(td.d, d.mant) { - t.Fatalf("\nexpected mantissa %v\n got %v", td.d, d.mant) - } - if ep != d.Prec() { - t.Fatalf("\nexpected precision %v\n got %v", ep, d.Prec()) - } - if td.e != d.exp { - t.Fatalf("\nexpected exponent %v\n got %v", td.p, d.Prec()) - } - }) - } -} - -func TestDecimal_SetString(t *testing.T) { - for i, td := range intData { - t.Run(strconv.Itoa(i), func(t *testing.T) { - d, _ := new(Decimal).SetMode(ToNearestEven).SetPrec(td.p).SetString(td.s) - if !reflect.DeepEqual(td.d, d.mant) { - t.Fatalf("\nexpected mantissa %v\n got %v", td.d, d.mant) - } - if td.pr != d.Prec() { - t.Fatalf("\nexpected precision %v\n got %v", td.pr, d.Prec()) - } - if td.e != d.exp { - t.Fatalf("\nexpected exponent %v\n got %v", td.p, d.Prec()) - } - }) - } -} - func BenchmarkDecimal_dnorm(b *testing.B) { d := dec(nil).make(1000) for i := range d { @@ -107,7 +22,7 @@ func BenchmarkDecimal_dnorm(b *testing.B) { for i := 0; i < b.N; i++ { d[0] = Word(rand.Uint64()) % _DB d[len(d)-1] = Word(rand.Uint64()) % _DB - benchU = uint(dnorm(d)) + _ = uint(dnorm(d)) } } func BenchmarkDecimal_Sqrt(b *testing.B) { @@ -146,3 +61,1861 @@ func TestDecimal_FMA(t *testing.T) { t.Fatalf("Aliasing z & u, %v * %v + 0.003 = %s, want 2.8", x, y, s) } } + +var decimalZero Decimal + +var ( + // required implemented interfaces + _ fmt.Stringer = &decimalZero + _ fmt.Scanner = &decimalZero + _ fmt.Formatter = &decimalZero + _ encoding.TextMarshaler = &decimalZero + _ encoding.TextUnmarshaler = &decimalZero + _ gob.GobEncoder = &decimalZero + _ gob.GobDecoder = &decimalZero +) + +// Verify that ErrNaN implements the error interface. +var _ error = ErrNaN{} + +func (x *Decimal) uint64() uint64 { + u, acc := x.Uint64() + if acc != Exact { + panic(fmt.Sprintf("%s is not a uint64", x.Text('g', 10))) + } + return u +} + +func (x *Decimal) int64() int64 { + i, acc := x.Int64() + if acc != Exact { + panic(fmt.Sprintf("%s is not an int64", x.Text('g', 10))) + } + return i +} + +func TestDecimalZeroValue(t *testing.T) { + // zero (uninitialized) value is a ready-to-use 0.0 + var x Decimal + if s := x.Text('f', 1); s != "0.0" { + t.Errorf("zero value = %s; want 0.0", s) + } + + // zero value has precision 0 + if prec := x.Prec(); prec != 0 { + t.Errorf("prec = %d; want 0", prec) + } + + // zero value can be used in any and all positions of binary operations + make := func(x int) *Decimal { + var f Decimal + if x != 0 { + f.SetInt64(int64(x)) + } + // x == 0 translates into the zero value + return &f + } + for _, test := range []struct { + z, x, y, want int + opname rune + op func(z, x, y *Decimal) *Decimal + }{ + {0, 0, 0, 0, '+', (*Decimal).Add}, + {0, 1, 2, 3, '+', (*Decimal).Add}, + {1, 2, 0, 2, '+', (*Decimal).Add}, + {2, 0, 1, 1, '+', (*Decimal).Add}, + + {0, 0, 0, 0, '-', (*Decimal).Sub}, + {0, 1, 2, -1, '-', (*Decimal).Sub}, + {1, 2, 0, 2, '-', (*Decimal).Sub}, + {2, 0, 1, -1, '-', (*Decimal).Sub}, + + {0, 0, 0, 0, '*', (*Decimal).Mul}, + {0, 1, 2, 2, '*', (*Decimal).Mul}, + {1, 2, 0, 0, '*', (*Decimal).Mul}, + {2, 0, 1, 0, '*', (*Decimal).Mul}, + + // {0, 0, 0, 0, '/', (*Decimal).Quo}, // panics + {0, 2, 1, 2, '/', (*Decimal).Quo}, + {1, 2, 0, 0, '/', (*Decimal).Quo}, // = +Inf + {2, 0, 1, 0, '/', (*Decimal).Quo}, + } { + z := make(test.z) + test.op(z, make(test.x), make(test.y)) + got := 0 + if !z.IsInf() { + got = int(z.int64()) + } + if got != test.want { + t.Errorf("%d %c %d = %d; want %d", test.x, test.opname, test.y, got, test.want) + } + } + + // TODO(db47h) test how precision is set for zero value results +} + +func makeDecimal(s string) *Decimal { + x, _, err := ParseDecimal(s, 0, 350, ToNearestEven) + if err != nil { + panic(err) + } + return x +} + +func TestDecimalSetPrec(t *testing.T) { + for _, test := range []struct { + x string + prec uint + want string + acc Accuracy + }{ + // prec 0 + {"0", 0, "0", Exact}, + {"-0", 0, "-0", Exact}, + {"-Inf", 0, "-Inf", Exact}, + {"+Inf", 0, "+Inf", Exact}, + {"123", 0, "0", Below}, + {"-123", 0, "-0", Above}, + + // prec at upper limit + {"0", MaxPrec, "0", Exact}, + {"-0", MaxPrec, "-0", Exact}, + {"-Inf", MaxPrec, "-Inf", Exact}, + {"+Inf", MaxPrec, "+Inf", Exact}, + + // just a few regular cases - general rounding is tested elsewhere + {"1.5", 1, "2", Above}, + {"-1.5", 1, "-2", Below}, + {"123", 1e6, "123", Exact}, + {"-123", 1e6, "-123", Exact}, + } { + x := makeDecimal(test.x).SetPrec(test.prec) + prec := test.prec + if prec > MaxPrec { + prec = MaxPrec + } + if got := x.Prec(); got != prec { + t.Errorf("%s.SetPrec(%d).Prec() == %d; want %d", test.x, test.prec, got, prec) + } + if got, acc := x.String(), x.Acc(); got != test.want || acc != test.acc { + t.Errorf("%s.SetPrec(%d) = %s (%s); want %s (%s)", test.x, test.prec, got, acc, test.want, test.acc) + } + } +} + +func TestDecimalMinPrec(t *testing.T) { + const max = 30 + for _, test := range []struct { + x string + want uint + }{ + {"0", 0}, + {"-0", 0}, + {"+Inf", 0}, + {"-Inf", 0}, + {"1", 1}, + {"9", 1}, + {"999", 3}, + {"123456", 6}, + {"123456e-1000", 6}, + {"123456e+1000", 6}, + // {"0.1", max}, + } { + x := makeDecimal(test.x).SetPrec(max) + if got := x.MinPrec(); got != test.want { + t.Errorf("%s.MinPrec() = %d; want %d", test.x, got, test.want) + } + } +} + +func TestDecimalSign(t *testing.T) { + for _, test := range []struct { + x string + s int + }{ + {"-Inf", -1}, + {"-1", -1}, + {"-0", 0}, + {"+0", 0}, + {"+1", +1}, + {"+Inf", +1}, + } { + x := makeDecimal(test.x) + s := x.Sign() + if s != test.s { + t.Errorf("%s.Sign() = %d; want %d", test.x, s, test.s) + } + } +} + +// alike(x, y) is like x.Cmp(y) == 0 but also considers the sign of 0 (0 != -0). +func alike(x, y *Decimal) bool { + return x.Cmp(y) == 0 && x.Signbit() == y.Signbit() +} + +func alike32(x, y float32) bool { + // we can ignore NaNs + return x == y && math.Signbit(float64(x)) == math.Signbit(float64(y)) + +} + +func alike64(x, y float64) bool { + // we can ignore NaNs + return x == y && math.Signbit(x) == math.Signbit(y) + +} + +func TestDecimalMantExp(t *testing.T) { + for _, test := range []struct { + x string + mant string + exp int + }{ + {"0", "0", 0}, + {"+0", "0", 0}, + {"-0", "-0", 0}, + {"Inf", "+Inf", 0}, + {"+Inf", "+Inf", 0}, + {"-Inf", "-Inf", 0}, + {"1.5", "0.15", 1}, + {"1.024e3", "0.1024", 4}, + {"-0.00125", "-0.125", -2}, + } { + x := makeDecimal(test.x) + mant := makeDecimal(test.mant) + m := new(Decimal) + e := x.MantExp(m) + if !alike(m, mant) || e != test.exp { + t.Errorf("%s.MantExp() = %s, %d; want %s, %d", test.x, m.Text('g', 10), e, test.mant, test.exp) + } + } +} + +func TestDecimalMantExpAliasing(t *testing.T) { + x := makeDecimal("0.5e10") + if e := x.MantExp(x); e != 10 { + t.Fatalf("Decimal.MantExp aliasing error: got %d; want 10", e) + } + if want := makeDecimal("0.5"); !alike(x, want) { + t.Fatalf("Decimal.MantExp aliasing error: got %s; want %s", x.Text('g', 10), want.Text('g', 10)) + } +} + +func TestDecimalSetMantExp(t *testing.T) { + for _, test := range []struct { + frac string + exp int + z string + }{ + {"0", 0, "0"}, + {"+0", 0, "0"}, + {"-0", 0, "-0"}, + {"Inf", 1234, "+Inf"}, + {"+Inf", -1234, "+Inf"}, + {"-Inf", -1234, "-Inf"}, + {"0", MinExp, "0"}, + {"0.01", MinExp, "+0"}, // exponent underflow + {"-0.01", MinExp, "-0"}, // exponent underflow + {"1", MaxExp, "+Inf"}, // exponent overflow + {"10", MaxExp - 1, "+Inf"}, // exponent overflow + {"1", MaxExp - 1, "1e2147483646"}, + {"0.75", 1, "7.5"}, + {"0.5", 4, "5000"}, + {"-0.5", -2, "-0.005"}, + {"32", 2, "3200"}, + {"1024", -5, "0.01024"}, + } { + frac := makeDecimal(test.frac) + want := makeDecimal(test.z) + var z Decimal + z.SetMantExp(frac, test.exp) + if !alike(&z, want) { + t.Errorf("SetMantExp(%s, %d) = %s; want %s", test.frac, test.exp, z.Text('g', 10), test.z) + } + // test inverse property + mant := new(Decimal) + if z.SetMantExp(mant, want.MantExp(mant)).Cmp(want) != 0 { + t.Errorf("Inverse property not satisfied: got %s; want %s", z.Text('g', 10), test.z) + } + } +} + +func TestDecimalPredicates(t *testing.T) { + for _, test := range []struct { + x string + sign int + signbit, inf bool + }{ + {x: "-Inf", sign: -1, signbit: true, inf: true}, + {x: "-1", sign: -1, signbit: true}, + {x: "-0", signbit: true}, + {x: "0"}, + {x: "1", sign: 1}, + {x: "+Inf", sign: 1, inf: true}, + } { + x := makeDecimal(test.x) + if got := x.Signbit(); got != test.signbit { + t.Errorf("(%s).Signbit() = %v; want %v", test.x, got, test.signbit) + } + if got := x.Sign(); got != test.sign { + t.Errorf("(%s).Sign() = %d; want %d", test.x, got, test.sign) + } + if got := x.IsInf(); got != test.inf { + t.Errorf("(%s).IsInf() = %v; want %v", test.x, got, test.inf) + } + } +} + +func TestDecimalIsInt(t *testing.T) { + for _, test := range []string{ + "0 int", + "-0 int", + "1 int", + "-1 int", + "0.5", + "1.23", + "1.23e1", + "1.23e2 int", + "0.000000001e+8", + "0.000000001e+9 int", + "1.2345e200 int", + "Inf", + "+Inf", + "-Inf", + } { + s := strings.TrimSuffix(test, " int") + want := s != test + if got := makeDecimal(s).IsInt(); got != want { + t.Errorf("%s.IsInt() == %t", s, got) + } + } +} + +// func fromBinary(s string) int64 { +// x, err := strconv.ParseInt(s, 2, 64) +// if err != nil { +// panic(err) +// } +// return x +// } + +// func toBinary(x int64) string { +// return strconv.FormatInt(x, 2) +// } + +// func testFloatRound(t *testing.T, x, r int64, prec uint, mode RoundingMode) { +// // verify test data +// var ok bool +// switch mode { +// case ToNearestEven, ToNearestAway: +// ok = true // nothing to do for now +// case ToZero: +// if x < 0 { +// ok = r >= x +// } else { +// ok = r <= x +// } +// case AwayFromZero: +// if x < 0 { +// ok = r <= x +// } else { +// ok = r >= x +// } +// case ToNegativeInf: +// ok = r <= x +// case ToPositiveInf: +// ok = r >= x +// default: +// panic("unreachable") +// } +// if !ok { +// t.Fatalf("incorrect test data for prec = %d, %s: x = %s, r = %s", prec, mode, toBinary(x), toBinary(r)) +// } + +// // compute expected accuracy +// a := Exact +// switch { +// case r < x: +// a = Below +// case r > x: +// a = Above +// } + +// // round +// f := new(Float).SetMode(mode).SetInt64(x).SetPrec(prec) + +// // check result +// r1 := f.int64() +// p1 := f.Prec() +// a1 := f.Acc() +// if r1 != r || p1 != prec || a1 != a { +// t.Errorf("round %s (%d bits, %s) incorrect: got %s (%d bits, %s); want %s (%d bits, %s)", +// toBinary(x), prec, mode, +// toBinary(r1), p1, a1, +// toBinary(r), prec, a) +// return +// } + +// // g and f should be the same +// // (rounding by SetPrec after SetInt64 using default precision +// // should be the same as rounding by SetInt64 after setting the +// // precision) +// g := new(Float).SetMode(mode).SetPrec(prec).SetInt64(x) +// if !alike(g, f) { +// t.Errorf("round %s (%d bits, %s) not symmetric: got %s and %s; want %s", +// toBinary(x), prec, mode, +// toBinary(g.int64()), +// toBinary(r1), +// toBinary(r), +// ) +// return +// } + +// // h and f should be the same +// // (repeated rounding should be idempotent) +// h := new(Float).SetMode(mode).SetPrec(prec).Set(f) +// if !alike(h, f) { +// t.Errorf("round %s (%d bits, %s) not idempotent: got %s and %s; want %s", +// toBinary(x), prec, mode, +// toBinary(h.int64()), +// toBinary(r1), +// toBinary(r), +// ) +// return +// } +// } + +// // TestFloatRound tests basic rounding. +// func TestFloatRound(t *testing.T) { +// for _, test := range []struct { +// prec uint +// x, zero, neven, naway, away string // input, results rounded to prec bits +// }{ +// {5, "1000", "1000", "1000", "1000", "1000"}, +// {5, "1001", "1001", "1001", "1001", "1001"}, +// {5, "1010", "1010", "1010", "1010", "1010"}, +// {5, "1011", "1011", "1011", "1011", "1011"}, +// {5, "1100", "1100", "1100", "1100", "1100"}, +// {5, "1101", "1101", "1101", "1101", "1101"}, +// {5, "1110", "1110", "1110", "1110", "1110"}, +// {5, "1111", "1111", "1111", "1111", "1111"}, + +// {4, "1000", "1000", "1000", "1000", "1000"}, +// {4, "1001", "1001", "1001", "1001", "1001"}, +// {4, "1010", "1010", "1010", "1010", "1010"}, +// {4, "1011", "1011", "1011", "1011", "1011"}, +// {4, "1100", "1100", "1100", "1100", "1100"}, +// {4, "1101", "1101", "1101", "1101", "1101"}, +// {4, "1110", "1110", "1110", "1110", "1110"}, +// {4, "1111", "1111", "1111", "1111", "1111"}, + +// {3, "1000", "1000", "1000", "1000", "1000"}, +// {3, "1001", "1000", "1000", "1010", "1010"}, +// {3, "1010", "1010", "1010", "1010", "1010"}, +// {3, "1011", "1010", "1100", "1100", "1100"}, +// {3, "1100", "1100", "1100", "1100", "1100"}, +// {3, "1101", "1100", "1100", "1110", "1110"}, +// {3, "1110", "1110", "1110", "1110", "1110"}, +// {3, "1111", "1110", "10000", "10000", "10000"}, + +// {3, "1000001", "1000000", "1000000", "1000000", "1010000"}, +// {3, "1001001", "1000000", "1010000", "1010000", "1010000"}, +// {3, "1010001", "1010000", "1010000", "1010000", "1100000"}, +// {3, "1011001", "1010000", "1100000", "1100000", "1100000"}, +// {3, "1100001", "1100000", "1100000", "1100000", "1110000"}, +// {3, "1101001", "1100000", "1110000", "1110000", "1110000"}, +// {3, "1110001", "1110000", "1110000", "1110000", "10000000"}, +// {3, "1111001", "1110000", "10000000", "10000000", "10000000"}, + +// {2, "1000", "1000", "1000", "1000", "1000"}, +// {2, "1001", "1000", "1000", "1000", "1100"}, +// {2, "1010", "1000", "1000", "1100", "1100"}, +// {2, "1011", "1000", "1100", "1100", "1100"}, +// {2, "1100", "1100", "1100", "1100", "1100"}, +// {2, "1101", "1100", "1100", "1100", "10000"}, +// {2, "1110", "1100", "10000", "10000", "10000"}, +// {2, "1111", "1100", "10000", "10000", "10000"}, + +// {2, "1000001", "1000000", "1000000", "1000000", "1100000"}, +// {2, "1001001", "1000000", "1000000", "1000000", "1100000"}, +// {2, "1010001", "1000000", "1100000", "1100000", "1100000"}, +// {2, "1011001", "1000000", "1100000", "1100000", "1100000"}, +// {2, "1100001", "1100000", "1100000", "1100000", "10000000"}, +// {2, "1101001", "1100000", "1100000", "1100000", "10000000"}, +// {2, "1110001", "1100000", "10000000", "10000000", "10000000"}, +// {2, "1111001", "1100000", "10000000", "10000000", "10000000"}, + +// {1, "1000", "1000", "1000", "1000", "1000"}, +// {1, "1001", "1000", "1000", "1000", "10000"}, +// {1, "1010", "1000", "1000", "1000", "10000"}, +// {1, "1011", "1000", "1000", "1000", "10000"}, +// {1, "1100", "1000", "10000", "10000", "10000"}, +// {1, "1101", "1000", "10000", "10000", "10000"}, +// {1, "1110", "1000", "10000", "10000", "10000"}, +// {1, "1111", "1000", "10000", "10000", "10000"}, + +// {1, "1000001", "1000000", "1000000", "1000000", "10000000"}, +// {1, "1001001", "1000000", "1000000", "1000000", "10000000"}, +// {1, "1010001", "1000000", "1000000", "1000000", "10000000"}, +// {1, "1011001", "1000000", "1000000", "1000000", "10000000"}, +// {1, "1100001", "1000000", "10000000", "10000000", "10000000"}, +// {1, "1101001", "1000000", "10000000", "10000000", "10000000"}, +// {1, "1110001", "1000000", "10000000", "10000000", "10000000"}, +// {1, "1111001", "1000000", "10000000", "10000000", "10000000"}, +// } { +// x := fromBinary(test.x) +// z := fromBinary(test.zero) +// e := fromBinary(test.neven) +// n := fromBinary(test.naway) +// a := fromBinary(test.away) +// prec := test.prec + +// testFloatRound(t, x, z, prec, ToZero) +// testFloatRound(t, x, e, prec, ToNearestEven) +// testFloatRound(t, x, n, prec, ToNearestAway) +// testFloatRound(t, x, a, prec, AwayFromZero) + +// testFloatRound(t, x, z, prec, ToNegativeInf) +// testFloatRound(t, x, a, prec, ToPositiveInf) + +// testFloatRound(t, -x, -a, prec, ToNegativeInf) +// testFloatRound(t, -x, -z, prec, ToPositiveInf) +// } +// } + +// // TestFloatRound24 tests that rounding a float64 to 24 bits +// // matches IEEE-754 rounding to nearest when converting a +// // float64 to a float32 (excluding denormal numbers). +// func TestFloatRound24(t *testing.T) { +// const x0 = 1<<26 - 0x10 // 11...110000 (26 bits) +// for d := 0; d <= 0x10; d++ { +// x := float64(x0 + d) +// f := new(Float).SetPrec(24).SetFloat64(x) +// got, _ := f.Float32() +// want := float32(x) +// if got != want { +// t.Errorf("Round(%g, 24) = %g; want %g", x, got, want) +// } +// } +// } + +// func TestFloatSetUint64(t *testing.T) { +// for _, want := range []uint64{ +// 0, +// 1, +// 2, +// 10, +// 100, +// 1<<32 - 1, +// 1 << 32, +// 1<<64 - 1, +// } { +// var f Float +// f.SetUint64(want) +// if got := f.uint64(); got != want { +// t.Errorf("got %#x (%s); want %#x", got, f.Text('p', 0), want) +// } +// } + +// // test basic rounding behavior (exhaustive rounding testing is done elsewhere) +// const x uint64 = 0x8765432187654321 // 64 bits needed +// for prec := uint(1); prec <= 64; prec++ { +// f := new(Float).SetPrec(prec).SetMode(ToZero).SetUint64(x) +// got := f.uint64() +// want := x &^ (1<<(64-prec) - 1) // cut off (round to zero) low 64-prec bits +// if got != want { +// t.Errorf("got %#x (%s); want %#x", got, f.Text('p', 0), want) +// } +// } +// } + +// func TestFloatSetInt64(t *testing.T) { +// for _, want := range []int64{ +// 0, +// 1, +// 2, +// 10, +// 100, +// 1<<32 - 1, +// 1 << 32, +// 1<<63 - 1, +// } { +// for i := range [2]int{} { +// if i&1 != 0 { +// want = -want +// } +// var f Float +// f.SetInt64(want) +// if got := f.int64(); got != want { +// t.Errorf("got %#x (%s); want %#x", got, f.Text('p', 0), want) +// } +// } +// } + +// // test basic rounding behavior (exhaustive rounding testing is done elsewhere) +// const x int64 = 0x7654321076543210 // 63 bits needed +// for prec := uint(1); prec <= 63; prec++ { +// f := new(Float).SetPrec(prec).SetMode(ToZero).SetInt64(x) +// got := f.int64() +// want := x &^ (1<<(63-prec) - 1) // cut off (round to zero) low 63-prec bits +// if got != want { +// t.Errorf("got %#x (%s); want %#x", got, f.Text('p', 0), want) +// } +// } +// } + +// func TestFloatSetFloat64(t *testing.T) { +// for _, want := range []float64{ +// 0, +// 1, +// 2, +// 12345, +// 1e10, +// 1e100, +// 3.14159265e10, +// 2.718281828e-123, +// 1.0 / 3, +// math.MaxFloat32, +// math.MaxFloat64, +// math.SmallestNonzeroFloat32, +// math.SmallestNonzeroFloat64, +// math.Inf(-1), +// math.Inf(0), +// -math.Inf(1), +// } { +// for i := range [2]int{} { +// if i&1 != 0 { +// want = -want +// } +// var f Float +// f.SetFloat64(want) +// if got, acc := f.Float64(); got != want || acc != Exact { +// t.Errorf("got %g (%s, %s); want %g (Exact)", got, f.Text('p', 0), acc, want) +// } +// } +// } + +// // test basic rounding behavior (exhaustive rounding testing is done elsewhere) +// const x uint64 = 0x8765432143218 // 53 bits needed +// for prec := uint(1); prec <= 52; prec++ { +// f := new(Float).SetPrec(prec).SetMode(ToZero).SetFloat64(float64(x)) +// got, _ := f.Float64() +// want := float64(x &^ (1<<(52-prec) - 1)) // cut off (round to zero) low 53-prec bits +// if got != want { +// t.Errorf("got %g (%s); want %g", got, f.Text('p', 0), want) +// } +// } + +// // test NaN +// defer func() { +// if p, ok := recover().(ErrNaN); !ok { +// t.Errorf("got %v; want ErrNaN panic", p) +// } +// }() +// var f Float +// f.SetFloat64(math.NaN()) +// // should not reach here +// t.Errorf("got %s; want ErrNaN panic", f.Text('p', 0)) +// } + +// func TestFloatSetInt(t *testing.T) { +// for _, want := range []string{ +// "0", +// "1", +// "-1", +// "1234567890", +// "123456789012345678901234567890", +// "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", +// } { +// var x Int +// _, ok := x.SetString(want, 0) +// if !ok { +// t.Errorf("invalid integer %s", want) +// continue +// } +// n := x.BitLen() + +// var f Float +// f.SetInt(&x) + +// // check precision +// if n < 64 { +// n = 64 +// } +// if prec := f.Prec(); prec != uint(n) { +// t.Errorf("got prec = %d; want %d", prec, n) +// } + +// // check value +// got := f.Text('g', 100) +// if got != want { +// t.Errorf("got %s (%s); want %s", got, f.Text('p', 0), want) +// } +// } + +// // TODO(gri) test basic rounding behavior +// } + +// func TestFloatSetRat(t *testing.T) { +// for _, want := range []string{ +// "0", +// "1", +// "-1", +// "1234567890", +// "123456789012345678901234567890", +// "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", +// "1.2", +// "3.14159265", +// // TODO(gri) expand +// } { +// var x Rat +// _, ok := x.SetString(want) +// if !ok { +// t.Errorf("invalid fraction %s", want) +// continue +// } +// n := max(x.Num().BitLen(), x.Denom().BitLen()) + +// var f1, f2 Float +// f2.SetPrec(1000) +// f1.SetRat(&x) +// f2.SetRat(&x) + +// // check precision when set automatically +// if n < 64 { +// n = 64 +// } +// if prec := f1.Prec(); prec != uint(n) { +// t.Errorf("got prec = %d; want %d", prec, n) +// } + +// got := f2.Text('g', 100) +// if got != want { +// t.Errorf("got %s (%s); want %s", got, f2.Text('p', 0), want) +// } +// } +// } + +// func TestFloatSetInf(t *testing.T) { +// var f Float +// for _, test := range []struct { +// signbit bool +// prec uint +// want string +// }{ +// {false, 0, "+Inf"}, +// {true, 0, "-Inf"}, +// {false, 10, "+Inf"}, +// {true, 30, "-Inf"}, +// } { +// x := f.SetPrec(test.prec).SetInf(test.signbit) +// if got := x.String(); got != test.want || x.Prec() != test.prec { +// t.Errorf("SetInf(%v) = %s (prec = %d); want %s (prec = %d)", test.signbit, got, x.Prec(), test.want, test.prec) +// } +// } +// } + +// func TestFloatUint64(t *testing.T) { +// for _, test := range []struct { +// x string +// out uint64 +// acc Accuracy +// }{ +// {"-Inf", 0, Above}, +// {"-1", 0, Above}, +// {"-1e-1000", 0, Above}, +// {"-0", 0, Exact}, +// {"0", 0, Exact}, +// {"1e-1000", 0, Below}, +// {"1", 1, Exact}, +// {"1.000000000000000000001", 1, Below}, +// {"12345.0", 12345, Exact}, +// {"12345.000000000000000000001", 12345, Below}, +// {"18446744073709551615", 18446744073709551615, Exact}, +// {"18446744073709551615.000000000000000000001", math.MaxUint64, Below}, +// {"18446744073709551616", math.MaxUint64, Below}, +// {"1e10000", math.MaxUint64, Below}, +// {"+Inf", math.MaxUint64, Below}, +// } { +// x := makeFloat(test.x) +// out, acc := x.Uint64() +// if out != test.out || acc != test.acc { +// t.Errorf("%s: got %d (%s); want %d (%s)", test.x, out, acc, test.out, test.acc) +// } +// } +// } + +// func TestFloatInt64(t *testing.T) { +// for _, test := range []struct { +// x string +// out int64 +// acc Accuracy +// }{ +// {"-Inf", math.MinInt64, Above}, +// {"-1e10000", math.MinInt64, Above}, +// {"-9223372036854775809", math.MinInt64, Above}, +// {"-9223372036854775808.000000000000000000001", math.MinInt64, Above}, +// {"-9223372036854775808", -9223372036854775808, Exact}, +// {"-9223372036854775807.000000000000000000001", -9223372036854775807, Above}, +// {"-9223372036854775807", -9223372036854775807, Exact}, +// {"-12345.000000000000000000001", -12345, Above}, +// {"-12345.0", -12345, Exact}, +// {"-1.000000000000000000001", -1, Above}, +// {"-1.5", -1, Above}, +// {"-1", -1, Exact}, +// {"-1e-1000", 0, Above}, +// {"0", 0, Exact}, +// {"1e-1000", 0, Below}, +// {"1", 1, Exact}, +// {"1.000000000000000000001", 1, Below}, +// {"1.5", 1, Below}, +// {"12345.0", 12345, Exact}, +// {"12345.000000000000000000001", 12345, Below}, +// {"9223372036854775807", 9223372036854775807, Exact}, +// {"9223372036854775807.000000000000000000001", math.MaxInt64, Below}, +// {"9223372036854775808", math.MaxInt64, Below}, +// {"1e10000", math.MaxInt64, Below}, +// {"+Inf", math.MaxInt64, Below}, +// } { +// x := makeFloat(test.x) +// out, acc := x.Int64() +// if out != test.out || acc != test.acc { +// t.Errorf("%s: got %d (%s); want %d (%s)", test.x, out, acc, test.out, test.acc) +// } +// } +// } + +// func TestFloatFloat32(t *testing.T) { +// for _, test := range []struct { +// x string +// out float32 +// acc Accuracy +// }{ +// {"0", 0, Exact}, + +// // underflow to zero +// {"1e-1000", 0, Below}, +// {"0x0.000002p-127", 0, Below}, +// {"0x.0000010p-126", 0, Below}, + +// // denormals +// {"1.401298464e-45", math.SmallestNonzeroFloat32, Above}, // rounded up to smallest denormal +// {"0x.ffffff8p-149", math.SmallestNonzeroFloat32, Above}, // rounded up to smallest denormal +// {"0x.0000018p-126", math.SmallestNonzeroFloat32, Above}, // rounded up to smallest denormal +// {"0x.0000020p-126", math.SmallestNonzeroFloat32, Exact}, +// {"0x.8p-148", math.SmallestNonzeroFloat32, Exact}, +// {"1p-149", math.SmallestNonzeroFloat32, Exact}, +// {"0x.fffffep-126", math.Float32frombits(0x7fffff), Exact}, // largest denormal + +// // special denormal cases (see issues 14553, 14651) +// {"0x0.0000001p-126", math.Float32frombits(0x00000000), Below}, // underflow to zero +// {"0x0.0000008p-126", math.Float32frombits(0x00000000), Below}, // underflow to zero +// {"0x0.0000010p-126", math.Float32frombits(0x00000000), Below}, // rounded down to even +// {"0x0.0000011p-126", math.Float32frombits(0x00000001), Above}, // rounded up to smallest denormal +// {"0x0.0000018p-126", math.Float32frombits(0x00000001), Above}, // rounded up to smallest denormal + +// {"0x1.0000000p-149", math.Float32frombits(0x00000001), Exact}, // smallest denormal +// {"0x0.0000020p-126", math.Float32frombits(0x00000001), Exact}, // smallest denormal +// {"0x0.fffffe0p-126", math.Float32frombits(0x007fffff), Exact}, // largest denormal +// {"0x1.0000000p-126", math.Float32frombits(0x00800000), Exact}, // smallest normal + +// {"0x0.8p-149", math.Float32frombits(0x000000000), Below}, // rounded down to even +// {"0x0.9p-149", math.Float32frombits(0x000000001), Above}, // rounded up to smallest denormal +// {"0x0.ap-149", math.Float32frombits(0x000000001), Above}, // rounded up to smallest denormal +// {"0x0.bp-149", math.Float32frombits(0x000000001), Above}, // rounded up to smallest denormal +// {"0x0.cp-149", math.Float32frombits(0x000000001), Above}, // rounded up to smallest denormal + +// {"0x1.0p-149", math.Float32frombits(0x000000001), Exact}, // smallest denormal +// {"0x1.7p-149", math.Float32frombits(0x000000001), Below}, +// {"0x1.8p-149", math.Float32frombits(0x000000002), Above}, +// {"0x1.9p-149", math.Float32frombits(0x000000002), Above}, + +// {"0x2.0p-149", math.Float32frombits(0x000000002), Exact}, +// {"0x2.8p-149", math.Float32frombits(0x000000002), Below}, // rounded down to even +// {"0x2.9p-149", math.Float32frombits(0x000000003), Above}, + +// {"0x3.0p-149", math.Float32frombits(0x000000003), Exact}, +// {"0x3.7p-149", math.Float32frombits(0x000000003), Below}, +// {"0x3.8p-149", math.Float32frombits(0x000000004), Above}, // rounded up to even + +// {"0x4.0p-149", math.Float32frombits(0x000000004), Exact}, +// {"0x4.8p-149", math.Float32frombits(0x000000004), Below}, // rounded down to even +// {"0x4.9p-149", math.Float32frombits(0x000000005), Above}, + +// // specific case from issue 14553 +// {"0x7.7p-149", math.Float32frombits(0x000000007), Below}, +// {"0x7.8p-149", math.Float32frombits(0x000000008), Above}, +// {"0x7.9p-149", math.Float32frombits(0x000000008), Above}, + +// // normals +// {"0x.ffffffp-126", math.Float32frombits(0x00800000), Above}, // rounded up to smallest normal +// {"1p-126", math.Float32frombits(0x00800000), Exact}, // smallest normal +// {"0x1.fffffep-126", math.Float32frombits(0x00ffffff), Exact}, +// {"0x1.ffffffp-126", math.Float32frombits(0x01000000), Above}, // rounded up +// {"1", 1, Exact}, +// {"1.000000000000000000001", 1, Below}, +// {"12345.0", 12345, Exact}, +// {"12345.000000000000000000001", 12345, Below}, +// {"0x1.fffffe0p127", math.MaxFloat32, Exact}, +// {"0x1.fffffe8p127", math.MaxFloat32, Below}, + +// // overflow +// {"0x1.ffffff0p127", float32(math.Inf(+1)), Above}, +// {"0x1p128", float32(math.Inf(+1)), Above}, +// {"1e10000", float32(math.Inf(+1)), Above}, +// {"0x1.ffffff0p2147483646", float32(math.Inf(+1)), Above}, // overflow in rounding + +// // inf +// {"Inf", float32(math.Inf(+1)), Exact}, +// } { +// for i := 0; i < 2; i++ { +// // test both signs +// tx, tout, tacc := test.x, test.out, test.acc +// if i != 0 { +// tx = "-" + tx +// tout = -tout +// tacc = -tacc +// } + +// // conversion should match strconv where syntax is agreeable +// if f, err := strconv.ParseFloat(tx, 32); err == nil && !alike32(float32(f), tout) { +// t.Errorf("%s: got %g; want %g (incorrect test data)", tx, f, tout) +// } + +// x := makeFloat(tx) +// out, acc := x.Float32() +// if !alike32(out, tout) || acc != tacc { +// t.Errorf("%s: got %g (%#08x, %s); want %g (%#08x, %s)", tx, out, math.Float32bits(out), acc, test.out, math.Float32bits(test.out), tacc) +// } + +// // test that x.SetFloat64(float64(f)).Float32() == f +// var x2 Float +// out2, acc2 := x2.SetFloat64(float64(out)).Float32() +// if !alike32(out2, out) || acc2 != Exact { +// t.Errorf("idempotency test: got %g (%s); want %g (Exact)", out2, acc2, out) +// } +// } +// } +// } + +// func TestFloatFloat64(t *testing.T) { +// const smallestNormalFloat64 = 2.2250738585072014e-308 // 1p-1022 +// for _, test := range []struct { +// x string +// out float64 +// acc Accuracy +// }{ +// {"0", 0, Exact}, + +// // underflow to zero +// {"1e-1000", 0, Below}, +// {"0x0.0000000000001p-1023", 0, Below}, +// {"0x0.00000000000008p-1022", 0, Below}, + +// // denormals +// {"0x0.0000000000000cp-1022", math.SmallestNonzeroFloat64, Above}, // rounded up to smallest denormal +// {"0x0.00000000000010p-1022", math.SmallestNonzeroFloat64, Exact}, // smallest denormal +// {"0x.8p-1073", math.SmallestNonzeroFloat64, Exact}, +// {"1p-1074", math.SmallestNonzeroFloat64, Exact}, +// {"0x.fffffffffffffp-1022", math.Float64frombits(0x000fffffffffffff), Exact}, // largest denormal + +// // special denormal cases (see issues 14553, 14651) +// {"0x0.00000000000001p-1022", math.Float64frombits(0x00000000000000000), Below}, // underflow to zero +// {"0x0.00000000000004p-1022", math.Float64frombits(0x00000000000000000), Below}, // underflow to zero +// {"0x0.00000000000008p-1022", math.Float64frombits(0x00000000000000000), Below}, // rounded down to even +// {"0x0.00000000000009p-1022", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal +// {"0x0.0000000000000ap-1022", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal + +// {"0x0.8p-1074", math.Float64frombits(0x00000000000000000), Below}, // rounded down to even +// {"0x0.9p-1074", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal +// {"0x0.ap-1074", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal +// {"0x0.bp-1074", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal +// {"0x0.cp-1074", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal + +// {"0x1.0p-1074", math.Float64frombits(0x00000000000000001), Exact}, +// {"0x1.7p-1074", math.Float64frombits(0x00000000000000001), Below}, +// {"0x1.8p-1074", math.Float64frombits(0x00000000000000002), Above}, +// {"0x1.9p-1074", math.Float64frombits(0x00000000000000002), Above}, + +// {"0x2.0p-1074", math.Float64frombits(0x00000000000000002), Exact}, +// {"0x2.8p-1074", math.Float64frombits(0x00000000000000002), Below}, // rounded down to even +// {"0x2.9p-1074", math.Float64frombits(0x00000000000000003), Above}, + +// {"0x3.0p-1074", math.Float64frombits(0x00000000000000003), Exact}, +// {"0x3.7p-1074", math.Float64frombits(0x00000000000000003), Below}, +// {"0x3.8p-1074", math.Float64frombits(0x00000000000000004), Above}, // rounded up to even + +// {"0x4.0p-1074", math.Float64frombits(0x00000000000000004), Exact}, +// {"0x4.8p-1074", math.Float64frombits(0x00000000000000004), Below}, // rounded down to even +// {"0x4.9p-1074", math.Float64frombits(0x00000000000000005), Above}, + +// // normals +// {"0x.fffffffffffff8p-1022", math.Float64frombits(0x0010000000000000), Above}, // rounded up to smallest normal +// {"1p-1022", math.Float64frombits(0x0010000000000000), Exact}, // smallest normal +// {"1", 1, Exact}, +// {"1.000000000000000000001", 1, Below}, +// {"12345.0", 12345, Exact}, +// {"12345.000000000000000000001", 12345, Below}, +// {"0x1.fffffffffffff0p1023", math.MaxFloat64, Exact}, +// {"0x1.fffffffffffff4p1023", math.MaxFloat64, Below}, + +// // overflow +// {"0x1.fffffffffffff8p1023", math.Inf(+1), Above}, +// {"0x1p1024", math.Inf(+1), Above}, +// {"1e10000", math.Inf(+1), Above}, +// {"0x1.fffffffffffff8p2147483646", math.Inf(+1), Above}, // overflow in rounding +// {"Inf", math.Inf(+1), Exact}, + +// // selected denormalized values that were handled incorrectly in the past +// {"0x.fffffffffffffp-1022", smallestNormalFloat64 - math.SmallestNonzeroFloat64, Exact}, +// {"4503599627370495p-1074", smallestNormalFloat64 - math.SmallestNonzeroFloat64, Exact}, + +// // https://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/ +// {"2.2250738585072011e-308", 2.225073858507201e-308, Below}, +// // https://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/ +// {"2.2250738585072012e-308", 2.2250738585072014e-308, Above}, +// } { +// for i := 0; i < 2; i++ { +// // test both signs +// tx, tout, tacc := test.x, test.out, test.acc +// if i != 0 { +// tx = "-" + tx +// tout = -tout +// tacc = -tacc +// } + +// // conversion should match strconv where syntax is agreeable +// if f, err := strconv.ParseFloat(tx, 64); err == nil && !alike64(f, tout) { +// t.Errorf("%s: got %g; want %g (incorrect test data)", tx, f, tout) +// } + +// x := makeFloat(tx) +// out, acc := x.Float64() +// if !alike64(out, tout) || acc != tacc { +// t.Errorf("%s: got %g (%#016x, %s); want %g (%#016x, %s)", tx, out, math.Float64bits(out), acc, test.out, math.Float64bits(test.out), tacc) +// } + +// // test that x.SetFloat64(f).Float64() == f +// var x2 Float +// out2, acc2 := x2.SetFloat64(out).Float64() +// if !alike64(out2, out) || acc2 != Exact { +// t.Errorf("idempotency test: got %g (%s); want %g (Exact)", out2, acc2, out) +// } +// } +// } +// } + +// func TestFloatInt(t *testing.T) { +// for _, test := range []struct { +// x string +// want string +// acc Accuracy +// }{ +// {"0", "0", Exact}, +// {"+0", "0", Exact}, +// {"-0", "0", Exact}, +// {"Inf", "nil", Below}, +// {"+Inf", "nil", Below}, +// {"-Inf", "nil", Above}, +// {"1", "1", Exact}, +// {"-1", "-1", Exact}, +// {"1.23", "1", Below}, +// {"-1.23", "-1", Above}, +// {"123e-2", "1", Below}, +// {"123e-3", "0", Below}, +// {"123e-4", "0", Below}, +// {"1e-1000", "0", Below}, +// {"-1e-1000", "0", Above}, +// {"1e+10", "10000000000", Exact}, +// {"1e+100", "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", Exact}, +// } { +// x := makeFloat(test.x) +// res, acc := x.Int(nil) +// got := "nil" +// if res != nil { +// got = res.String() +// } +// if got != test.want || acc != test.acc { +// t.Errorf("%s: got %s (%s); want %s (%s)", test.x, got, acc, test.want, test.acc) +// } +// } + +// // check that supplied *Int is used +// for _, f := range []string{"0", "1", "-1", "1234"} { +// x := makeFloat(f) +// i := new(Int) +// if res, _ := x.Int(i); res != i { +// t.Errorf("(%s).Int is not using supplied *Int", f) +// } +// } +// } + +// func TestFloatRat(t *testing.T) { +// for _, test := range []struct { +// x, want string +// acc Accuracy +// }{ +// {"0", "0/1", Exact}, +// {"+0", "0/1", Exact}, +// {"-0", "0/1", Exact}, +// {"Inf", "nil", Below}, +// {"+Inf", "nil", Below}, +// {"-Inf", "nil", Above}, +// {"1", "1/1", Exact}, +// {"-1", "-1/1", Exact}, +// {"1.25", "5/4", Exact}, +// {"-1.25", "-5/4", Exact}, +// {"1e10", "10000000000/1", Exact}, +// {"1p10", "1024/1", Exact}, +// {"-1p-10", "-1/1024", Exact}, +// {"3.14159265", "7244019449799623199/2305843009213693952", Exact}, +// } { +// x := makeFloat(test.x).SetPrec(64) +// res, acc := x.Rat(nil) +// got := "nil" +// if res != nil { +// got = res.String() +// } +// if got != test.want { +// t.Errorf("%s: got %s; want %s", test.x, got, test.want) +// continue +// } +// if acc != test.acc { +// t.Errorf("%s: got %s; want %s", test.x, acc, test.acc) +// continue +// } + +// // inverse conversion +// if res != nil { +// got := new(Float).SetPrec(64).SetRat(res) +// if got.Cmp(x) != 0 { +// t.Errorf("%s: got %s; want %s", test.x, got, x) +// } +// } +// } + +// // check that supplied *Rat is used +// for _, f := range []string{"0", "1", "-1", "1234"} { +// x := makeFloat(f) +// r := new(Rat) +// if res, _ := x.Rat(r); res != r { +// t.Errorf("(%s).Rat is not using supplied *Rat", f) +// } +// } +// } + +// func TestFloatAbs(t *testing.T) { +// for _, test := range []string{ +// "0", +// "1", +// "1234", +// "1.23e-2", +// "1e-1000", +// "1e1000", +// "Inf", +// } { +// p := makeFloat(test) +// a := new(Float).Abs(p) +// if !alike(a, p) { +// t.Errorf("%s: got %s; want %s", test, a.Text('g', 10), test) +// } + +// n := makeFloat("-" + test) +// a.Abs(n) +// if !alike(a, p) { +// t.Errorf("-%s: got %s; want %s", test, a.Text('g', 10), test) +// } +// } +// } + +// func TestFloatNeg(t *testing.T) { +// for _, test := range []string{ +// "0", +// "1", +// "1234", +// "1.23e-2", +// "1e-1000", +// "1e1000", +// "Inf", +// } { +// p1 := makeFloat(test) +// n1 := makeFloat("-" + test) +// n2 := new(Float).Neg(p1) +// p2 := new(Float).Neg(n2) +// if !alike(n2, n1) { +// t.Errorf("%s: got %s; want %s", test, n2.Text('g', 10), n1.Text('g', 10)) +// } +// if !alike(p2, p1) { +// t.Errorf("%s: got %s; want %s", test, p2.Text('g', 10), p1.Text('g', 10)) +// } +// } +// } + +// func TestFloatInc(t *testing.T) { +// const n = 10 +// for _, prec := range precList { +// if 1< y: +// want = +1 +// } +// if got != want { +// t.Errorf("(%g).Cmp(%g) = %v; want %v", x, y, got, want) +// } +// } +// } +// } +// } + +// func BenchmarkFloatAdd(b *testing.B) { +// x := new(Float) +// y := new(Float) +// z := new(Float) + +// for _, prec := range []uint{10, 1e2, 1e3, 1e4, 1e5} { +// x.SetPrec(prec).SetRat(NewRat(1, 3)) +// y.SetPrec(prec).SetRat(NewRat(1, 6)) +// z.SetPrec(prec) + +// b.Run(fmt.Sprintf("%v", prec), func(b *testing.B) { +// b.ReportAllocs() +// for i := 0; i < b.N; i++ { +// z.Add(x, y) +// } +// }) +// } +// } + +// func BenchmarkFloatSub(b *testing.B) { +// x := new(Float) +// y := new(Float) +// z := new(Float) + +// for _, prec := range []uint{10, 1e2, 1e3, 1e4, 1e5} { +// x.SetPrec(prec).SetRat(NewRat(1, 3)) +// y.SetPrec(prec).SetRat(NewRat(1, 6)) +// z.SetPrec(prec) + +// b.Run(fmt.Sprintf("%v", prec), func(b *testing.B) { +// b.ReportAllocs() +// for i := 0; i < b.N; i++ { +// z.Sub(x, y) +// } +// }) +// } +// }