Поплавок в двоичный

Я пытаюсь преобразовать число с плавающей точкой в ​​двоичное представление; как я могу это достичь? Моя цель, однако, не ограничивается 2 м, поэтому я надеюсь на что-то, что можно легко распространить на любую базу (3, 4, 8) ecc.

До сих пор у меня есть прямая реализация целых чисел:

import string LETTER = '0123456789' + string.ascii_lowercase def convert_int(num, base): if base == 1: print "WARNING! ASKING FOR BASE = 1" return '1' * num if num != 0 else '0' if base > 36: raise ValueError('base must be >= 1 and <= 36') num, rest = divmod(num, base) rest = [LETTER[rest]] while num >= base: num, r = divmod(num, base) rest.append(LETTER[r]) rest.reverse() return (LETTER[num] if num else '') + ''.join(str(x) for x in rest) 

любая помощь оценивалась 🙂

редактировать:

 def convert_float(num, base, digits=None): num = float(num) if digits is None: digits = 6 num = int(round(num * pow(base, digits))) num = convert_int(num, base) num = num[:-digits] + '.' + num[:digits] if num.startswith('.'): num = '0' + num return num 

это правильно? почему я получаю такое поведение?

 >>> convert_float(1289.2893, 16) '509.5094a0' >>> float.hex(1289.2983) '0x1.42531758e2196p+10' 

ps Как преобразовать число с плавающей точкой в ​​двоичный?

Я прочитал эту дискуссию, но я не получаю ответа. Я имею в виду, она работает только на 0,25, 0,125? и я не понимаю, фраза «должна быть в обратном порядке» …

  • Меркурийные скрипты с питоном
  • gevent и posgres: асинхронное соединение не выполнено
  • Обработка щебетать в Twitter
  • Использовать datetime.strftime () до 1900 года? («Требуется год> = 1900»)
  • Python в Windows - как ждать нескольких дочерних процессов?
  • Django Admin: упорядочение отношений ForeignKey и ManyToManyField, ссылающихся на пользователя
  • Установка Python 2.7 на SLES 11
  • Как получить файл HTML с помощью Python?
  • 5 Solutions collect form web for “Поплавок в двоичный”

    Следующий ответ с некоторой теорией.

    Объяснение ниже не объясняет стандарт IEEE Floating Point только общие идеи относительно представления чисел с плавающей запятой

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

    Итак, у нас есть

    1. Значок бит
    2. Дробные частичные цифры
    3. Цифры деталей

    Пример для базы 2 с 8-разрядной долей и 8-разрядным показателем

    Биты во фракционной части указывают нам, какие слагаемые (числа, которые должны быть добавлены) из приведенной ниже последовательности должны быть включены в представленное числовое значение

    2 ^ -1 + 2 ^ -2 + 2 ^ -3 + 2 ^ -4 + 2 ^ -5 + 2 ^ -6 + 2 ^ -7 + 2 ^ -8

    Итак, если вы говорите 01101101 в дробной части, она дает

    0 * 2 ^ -1 + 1 * 2 ^ -2 + 1 * 2 ^ -3 + 0 * 2 ^ -4 + 1 * 2 ^ -5 + 1 * 2 ^ -6 + 0 * 2 ^ -7 + 1 * 2 ^ -8 = 0,42578125

    Теперь отличные от нуля числа, которые представляются таким образом, падают между 2 ** -8 = 0,00390625 и 1 – 2 ** – 8 = 0,99609375

    Здесь присутствует экспоненциальная часть. Экспонента позволяет нам представлять очень большие числа, умножая часть дроби на экспоненту. Поэтому, если у нас есть 8-битный показатель, мы можем умножить полученную долю на числа от 0 до 2 ^ 255.

    Поэтому, вернемся к примеру выше, возьмем показатель 11000011 = 195.

    У нас есть дробная часть 01101101 = 0,42578125 и экспоненциальная часть 11000011 = 195. Она дает нам номер 0.42578125 * 2 ^ 195, это действительно большое количество.

    Пока мы можем представить ненулевые числа между 2 ^ -8 * 2 ^ 0 и (1-2 ^ -8) * 2 ^ 255. Это позволяет использовать очень большие цифры, но не для очень маленьких чисел. Чтобы иметь возможность представлять небольшие числа, мы должны включить так называемое смещение в нашем экспоненте. Это число, которое будет всегда вычитаться из экспоненты, чтобы допускать представление небольших чисел.

    Возьмем смещение 127. Теперь все экспоненты вычитаются 127. Таким образом, числа, которые могут быть представлены, находятся между 2 ^ -8 * 2 ^ (0 – 127) и (1-2 ^ -8) * 2 ^ (255 – 127 = 128)

    Номер примера теперь 0.42578125 * 2 ^ (195-127 = 68), который по-прежнему довольно большой.

    Пример заканчивается

    Чтобы лучше понять это, попробуйте поэкспериментировать с разными основаниями и размерами для дробной и экспоненциальной части. Вначале не пытайтесь использовать нечетные базы, потому что это только усложняет необходимые вещи.

    Как только вы поймете, как это представление работает, вы должны иметь возможность писать код, чтобы получить представление любого числа в любой базовой, дробной / экспоненциальной комбинации деталей.

    Для поплавков существует встроенный метод hex ().

    http://docs.python.org/library/stdtypes.html#float.hex

    Он дает шестнадцатеричное представление заданного числа. И форма перевода hex в двоичную форму тривиальна.

    Например:

     In [15]: float.hex(1.25) Out[15]: '0x1.4000000000000p+0' In [16]: float.hex(8.25) Out[16]: '0x1.0800000000000p+3' 

    Если вы хотите преобразовать float в строку с d цифрами после десятичной точки счисления:

    1. Умножьте число на base**d .
    2. Раунд до ближайшего целого.
    3. Преобразуйте целое число в строку.
    4. Вставьте . символ d до конца.

    Например, чтобы представить 0,1 в базе 12 с 4 десятичными десятичными местами,

    1. 0,1 × 12 4 = 2073,6
    2. От округленного до ближайшего целого → 2074
    3. Преобразовать в строку → 124A
    4. Добавить радиус точки → 0.124A

    Это не тот стиль бинарного представления, который вы хотите, но это преобразует IEEE 754 в его знак, мантиссу и базу, которые можно использовать для создания шестнадцатеричного представления довольно простым способом. Обратите внимание, что «значение» мантиссы равно 1 + BINARY, где BINARY является двоичным представлением – следовательно, -1 в обратном.

    Я написал этот код и объявляю его общедоступным.

      def disect_float(f): f = float(f); #fixes passing integers sign = 0x00; #positive exp = 0; mant = 0; if(f < 0): #make f positive, store the sign sign = '-'; #negative f = -f; #get the mantissa by itself while(f % 1 > 0): #exp is positive f*=2 exp+=1 #while(f % 1 > 0): tf = f/2; while(tf % 1 <= 0): #exp is negative exp-=1; f=tf; tf=f/2; if(exp < -1024): break; mant=int(f); return sign, mant-1, exp; 

    Отвечая на заголовок напрямую и используя float.hex, который использует 64-битный IEE754, можно написать этот метод:

     def float_to_bin(x): if x == 0: return "0" * 64 w, sign = (float.hex(x), 0) if x > 0 else (float.hex(x)[1:], 1) mantissa, exp = int(w[4:17], 16), int(w[18:]) return "{}{:011b}{:052b}".format(sign, exp + 1023, mantissa) float_to_bin(-0.001) # '1011111101010000000010110011111101011000011011100110110100101010' 

    Обратите внимание, однако, это не работает для NaN и Inf.

    Python - лучший язык программирования в мире.