Как преобразовать число с плавающей запятой в базу 3 в python

Как преобразовать число с плавающей запятой base-10 в Python в число с плавающей запятой base-N?

в частности, в моем случае я хотел бы преобразовать числа в базу 3 (получить представление чисел с плавающей запятой в базе 3), для расчетов с Кантор set.

1 ответов


после небольшой возни, вот что я придумал. Я смиренно представляю его вам, помня предупреждение Игнасио. Пожалуйста, дайте мне знать, если вы найдете какие-либо недостатки. Помимо всего прочего, у меня нет оснований полагать, что precision аргумент дает нечто большее, чем смутную уверенность в том, что первый precision цифры довольно близки к правильному.

def base3int(x):
    x = int(x)
    exponents = range(int(math.log(x, 3)), -1, -1)
    for e in exponents:
        d = int(x // (3 ** e))
        x -= d * (3 ** e)
        yield d

def base3fraction(x, precision=1000):
    x = x - int(x)
    exponents = range(-1, (-precision - 1) * 2, -1)
    for e in exponents:
        d = int(x // (3 ** e))
        x -= d * (3 ** e)
        yield d
        if x == 0: break

это итераторы, возвращающие ints. Дайте мне знать, если вам нужно преобразование строк; но я думаю, вы можете справиться что.

EDIT: на самом деле, глядя на это еще немного, кажется, что if x == 0: break строке после yield на base3fraction дает вам довольно много произвольной точности. Я пошел вперед и добавил Это. Тем не менее, я ухожу в precision аргумент; имеет смысл иметь возможность ограничить это количество.

кроме того, если вы хотите преобразовать обратно в десятичные дроби, это то, что я использовал для проверки выше.

sum(d * (3 ** (-i - 1)) for i, d in enumerate(base3fraction(x)))

обновление

по какой-то причине Меня вдохновила эта проблема. Вот гораздо более обобщенное решение. Это возвращает два генератора, которые генерируют последовательности целых чисел, представляющих интегральную и дробную часть заданного числа в произвольной базе. Обратите внимание, что это возвращает только два генератора для различения частей числа; алгоритм генерации цифр одинаков в обоих случаях.

def convert_base(x, base=3, precision=None):
    length_of_int = int(math.log(x, base))
    iexps = range(length_of_int, -1, -1)
    if precision == None: fexps = itertools.count(-1, -1)
    else: fexps = range(-1, -int(precision + 1), -1)

    def cbgen(x, base, exponents):
        for e in exponents:
            d = int(x // (base ** e))
            x -= d * (base ** e)
            yield d
            if x == 0 and e < 0: break

    return cbgen(int(x), base, iexps), cbgen(x - int(x), base, fexps)