Точное текстовое представление IEEE “дважды”

Я должен представить IEEE 754-1985 дважды (64-разрядное) число с плавающей точкой в человекочитаемой текстовой форме с условием, что текстовая форма может быть проанализирована назад в точно то же (поразрядное) число.

Действительно ли это возможно/практично обойтись без просто печати необработанных байтов? Если бы да, код, чтобы сделать это очень ценилось бы.

6
задан Vladimir Panteleev 19 March 2010 в 21:48
поделиться

4 ответа

Лучший вариант: используйте шестнадцатеричный формат с плавающей запятой C99:

printf("%a", someDouble);

Созданные таким образом строки можно преобразовать обратно в double с помощью функции C99 strtod () , а также с помощью функции scanf () . Несколько других языков также поддерживают этот формат. Некоторые примеры:

decimal number    %a format     meaning
--------------------------------------------
2.0               0x1.0p1       1.0 * 2^1
0.75              0x1.8p-1      1.5 * 2^-1

Шестнадцатеричный формат имеет то преимущество, что все представления точны . Таким образом, преобразование строки обратно в число с плавающей запятой всегда будет давать исходное число, даже если кто-то изменит режим округления, в котором выполняется преобразование. Это неверно для неточных форматов.

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

12
ответ дан 8 December 2019 в 05:54
поделиться

В .NET framework для этого есть двусторонний формат:

string formatted = myDouble.ToString("r");

Из документации:

round- Спецификатор поездки гарантирует, что числовое значение , преобразованное в строку , будет преобразовано обратно в то же числовое значение . Когда числовое значение форматируется с использованием этого спецификатора, оно сначала тестируется с использованием общего формата с 15 точками точности для двойного и 7 пробелов. точности для Single. Если значение успешно преобразовано обратно в то же числовое значение, оно форматируется с использованием общего спецификатора формата . Однако, если значение не было успешно преобразовано обратно в то же числовое значение, тогда значение форматируется с использованием 17 цифр точности для Double и 9 цифр точности для Single.

Этот метод, конечно, можно воссоздать практически на любом языке.

3
ответ дан 8 December 2019 в 05:54
поделиться

Похоже, вы хотите Алгоритм Бургера (PDF):

В режиме свободного формата алгоритм генерирует {{1} } кратчайшая правильно округленная выходная строка, которая преобразуется в то же число при повторном считывании, независимо от того, как средство чтения разрывает связи при округлении.

Также доступен пример исходного кода (на C и схеме).

Это алгоритм, используемый в Python 3.x для обеспечения возможности преобразования чисел с плавающей запятой в строки и обратно без потери точности. В Python 2.x float s всегда были представлены 17 значащими цифрами, потому что:

repr (float) производит 17 значащих цифр, потому что оказывается, что этого достаточно (на большинстве машин), чтобы eval (repr (x)) == x точно для всех конечных чисел с плавающей запятой x , но округления до 16 цифр недостаточно, чтобы сделать это верным. (Источник: http://docs.python.org/tutorial/floatingpoint.html )

6
ответ дан 8 December 2019 в 05:54
поделиться

Да, это можно сделать, хотя реализация зависит от языка. Основная идея заключается в том, чтобы просто вывести его с достаточной точностью.

Обратите внимание, что обратное не верно: некоторые числа, которые могут быть точно представлены в десятичной системе счисления, просто не могут быть представлены в двоичной.

1
ответ дан 8 December 2019 в 05:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: