Найти - Пользователи
Полная версия: система счисления с основанием n
Начало » Python для новичков » система счисления с основанием n
1 2 3
shiroi
Вечер добрый всем. Может кто подсказать, как написать функцию, которая бы переводила введенное десятичное число в систему счисления с основанием от 2 до 36?Заранее благодарю за любую помощь
py.user.next
Переводит число из десятичной системы в любую систему в пределах [2; +inf).

Add
Для нуля забыл учесть, ниже поправил версию.
shiroi
py.user.next
Переводит число из десятичной системы в любую систему в пределах [2; +inf).
оо,спасибо большое за помощь
py.user.next
Исправил версию, добавив обработку нуля в числе.

tags: system base
shiroi
py.user.next
Спасибо еще раз. Возникла проблема,при вводе с клавиатуры числа 34 и при переводе его в 8 систему, выводит это : 4.02.0, хотя должен 42. И так со всеми, особенно если вводимое число дробное.
py.user.next
Она не переводит вещественные (дробные) числа, только целые положительные. Это сделано специально. Это общая задача, все остальные варианты строятся на её решении.
1) Дробные числа переводятся по частям: сначала число разделяется на целую и дробную части; затем переводится целая часть; затем переводится дробная часть; затем переведённые части соединяются обратно через точку.
2) То же самое с отрицательными числами: сначала отделяется знак; затем число переводится; затем знак присоединяется обратно к переведённому числу.

И тут ты понимаешь, что отрицательное число может быть как целым, так и дробным. Целое раскладывать не нужно, а дробное - нужно. То есть уже всё запутывается, поэтому это всё нельзя в одну функцию загонять. Может получиться так, что у тебя в программе будут только целые числа встречаться, а функция будет пытаться постоянно что-то разложить, затрачивая время на это, хотя это не надо.

Можно написать функцию-обёртку, которая определяет вид поданного числа, раскладывает его соответствующим образом (если надо), потом использует эту базовую функцию для перевода числа в заданную систему счисления, а потом соединяет переведённые части обратно тем же образом, которым они разделялись.

То есть получается, что у тебя есть разные функции, и каждая из этих функций занимается только своим делом. Одна функция готовит части числа, другая функция переводит каждую часть определённым образом. Таким образом в функциях соблюдается принцип функциональной прочности модуля: одна функция - одно действие.
Дед Мороз, который сам танцует, сам поёт, сам подарки раздаёт, - в программировании не приветствуется. Почему? Потому что в таком случае не получается реюз кода. Реюз кода - это когда ты написал функцию один раз, а потом используешь её в разных программах годами. Чтобы был возможен реюз кода, код должен быть максимально сужен до своей задачи.
Представь просто связку ключей, которую ты носишь с собой, и тут тебя просят один конкретный ключ от гаража, но ты не можешь его дать со всей связкой, потому что тебе надо попасть домой, а ключ от дома в этой же связке. Из-за этого ты должен тратить время на расцепление ключей. Вот с функциями то же самое происходит: когда тебе нужна функция в каком-то проекте, но она делает что-то ещё, что тебе в том проекте не надо, тебе придётся её брать и редактировать, удаляя лишнее и всё это ещё проверяя потом на правильность, вместо того, чтобы просто её взять и сразу использовать.
shiroi
py.user.next
Она не переводит вещественные (дробные) числа, только целые положительные. Это сделано специально. Это общая задача, все остальные варианты строятся на её решении.1) Дробные числа переводятся по частям: сначала число разделяется на целую и дробную части; затем переводится целая часть; затем переводится дробная часть; затем переведённые части соединяются обратно через точку.2) То же самое с отрицательными числами: сначала отделяется знак; затем число переводится; затем знак присоединяется обратно к переведённому числу.И тут ты понимаешь, что отрицательное число может быть как целым, так и дробным. Целое раскладывать не нужно, а дробное - нужно. То есть уже всё запутывается, поэтому это всё нельзя в одну функцию загонять. Может получиться так, что у тебя в программе будут только целые числа встречаться, а функция будет пытаться постоянно что-то разложить, затрачивая время на это, хотя это не надо.Можно написать функцию-обёртку, которая определяет вид поданного числа, раскладывает его соответствующим образом (если надо), потом использует эту базовую функцию для перевода числа в заданную систему счисления, а потом соединяет переведённые части обратно тем же образом, которым они разделялись.То есть получается, что у тебя есть разные функции, и каждая из этих функций занимается только своим делом. Одна функция готовит части числа, другая функция переводит каждую часть определённым образом. Таким образом в функциях соблюдается принцип функциональной прочности модуля: одна функция - одно действие. Дед Мороз, который сам танцует, сам поёт, сам подарки раздаёт, - в программировании не приветствуется.
охох, спасибо большое за такой ответ, буду тогда пытаться написать все это правильно
py.user.next
Это на базе функции decimal_to_base() построена функция, которая вычисляет для целых и вещественных чисел со знаком. Таких функций можно построить много, с разным поведением.
  
def decimal_fraction_to_base(number, base):
    out = None
    if isinstance(number, int):
        out = decimal_to_base(abs(number), base)
        if number < 0:
            out = '-' + out
    elif isinstance(number, float):
        parts = str(number).partition('.')
        ipart = int(parts[0].strip('-'))
        fpart = int(parts[-1])
        oipart = decimal_to_base(ipart, base)
        ofpart = decimal_to_base(fpart, base)
        out = oipart + '.' + ofpart
        if number < 0:
            out = '-' + out
    return out

  
>>> import numbase
>>>
>>> numbase.decimal_fraction_to_base(12345.255, 36)
'9(18)(33).73'
>>> numbase.decimal_fraction_to_base(12345.255, 16)
'3039.(15)(15)'
>>> numbase.decimal_fraction_to_base(-12345, 16)
'-3039'
>>> numbase.decimal_fraction_to_base(-12345.255, 16)
'-3039.(15)(15)'
>>>

Видишь, как тут играет роль то, что базовая функция не учитывает знак числа? Просто при вычислении дробного числа нам не нужно учитывать знак у дробной части, поэтому базовая функция при вычислении дробной части не делает лишних телодвижений, чтобы понять, какой там знак.
shiroi
py.user.next
Еще раз спасибо за помощь. Вопрос если можно, а как вывести вместо ‘9(18)(33).73’ числа от 0-9 а потом буквенные значения?
py.user.next
Мы делаем дополнительный транслятор цифр любой системы счисления в любые символы и встраиваем его в функцию преобразования вещественных чисел
  
>>> import re
>>> 
>>> def translate_base_digits(number):
...     digits_map = {
...         '(10)': 'a', '(11)': 'b', '(12)': 'c',
...         '(13)': 'd', '(14)': 'e', '(15)': 'f',
...         '(16)': 'g', '(17)': 'h', '(18)': 'i',
...         '(19)': 'j', '(20)': 'k', '(21)': 'l',
...         '(22)': 'm', '(23)': 'n', '(24)': 'o',
...         '(25)': 'p', '(26)': 'q', '(27)': 'r',
...         '(28)': 's', '(29)': 't', '(30)': 'u',
...         '(31)': 'v', '(32)': 'w', '(33)': 'x',
...         '(34)': 'y', '(35)': 'z',
...     }
...     def trans(digit):
...         return digits_map.get(digit, digit)
...     out = re.sub(r'\(\d+\)', lambda mo: trans(mo.group()), number)
...     return out
... 
>>> def decimal_fraction_to_base(number, base):
...     out = None
...     if isinstance(number, int):
...         out = decimal_to_base(abs(number), base)
...         if number < 0:
...             out = '-' + out
...     elif isinstance(number, float):
...         parts = str(number).partition('.')
...         ipart = int(parts[0].strip('-'))
...         fpart = int(parts[-1])
...         oipart = decimal_to_base(ipart, base)
...         ofpart = decimal_to_base(fpart, base)
...         out = oipart + '.' + ofpart
...         if number < 0:
...             out = '-' + out
...     out = translate_base_digits(out)
...     return out
... 
>>> from numbase import decimal_to_base
>>> 
>>> decimal_fraction_to_base(12345.255, 36)
'9ix.73'
>>> decimal_fraction_to_base(12345.255, 16)
'3039.ff'
>>> decimal_fraction_to_base(-12345, 16)
'-3039'
>>> decimal_fraction_to_base(-12345, 36)
'-9ix'
>>> decimal_fraction_to_base(-12345.255, 16)
'-3039.ff'
>>> decimal_fraction_to_base(-12345.255, 36)
'-9ix.73'
>>>
В идеале, у тебя должны быть отдельные функции, в которые подаются данные, поступающие из других функций или передающиеся напрямую. Здесь же транслятор цифр фиксирует данные (какие цифры в какие буквы) внутри функции, тогда как в идеале маппинг должен передаваться в функцию снаружи, чтобы можно было его дополнить в любой момент или видоизменить (сделать больше букв всяких, поменять регистр букв и так далее).
Почему нельзя сделать всё с самого начала на буквах? Потому что букв самих по себе немного, а базовая функция работает с любыми системами счисления (это математический подход, в котором системы счисления не ограничены какой либо базой).
В твоём случае надо ограничить систему счисления 36-ю, а где-то понадобится система счисления 1000, поэтому в ней никаких букв не хватит. Вот поэтому в общей функции используются скобки с числами, а всё остальное становится частными случаями и реализуется каждый раз по-своему.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB