pow, log and exp
.NET Test / .NET tests (push) Successful in 1m31s

This commit is contained in:
2026-09-15 00:33:31 +04:00
parent beb9a084d0
commit b54a0a2d42
18 changed files with 2890 additions and 12 deletions
@@ -0,0 +1,43 @@
#!/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()