Преобразование двоичного файла с плавающей запятой

#python

#python

Вопрос:

Дана двоичная строка с плавающей запятой, содержащая дробную часть s: 100.0011

вывод должен быть 4.1875

я использовал ".".join(map(lambda x:str(int(x,2)),s.split('.')))

это дает 4.3 , но не 4.1875

Комментарии:

1. Удалите десятичную точку, преобразуйте ее в int с int(x, 2) помощью, а затем масштабируйте ее в зависимости от того, где была десятичная точка?

2. @user2357112 я сделал это, но это неправильно. поскольку 0011 равно 3. но ответ — 1875

3. Вы должны прочитать о двоичном представлении действительных чисел .

4. 0011 равно 3 в базе 2 . Почему это должно быть 1875?

5. @sundarnatarajСундар да, вы пропустили шаг масштабирования

Ответ №1:

Разделите число на целые и дробные разделы, затем используйте int , чтобы сделать каждую часть десятичной, имея в виду, что дробный раздел должен быть скорректирован в зависимости от его длины:

 >>> s = "100.0011"

>>> d = s.split(".")

>>> int(d[0],2)   float(int(d[1],2)) / 2**len(d[1])
4.1875
 

Деление 0011 на два степени его длины (2 4 равно 16) гарантирует, что оно обрабатывается правильно (3/16 равно 0,1875).

Комментарии:

1. bin здесь не используется. Вы хотели сказать что-то еще?

2. @user2357112: да, извините, я правильно понял в коде, но неправильно в тексте. Исправлено, спасибо за предупреждение.

Ответ №2:

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

 s = "100.0011" # binary number
n = s.index(".") # number of positions before the decimal point
r = 0 # result

for digit in s.replace(".", ""): # iterate through each digit ommiting the point '.'
    r  = int(digit) * 2 ** (n-1) # multiplicate the digit by the respective power of 2
    n -= 1

print r # 4.1875
 

Как это работает? Помните, как вы преобразуете двоичное число в десятичное (основание 10):

 100.0011  -> 1       0       0   .   0          0          1          1
powerOf 2 ->    4       2       1      1/2        1/4        1/8        1/16
                |       |       |       |          |          |          |
             1*2^2   0*2^1   0*2^0   0*2^(-1)   0*2^(-2)   1*2^(-3)   1*2^(-4)
 

Комментарии:

1. Обратите внимание на это len(s.split(".")[0]) == s.index(".") , и вы могли бы использовать zip и range для учета ручного увеличения n

2. @jonrsharpe спасибо, что указали на это. Я отредактирую его завтра. Время ожидания 🙂

Ответ №3:

int(x,2) не собирается понимать, как преобразовать дробную часть десятичной дроби, поскольку все эти значения являются степенями отрицательных 2, а не положительных 2. Вы можете сделать что-то вроде следующего:

 int_, frac = s.split(".")
res = ((int(int_, 2) << len(frac))   int(frac, 2)) / (2 ** len(frac))
 

Комментарии:

1. Это дает ответ в виде 4

2. Извините, я не понял, что >> округляет числа с плавающей запятой. Это исправлено и теперь дает правильный ответ.