You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

45 lines
1.6 KiB

#!/usr/bin/env python2
#
# Generate a table indicating how many digits should be considered
# significant for each radix (2 to 36) when doing string-to-number
# conversion.
#
# For decimal, the E5/E5.1 specification indicates that anything
# after the 20th digit can be ignored (treated as zero) and the
# 20th digit can be rounded upwards. We estimate the significant
# bits of precision from this and compute similar values for other
# radix values.
#
# Also generate a table of minimum and maximum radix-specific
# exponent values above and below which a number is guaranteed
# to overflow to Infinity or underflow to zero. This allows the
# C code to quick reject such exponent values, and to keep bigint
# values bounded. The exponent limit is relative to an integer
# significand padded to the precision-related digit count (e.g.
# 20 for decimal).
import math
digits_table = []
limits_table = []
for radix in xrange(2, 36+1):
bits_per_digit = math.log(radix, 2)
if radix == 10:
prec_digits = 20
else:
target_bits = math.ceil(math.log(10, 2) * 20) + 2 # +2 is extra, just in case
prec_digits = int(math.ceil(target_bits / bits_per_digit))
digits_table.append(prec_digits)
# these are conservative (details are off by one etc); +/- 2 is the extra
overflow_limit = int(math.ceil(1024.0 / bits_per_digit)) + 2 - prec_digits
underflow_limit = int(math.floor((-1024.0 - 52.0) / bits_per_digit)) - 2 - prec_digits
limits_table.append(overflow_limit)
limits_table.append(underflow_limit)
print repr(digits_table)
print repr(limits_table)