Несоответствие плавающего представления - PullRequest
0 голосов
/ 08 июня 2018

В этом SO-ответе пользователь предоставил эту короткую функцию, которая возвращает двоичное представление значения с плавающей запятой:

import struct
import sys

def float_to_bin(f):
    """ Convert a float into a binary string. """
    if sys.version_info >= (3,):  # Python 3?
        ba = struct.pack('>d', f)
    else:
        ba = bytearray(struct.pack('>d', f)) # Convert str result.

    s = ''.join('{:08b}'.format(b) for b in ba)
    return s[:-1].lstrip('0') + s[0] # Strip but one leading zero.

Когда я вызываю эту функцию со значением 7/3-4/3 (в Python 3.5), или с 1.0000000000000002, я получаю это двоичное представление:

11111111110000000000000000000000000000000000000000000000000000

Используя этот онлайн-инструмент , с теми же значениямиЯ получаю это двоичное представление:

11111111110000000000000000000000000000000000000000000000000001

  • Почему существует разница между этими двумя представлениями?
  • Почему float_to_bin возвращает плавающее представление 1.0 для 1.0000000000000002?
  • Есть ли какие-то потери точности в float_to_bin, вызванные где-то (возможно, при вызове struct.pack)?

1 Ответ

0 голосов
/ 08 июня 2018

Логика в этой функции для «обрезки, но одного начального нуля» полностью неверна и удаляет значащие цифры из результата.

Правильное представление значения равно или иззначения, указанные в вашем вопросе;это:

0011111111110000000000000000000000000000000000000000000000000001

, который можно получить, заменив последнюю строку этой функции на:

return s

или используя более простую реализацию:

def float_to_bin(f):
    [d] = struct.unpack(">Q", struct.pack(">d", f))
    return '{:064b}'.format(d)

Начальные и конечные нули в значениях с плавающей запятой имеют большое значение и не могут быть удалены без изменения значения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...