| #!/usr/bin/env python3 | |
| # | |
| # Compute tables for longobject.c long_from_non_binary_base(). They are used | |
| # for conversions of strings to integers with a non-binary base. | |
| import math | |
| import textwrap | |
| def format_array(name, values): | |
| values = [str(v) for v in values] | |
| values = ', '.join(values) | |
| result = f'{name} = {{{values}}};' | |
| result = textwrap.wrap( | |
| result, | |
| initial_indent=' ' * 4, | |
| subsequent_indent=' ' * 8, | |
| ) | |
| return '\n'.join(result) | |
| def conv_tables(long_bits): | |
| PyLong_BASE = 1 << long_bits | |
| log_base_BASE = [0.0] * 37 | |
| convmultmax_base = [0] * 37 | |
| convwidth_base = [0] * 37 | |
| for base in range(2, 37): | |
| is_binary_base = (base & (base - 1)) == 0 | |
| if is_binary_base: | |
| continue # don't need, leave as zero | |
| convmax = base | |
| i = 1 | |
| log_base_BASE[base] = math.log(base) / math.log(PyLong_BASE) | |
| while True: | |
| next = convmax * base | |
| if next > PyLong_BASE: | |
| break | |
| convmax = next | |
| i += 1 | |
| convmultmax_base[base] = convmax | |
| assert i > 0 | |
| convwidth_base[base] = i | |
| return '\n'.join( | |
| [ | |
| format_array( | |
| 'static const double log_base_BASE[37]', log_base_BASE | |
| ), | |
| format_array( | |
| 'static const int convwidth_base[37]', convwidth_base | |
| ), | |
| format_array( | |
| 'static const twodigits convmultmax_base[37]', | |
| convmultmax_base, | |
| ), | |
| ] | |
| ) | |
| def main(): | |
| print( | |
| f'''\ | |
| // Tables are computed by Tools/scripts/long_conv_tables.py | |
| #if PYLONG_BITS_IN_DIGIT == 15 | |
| {conv_tables(15)} | |
| #elif PYLONG_BITS_IN_DIGIT == 30 | |
| {conv_tables(30)} | |
| #else | |
| #error "invalid PYLONG_BITS_IN_DIGIT value" | |
| #endif | |
| ''' | |
| ) | |
| if __name__ == '__main__': | |
| main() |