Files
just b54a0a2d42
.NET Test / .NET tests (push) Successful in 1m31s
pow, log and exp
2026-09-15 00:33:31 +04:00

44 lines
1.7 KiB
Python

#!/usr/bin/env python3
"""Generate integer Pow fixtures independently with Python's stdlib Decimal.
Use exact binary64 components, then Decimal integer exponentiation at 160 and
240 significant decimal digits. Retain only rows whose floor after multiplication
by 10**100 agrees at both precisions. Tests check both ends of the resulting
100-decimal-place reference interval, far tighter than their DD error tolerance.
No Python or generated data is needed when running the .NET tests.
"""
from decimal import Decimal, localcontext, ROUND_FLOOR
import math
def reference(high, low, exponent, precision):
with localcontext() as context:
context.prec = precision
value = Decimal.from_float(high) + Decimal.from_float(low)
result = context.power(value, exponent)
return int((result * (Decimal(10) ** 100)).to_integral_value(rounding=ROUND_FLOOR))
def main():
inputs = [
(1.0, math.ldexp(1.0, -54)),
(1.0, -math.ldexp(1.0, -54)),
(1.0 + math.ldexp(1.0, -30), math.ldexp(1.0, -84)),
(1.0 - math.ldexp(1.0, -30), -math.ldexp(1.0, -84)),
(1.00000003, math.ldexp(1.0, -55)),
]
for high, low in inputs:
for exponent in [-2147483648, 2147483647]:
first = reference(high, low, exponent, 160)
second = reference(high, low, exponent, 240)
assert first == second, (high, low, exponent)
# Very tiny results need a relative rather than fixed-place interval;
# these rows instead exercise the large positive-power fixture.
if first == 0:
continue
print(f' [InlineData({high!r}, {low!r}, {exponent}, "{first}")]')
if __name__ == "__main__":
main()