Перевод целых и дробных чисел в троичную систему на Python
Перевод числа в троичную систему счисления на Python
Наиболее эффективный способ перевода целого положительного числа в троичную систему - последовательное деление на 3 с сохранением остатков. Функция to_ternary(n) принимает целое число и возвращает строку с троичным представлением.
def to_ternary(n):
if n == 0:
return '0'
digits = []
while n > 0:
digits.append(str(n % 3))
n //= 3
return ''.join(reversed(digits))алгоритм перевода систем счисления python (алгоритм перевода систем счисления на python)
Пояснение: на каждом шаге остаток от деления на 3 (0, 1 или 2) добавляется в список. После выхода из цикла список переворачивается и объединяется в строку. Для нуля возвращается '0'.
Как получить троичное представление с помощью рекурсии?
Рекурсивный вариант компактнее, но может вызвать переполнение стека для очень больших чисел.
def to_ternary_rec(n):
if n < 3:
return str(n)
return to_ternary_rec(n // 3) + str(n % 3)перевод в любую систему счисления python код (перевод числа в любую систему счисления на python (код))
Базовый случай: если n < 3, возвращаем его строковое представление. Иначе рекурсивно обрабатываем целую часть от деления на 3 и дописываем остаток.
Как преобразовать отрицательное число в троичную систему?
Для отрицательных чисел обычно добавляют знак. Можно модифицировать функцию, определив знак отдельно.
def to_ternary_signed(n):
if n == 0:
return '0'
sign = '-' if n < 0 else ''
n = abs(n)
digits = []
while n > 0:
digits.append(str(n % 3))
n //= 3
return sign + ''.join(reversed(digits))перевод в троичную систему счисления python (перевод числа в троичную систему счисления на python)
Проблема: знак просто добавляется в начало строки, что соответствует распространённой практике для целых чисел.
Как перевести дробное число (с плавающей точкой) в троичную систему?
Дробная часть переводится умножением на 3 с выделением целой части. Для дробных чисел результат может быть бесконечным, поэтому ограничиваем точность.
def to_ternary_float(num, precision=10):
"""Перевод числа с плавающей точкой в троичную систему."""
if num == 0:
return '0'
sign = '-' if num < 0 else ''
num = abs(num)
integer_part = int(num)
fractional_part = num - integer_part
# Перевод целой части
int_str = ''
if integer_part == 0:
int_str = '0'
else:
while integer_part > 0:
int_str = str(integer_part % 3) + int_str
integer_part //= 3
# Перевод дробной части
frac_str = ''
while fractional_part > 0 and precision > 0:
fractional_part *= 3
digit = int(fractional_part)
frac_str += str(digit)
fractional_part -= digit
precision -= 1
if frac_str:
return sign + int_str + '.' + frac_str
else:
return sign + int_strшестнадцатеричная система счисления python (шестнадцатеричная система счисления в python)
Важно: точность ограничена параметром precision, иначе для некоторых чисел (например, 1/3) цикл станет бесконечным.
Как использовать встроенную функцию format для перевода в троичную систему?
В Python нет прямого метода для троичной системы, но её можно эмулировать через пользовательскую функцию. Если нужно быстро перевести небольшое число, можно воспользоваться numpy.base_repr (требует установки numpy). Однако такое решение избыточно для простой задачи.
import numpy as np
np.base_repr(10, base=3) # '101'Этот способ удобен, если вы уже используете numpy в проекте, но добавлять зависимость ради одной операции нецелесообразно.
Типичные ошибки и их решение
- Забыли обработать ноль. Если число равно 0, цикл while не выполнится, и будет возвращена пустая строка. Решение: проверять n == 0 в начале.
- Неправильная обработка отрицательных чисел. Если передать отрицательное число без учёта знака, остатки от деления по модулю могут быть отрицательными. Решение: взять модуль перед циклом, а знак добавить отдельно.
- Бесконечный цикл для дробной части. Некоторые числа (например, 1/3) имеют бесконечную троичную запись. Решение: ограничить количество итераций параметром точности.
- Переполнение стека при рекурсии. Для очень больших чисел рекурсивный вызов может превысить лимит. Решение: использовать итеративный подход или увеличить лимит рекурсии через sys.setrecursionlimit.
Дополнительные расширенные примеры
Пример 1. Перевод нескольких чисел с проверкой корректности
def to_ternary_checked(s):
"""Перевод строки, содержащей целое число, в троичную систему."""
try:
n = int(s)
except ValueError:
return 'Ошибка: введите целое число'
if n < 0:
sign = '-'
n = -n
else:
sign = ''
if n == 0:
return '0'
digits = []
while n:
digits.append(str(n % 3))
n //= 3
return sign + ''.join(reversed(digits))
# Тесты
print(to_ternary_checked('123')) # 11120
print(to_ternary_checked('-5')) # -12
print(to_ternary_checked('abc')) # Ошибка: введите целое число
print(to_ternary_checked('0')) # 011120 -12 Ошибка: введите целое число 0
Пример 2. Обратное преобразование из троичной строки в десятичное число
def from_ternary(s):
"""Преобразует строку троичного числа в десятичное."""
if '.' in s:
integer_part, fractional_part = s.split('.')
else:
integer_part, fractional_part = s, ''
sign = 1
if integer_part.startswith('-'):
sign = -1
integer_part = integer_part[1:]
# Целая часть
result = 0
for i, digit in enumerate(reversed(integer_part)):
result += int(digit) * (3 ** i)
# Дробная часть
for i, digit in enumerate(fractional_part, start=1):
result += int(digit) * (3 ** (-i))
return sign * result
# Тесты
print(from_ternary('11120')) # 123
print(from_ternary('-12')) # -5
print(from_ternary('10.1')) # 3.333... -> 3.3333333333333335 (неточность из-за float)123 -5 3.3333333333333335
Пример 3. Перевод больших чисел (сравнение скорости)
import time
def to_ternary_iter(n):
if n == 0:
return '0'
digits = []
while n:
digits.append(str(n % 3))
n //= 3
return ''.join(reversed(digits))
def to_ternary_rec(n):
if n < 3:
return str(n)
return to_ternary_rec(n // 3) + str(n % 3)
# Измерим время для числа 10^50
big = 10**50
start = time.time()
res = to_ternary_iter(big)
time_iter = time.time() - start
start = time.time()
res_rec = to_ternary_rec(big)
time_rec = time.time() - start
print(f'Итеративный: {time_iter:.6f} сек')
print(f'Рекурсивный: {time_rec:.6f} сек')
# Вывод первых 20 символов результата для проверки
print(res[:20])Итеративный: 0.000015 сек Рекурсивный: 0.000062 сек (первые 20 символов троичного представления)
Итеративный метод быстрее, так как не нагружает стек рекурсивными вызовами.
Пример 4. Перевод числа с точкой с использованием модуля fractions
from fractions import Fraction
def to_ternary_fraction(num, max_denominator=1000):
"""Перевод числа в троичную дробь через точное представление Fraction."""
frac = Fraction(num).limit_denominator(max_denominator)
integer = frac.numerator // frac.denominator
remainder = Fraction(frac.numerator % frac.denominator, frac.denominator)
# Целая часть
if integer == 0:
int_str = '0'
else:
int_str = ''
while integer:
int_str = str(integer % 3) + int_str
integer //= 3
# Дробная часть
frac_str = ''
while remainder != 0 and len(frac_str) < 20:
remainder *= 3
digit = int(remainder)
frac_str += str(digit)
remainder -= digit
if frac_str:
return int_str + '.' + frac_str
else:
return int_str
print(to_ternary_fraction(1/3)) # 0.1
print(to_ternary_fraction(0.2)) # 0.0121... (возможно с периодикой)
print(to_ternary_fraction(2.5)) # 2.1111111111... (10/3 в десятичной - бесконечная троичная 2.111...)0.1 0.01210121012101210121 2.11111111111111111111
Метод с Fraction позволяет избежать накопления погрешностей при переводе рациональных чисел.