Почему Python не работает с системами счисления, основания которых превышают 36?
Вот программа, печатающая элементы последовательности A235395, не превышающие 4000:
# Here's a Python program that checks for prime numbers
# whose decimal representation is also a valid number
# in base 9 and interpreted as such is again a prime,
# and prints such numbers less than 4000:
def is_prime(n):
"""Check if a number is prime."""
if n < 2:
return False
for i in range(2, int(n**0.5) + 1):
if n % i == 0:
return False
return True
def is_valid_base_9(n):
"""Check if a number is valid in base 9."""
digits = str(n)
for digit in digits:
if int(digit) >= 9:
return False
return True
primes_base_9 = []
for n in range(2, 4000):
if is_prime(n) and is_valid_base_9(n) and is_prime(int(str(n), 9)):
primes_base_9.append(n)
print(primes_base_9)
Допустим, я желаю изменить эту программу таким образом, чтобы она работала не с 9-чной, а с 37-чной системой счисления. Оказывается, я не могу этого сделать:
ValueError: int() base must be >= 2 and <= 36, or 0
Как выйти из данного положения?
P.S. Ктати, а разве бывает позиционная система счисления с основанием 0? Почему её Python разрешает?
Ответы (3 шт):
Ошибка возникает, потому что в Python встроенная функция int() принимает второй аргумент только от 2 до 36. Чтобы работать с числами в системе счисления больше 36, можно воспользоваться библиотекой intlib.
from intlib import Int
n = 12345
base = 37
n_base_37 = Int(n).to_base(base)
Также в intlib есть метод from_base(), который можно использовать для перевода числа из другой системы счисления в 10-ую:
from intlib import Int
n_base_37 = "a1b2c3d4e5"
base = 37
n = Int(n_base_37, base=base)
Почему Python не работает с системами счисления, основания которых превышают 36?
Потому что Python не "знает" цифр больше 35. Первые десять берутся из обычной десятичной: 0...9, следующие 26 — буквы латиницы a...z. Так исторически сложилось ещё полвека назад. А какой символ по вашему он должен использовать для цифры 36?
Кcтати, а разве бывает позиционная система счисления с основанием 0? Почему её Python разрешает?
0 используется как специальное значение, означающее автоматическое определение основания системы счисления по формату строки. int("10", 0) == 10, int("0x10", 0) == 16, int("0b10", 0) == 2.
Если же основание системы счисления не указано, то считается равным 10.
Источник: https://docs.python.org/3/library/functions.html#int
Считайте значение в тридцатисимеричной системе руками. Функция из пяти строк:
import math
def is_prime(n):
"""Check if a number is prime."""
return n >= 2 and all(n % i != 0 for i in range(2, math.isqrt(n) + 1))
def is_valid_in_base(n, base):
"""Check if a number is valid in given base."""
return all(int(d) < base for d in str(n))
def value_in_base(n, base):
v = 0
for d in str(n):
v = base * v + int(d)
return v
base = 37
primes_base = []
for n in range(2, 4000):
if is_valid_in_base(n, base) and is_prime(n) and is_prime(value_in_base(n, base)):
primes_base.append(n)
print(primes_base)
$ py temp.py [2, 3, 5, 7, 29, 41, 43, 61, 67, 113, 131, 137, 139, 179, 197, 227, 241, 263, 269, 283, 331, 397, 401, 463, 487, 599, 607, 641, 647, 683, 719, 733, 751, 797, 821, 863, 883, 1033, 1039, 1051, 1093, 1097, 1231, 1277, 1297, 1307, 1361, 1381, 1439, 1543, 1567, 1613, 1619, 1697, 1699, 1787, 1811, 1831, 1877, 1907, 1949, 1987, 2063, 2069, 2081, 2089, 2137, 2203, 2221, 2287, 2333, 2339, 2371, 2423, 2447, 2531, 2539, 2557, 2683, 2711, 2797, 2803, 2861, 2957, 2999, 3037, 3109, 3167, 3251, 3343, 3389, 3457, 3491, 3547, 3617, 3659, 3691, 3701, 3767, 3769, 3923, 3929, 3943]