44 lines
1.7 KiB
Python
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()
|