Answer fractional powers of exact numbers past a double's range (closes #16)
check / check (push) Successful in 1m21s
check / check (push) Successful in 1m21s
A fractional power turned its base into a double first and refused a base outside the normal range of a double, so (2^1200)^0.5, (2^1024)^0.5, (2^-1200)^0.5 and 1e400^0.5 were refused although each answer is an ordinary double. Such a base is now brought into that range by square roots taken from its exact value in a big.Float, at most three under the 4096-bit limit, with the exponent doubled for each, and only a result that is not a normal double is refused. The tests give these powers and the edges of the range their values, and the bounded-work test covers a base that needs three roots. The README's refusal sentence and example are updated. Model: opus-5-5
This commit is contained in:
@@ -130,6 +130,21 @@ func TestEvaluatePowers(t *testing.T) {
|
||||
// A power computed in float64 carries its rounding into the exact
|
||||
// arithmetic after it, past the range of a double as within it.
|
||||
"2^0.5 * 1e400": "1.4142135623730951e+400",
|
||||
// A fractional power of an exact number outside the range of a
|
||||
// double, taken from its exact value, up to the edges of that
|
||||
// range.
|
||||
"(2^1200)^0.5": "4.149515568880993e+180",
|
||||
"(2^1024)^0.5": "1.3407807929942597e+154",
|
||||
"(2^-1200)^0.5": "2.409919865102884e-181",
|
||||
"1e400^0.5": "1e+200",
|
||||
"1e-400^0.5": "1e-200",
|
||||
"1e-310^0.5": "1e-155",
|
||||
"(2^1200)^-0.5": "2.409919865102884e-181",
|
||||
"(2^1200)^0.5 / 2^600": "1",
|
||||
"1e400^-0.001": "0.39810717055349726",
|
||||
"1e-400^0.001": "0.39810717055349726",
|
||||
"(2^2047)^0.5": "1.2711610061536464e+308",
|
||||
"(2^-2044)^0.5": "2.2250738585072014e-308",
|
||||
})
|
||||
}
|
||||
|
||||
@@ -252,15 +267,17 @@ func TestEvaluateOutOfRange(t *testing.T) {
|
||||
"2^5000": calc.ErrOutOfRange,
|
||||
"(-2)^5001": calc.ErrOutOfRange,
|
||||
"0.5^-5000": calc.ErrOutOfRange,
|
||||
// Powers computed in float64 whose base or result is not a
|
||||
// normal double, and so has lost digits, or all of them.
|
||||
// Powers computed in float64 whose result is not a normal double,
|
||||
// and so has lost digits, or all of them, whatever the size of
|
||||
// the base.
|
||||
"2^-1073.5 * 2^1073": calc.ErrOutOfRange,
|
||||
"1e400^-0.001": calc.ErrOutOfRange,
|
||||
"1e-400^0.001": calc.ErrOutOfRange,
|
||||
"1e-310^0.5": calc.ErrOutOfRange,
|
||||
"2^1500.5": calc.ErrOutOfRange,
|
||||
"(2^1200)^0.9": calc.ErrOutOfRange,
|
||||
"1e-400^0.9": calc.ErrOutOfRange,
|
||||
"(2^2048)^0.5": calc.ErrOutOfRange,
|
||||
"(2^-2046)^0.5": calc.ErrOutOfRange,
|
||||
"(0.5^1100)^4 / (0.5^1100)^4": calc.ErrOutOfRange,
|
||||
"(1/3)^1e400": calc.ErrOutOfRange,
|
||||
"(2^1200)^0.5": calc.ErrOutOfRange,
|
||||
// go/constant holds numbers of this size rounded. A sum of them
|
||||
// can lose the answer (this one would be 0), and so can a
|
||||
// remainder or the sign of -1 to such a power.
|
||||
@@ -343,6 +360,10 @@ func TestEvaluateBoundsWork(t *testing.T) {
|
||||
{in: "3^2583", want: "2.5363018640659988e+1232"},
|
||||
{in: "2^-4094", want: "3.8299909843808741e-1233"},
|
||||
{in: "-1/3^2583", want: "-3.9427483540814775e-1233"},
|
||||
// Fractional powers of numbers just below the limit, whose bases
|
||||
// take the most square roots to bring into the range of a double.
|
||||
{in: "(2^-4094)^0.125", want: "8.869511863657883e-155"},
|
||||
{in: "(1/3^2583)^0.5", err: calc.ErrOutOfRange},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
|
||||
Reference in New Issue
Block a user