back to table · edit · history · where entries came from · files · download
3596 bytes, as of the version from 2026-10-25 07:24 (current). Recorded here, not run.
"""Check the precision correction for numberdb.org/T477.
Run with SageMath (numberdb installed):
sage -python repair-checks.py T477-live-before.json
Or pipe an API key on stdin to check the current private draft:
cat "$NUMBERDB_KEY_FILE" | sage -python repair-checks.py
This script writes nothing to NumberDB. Source bounds are from Markot (2021),
Section 7.5, DOI 10.1007/s10898-021-01086-z, fetched 2026-10-25 at
https://pmc.ncbi.nlm.nih.gov/articles/PMC8550790/?pdf=1 .
The decimal intervals are interpreted with NumberDB's one-last-place radius.
"""
import json
import sys
from decimal import Decimal
from pathlib import Path
import numberdb.sage as numberdb
from sage.rings.rational_field import QQ
from sage.rings.real_mpfr import RealField # initializes QQ string coercion
from sage.version import version as sage_version
def rational(text):
if '/' in text:
return QQ(text)
value = Decimal(text)
sign, digits, exponent = value.as_tuple()
mantissa = int(''.join(map(str, digits))) * (-1 if sign else 1)
return QQ(mantissa) * QQ(10) ** int(exponent)
def interval(text):
center = rational(text)
if '.' not in text and 'e' not in text.lower():
return center, center
radius = QQ(10) ** int(Decimal(text).as_tuple().exponent)
return center - radius, center + radius
def significant_digits(text):
return len(Decimal(text).as_tuple().digits)
assert significant_digits('0.0012300') == 5
assert significant_digits('11.463944032450') == 14
assert interval('3.14') == (QQ(313)/QQ(100), QQ(315)/QQ(100))
assert interval('1/2') == (QQ(1)/QQ(2), QQ(1)/QQ(2))
assert interval('4') == (QQ(4), QQ(4))
if len(sys.argv) > 1:
document = json.loads(Path(sys.argv[1]).read_text())
else:
client = numberdb.Client(api_key=sys.stdin.read().strip())
document = numberdb.table('T477', client=client)
bounds = {
'31': ('0.2175472916191243', '0.2175472916191280'),
'32': ('0.2131745625898764', '0.2131745625898779'),
'33': ('0.2113283841432631', '0.2113283841432645'),
}
results = []
for n, (low, high) in bounds.items():
lo, hi = rational(low), rational(high)
assert QQ(0) < lo < hi
certified = {'separation': (lo, hi),
'container': (QQ(2)+QQ(2)/hi, QQ(2)+QQ(2)/lo)}
for form, (a, b) in certified.items():
text = document['Numbers'][n][form]['number']
lower, upper = interval(text)
assert lower <= a <= b <= upper, (n, form)
digits = significant_digits(text)
assert digits == (13 if (n, form) == ('31', 'separation') else 14)
results.append({'n': n, 'normalisation': form, 'number': text,
'significant_digits': digits,
'contains_certified_interval': True,
'certified_lower': str(a), 'certified_upper': str(b)})
for n, pair in document['Numbers'].items():
drow, srow = pair['separation'], pair['container']
dlo, dhi = interval(drow['number'] if isinstance(drow, dict) else drow)
slo, shi = interval(srow['number'] if isinstance(srow, dict) else srow)
assert dlo > QQ(0) and slo > QQ(2)
transformed = (QQ(2)+QQ(2)/dhi, QQ(2)+QQ(2)/dlo)
assert max(slo, transformed[0]) <= min(shi, transformed[1]), n
assert len(document['Numbers']) == 99
print(json.dumps({'table': 'T477', 'sage_version': sage_version,
'controls_passed': True, 'certified_rows': results,
'conversion_interval_checks_passed': 99,
'scope': 'Precision counts and source-bound containment, not a new optimality proof.'}, indent=2))