Преобразование числа из ячейки Excel в шестнадцатеричный формат IEEE 754 - PullRequest
2 голосов
/ 02 августа 2020

Недавно я боролся с Excel из-за ограничения отображения 15 значащих цифр для числа. Я искал способ отобразить формат IEEE 754 значения, содержащегося в ячейке Excel (, поскольку они задокументированы , чтобы работать таким образом ).

Я бы предпочел не полагаться на VBA в этом проекте ( хотя я могу испытать соблазн, если возможно memcpy -подобное решение ).

См. Мои ответ ниже для моей текущей реализации. Любой ввод или альтернатива приветствуются. Я предпочитаю верить, что пропустил более простое, хорошо проверенное решение.

1 Ответ

2 голосов
/ 02 августа 2020

Следующая последовательность позволяет мне преобразовать число в его шестнадцатеричное представление IEEE 754, используя формулы Excel. Я не пытался обрабатывать какие-либо исключения, кроме 0. От ячейки A1 до G1:

  • A1: 0.123456

  • B1: =INT(LOG(ABS(A1);2)) Экспонента

  • C1: =ABS(A1)/(2^B1) Мантисса

  • D1: =(C1-1)*(2^52) Преобразование мантиссы в десятичное

  • E1: =DEC2HEX(1023+B1+IF(A1<0;2^11;0)) Преобразование знака и экспоненты в шестнадцатеричное

  • F1: =CONCATENATE(DEC2HEX(D1/2^32;5);DEC2HEX(MOD(D1;2^32);8)) Преобразование десятичного числа в шестнадцатеричное.

  • G1: ="0x"&IF(A1=0;0;E1&F1)

Некоторые из моих результатов:

  • 22222.0948199999> 0x40D5B3861187E7A5
  • =1.35632902954101*2^14> 0x40D5B3861187E7A7
  • 22222,09482 > 0x40D5B3861187E7C0
  • 0,000123456> 0x3F202E7EF70994DD
  • 1E + 307> 0x7FAC7B1F3CAC7433
  • -3560000 *1054* *1055* -3580000 *1054* 1055 * -3580000 * 0 *

EDIT : продолжение комментариев chux.

Мы видим, что следующее значение дает неверный результат из-за ошибки округления :

  • =255+0,9999999999999> 0x40700000FFFFFFFE * 10 71 *

В этом сценарии значение, указанное на шаге D1, отрицательно. Если я использую эту информацию для обновления своей экспоненты, мои результаты будут согласованными:

  • =255+0,9999999999999> 0x406FFFFFFFFFFFF C

Вот обновленная формула B1:

  • B1: =IF((ABS(A1)/(2^INT(LOG(ABS(A1);2)))-1)*(2^52)<0;INT(LOG(ABS(A1);2))-1;INT(LOG(ABS(A1);2)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...