Перевод целых и дробных чисел в троичную систему на Python

Раздел: Алгоритмы -> Системы счисления в 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'))      # 0
11120
-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 позволяет избежать накопления погрешностей при переводе рациональных чисел.

Перевод числа в троичную систему счисления на Python - comments

En
перевод в троичную систему счисления python (python)