add precomputed mathematical constants and specialize the second division residual
.NET Test / .NET tests (push) Successful in 2m23s

This commit is contained in:
2026-09-14 21:21:48 +04:00
parent 08036a31d5
commit 4efecbb1bc
11 changed files with 875 additions and 24 deletions
@@ -0,0 +1,76 @@
"""Reproduce DoubleDouble's precomputed mathematical constants.
Run: python3 -B 1-tests/Just.PreciseMath.Tests/ReferenceData/generate_constants.py
Standard library only; no dependency on the implementation under test.
Decimal evaluates formulas at 160 and 240 digits; Fraction-based splitting
rounds the high and then the exact residual to nearest-even binary64.
"""
from decimal import Decimal, localcontext
from fractions import Fraction
from generate_irrational_arithmetic import arctan_inverse, split
def constants(precision: int) -> dict[str, tuple[float, float]]:
with localcontext() as context:
context.prec = precision
one = Decimal(1)
pi = 16 * arctan_inverse(5) - 4 * arctan_inverse(239)
e = one.exp()
ln2 = Decimal(2).ln()
ln10 = Decimal(10).ln()
sqrt2 = Decimal(2).sqrt()
sqrt3 = Decimal(3).sqrt()
sqrt5 = Decimal(5).sqrt()
sqrt_pi = pi.sqrt()
sqrt_tau = (2 * pi).sqrt()
values = {
"Pi": pi,
"E": e,
"Ln2": ln2,
"Tau": 2 * pi,
"PiOver2": pi / 2,
"PiOver3": pi / 3,
"PiOver4": pi / 4,
"PiOver6": pi / 6,
"InvPi": one / pi,
"InvTau": one / (2 * pi),
"DegToRad": pi / 180,
"RadToDeg": 180 / pi,
"InvE": one / e,
"Ln10": ln10,
"Log2E": one / ln2,
"Log10E": one / ln10,
"Log2Of10": ln10 / ln2,
"Log10Of2": ln2 / ln10,
"Sqrt2": sqrt2,
"Sqrt3": sqrt3,
"Sqrt5": sqrt5,
"InvSqrt2": one / sqrt2,
"InvSqrt3": one / sqrt3,
"SqrtPi": sqrt_pi,
"InvSqrtPi": one / sqrt_pi,
"TwoInvSqrtPi": 2 / sqrt_pi,
"SqrtTau": sqrt_tau,
"InvSqrtTau": one / sqrt_tau,
"GoldenRatio": (one + sqrt5) / 2,
}
pairs = {name: split(Fraction(value)) for name, value in values.items()}
for name, value in values.items():
high, low = pairs[name]
assert high + low == high, f"Unnormalized constant: {name}"
assert low != 0.0, f"Lost residual: {name}"
assert abs(Fraction(high) + Fraction(low) - Fraction(value)) <= abs(Fraction(value)) / (1 << 105)
return pairs
if __name__ == "__main__":
pairs = constants(160)
assert pairs == constants(240), "Increase precision: binary64 constants did not stabilize"
print("// Expected test components")
for name, (high, low) in pairs.items():
print(f' [InlineData("{name}", {high!r}, {low!r})]')
print("\n// Precomputed properties")
for name, (high, low) in pairs.items():
print(f" public static DoubleDouble {name} => new({high!r}, {low!r});")