Точное текстовое представление IEEE «Double»
-
21-09-2019 - |
Вопрос
Мне нужно представить двойное (64-разрядное) плавающее число IEEE 754–1985 в яблочко то же самое (битовое) число.
Возможно ли это сделать, не просто печатать сырые байты? Если да, код для этого будет очень ценится.
Решение
Лучший вариант: используйте шестнадцатеричную формат шестнадцатеричного плавания 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 Значительные цифры. Если у вас есть правильная закругленная процедура преобразования (большинство - не все - платформы делают), это гарантирует, что вы сможете совершить поездку из двойного до строки и обратно без какой -либо потери точности.
Другие советы
Похоже, ты хочешь Алгоритм Бургера (PDF):
В режиме свободного формата алгоритм генерирует кратчайшую правильно закругленную выходную строку, которая преобразуется в одно и то же число при чтении обратно, независимо от того, как читатель разрывает галстуки при округлении.
Пример исходного кода (в C и схеме) также доступен.
Это алгоритм, используемый в Python 3.x для обеспечения float
S может быть преобразован в строки и обратно без какой -либо потери точности. В Python 2.x, float
S всегда были представлены с 17 значимыми цифрами, потому что:
repr(float)
производит 17 значительных цифр, потому что оказалось, что этого достаточно (на большинстве машин), чтобы это былоeval(repr(x)) == x
именно для всех конечных поплавокx
, но округление до 16 цифр недостаточно, чтобы сделать это правдой. (Источник: http://docs.python.org/tutorial/flotingpoint.html)
Для этого есть формат .NET Framework:
string formatted = myDouble.ToString("r");
Из документации:
Спецификатор обработки гарантирует, что числовое значение, преобразованное в строку, будет проанализировано обратно в то же числовое значение. Когда числовое значение отформатируется с использованием этого спецификатора, оно сначала протестируется с использованием общего формата, с 15 местами точности для двойного и 7 мест точности для одного. Если значение успешно проанализировано обратно к тому же числовому значению, оно отформатируется с использованием спецификатора общего формата. Однако, если значение не успешно проанализируется обратно к тому же числовому значению, то значение отформатируется с использованием 17 цифр точности для двойной и 9 цифр точности для одного.
Этот метод, конечно, может быть воссоздан на большинстве языков.
Да, это можно сделать, хотя реализация зависит от языка. Основная идея состоит в том, чтобы просто распечатать ее с достаточной точностью.
Обратите внимание, что обратное нет Верно, хотя: некоторые цифры, которые могут быть представлены именно в десятичном виде, просто не могут быть представлены в двоичном языке.