Распечатка внутреннего шестнадцатеричного числа с плавающей точкой - PullRequest
0 голосов
/ 26 апреля 2018

Итак, я подумал, что могу напечатать внутренний гекс float так:

const auto foo = 13.0F;
const auto bar = reinterpret_cast<const unsigned char*>(&foo);

printf("0x%02hhX%02hhX%02hhX%02hhX\n", bar[0], bar[1], bar[2], bar[3]);

Это выводит:

0x00005041

Но когда я смотрю на отладчик, гекс, для которого он сообщает foo, выглядит так:

0x003EF830

Может кто-нибудь помочь мне понять, почему это не сработало и что мне нужно сделать, чтобы это сработало?

Ответы [ 2 ]

0 голосов
/ 26 апреля 2018

Ты почти понял. Я не уверен, что выводит на экран отладчик, но это не ваш код. Может это адрес?

Фактическое значение с плавающей запятой составляет 0x41500000. Вы можете проверить это здесь: IEEE-754 преобразователь с плавающей запятой . Если ссылка не работает, вам придется самостоятельно найти онлайн анализатор / описание с плавающей запятой.

Вы сделали это правильно, но вы забыли, что процессоры Intel x86 (я полагаю, ваш процессор Intel x86) little-endian . Это означает, что старшие байты значимости находятся на старших адресах памяти. Таким образом, вы должны распечатать байты в обратном порядке, чем вы печатаете их, например:

printf("0x%02hhX%02hhX%02hhX%02hhX\n", bar[3], bar[2], bar[1], bar[0]);
0 голосов
/ 26 апреля 2018

Шестнадцатеричное значение для значения с плавающей запятой 13.0f:

0x41500000

Подтверждение:

Взять 0x41500000 в двоичном виде:

0100,0001,0101,0000,0000,0000,0000,0000

, который разделен на 1-битный знак, 8-битную экспоненту и 23-битную мантиссу:

0 : 10000010 : 10100000000000000000000

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

-1^s x 1.<mantissa> x 2^(exponent-127)

в

(-1)^0 x 1.101 x 2^(10000010-1111111)

, что

1.101b x (10b)^11b

, что

1.625 x 8

что составляет

13.0f

Что означает, что ваш вывод правильный (при условии, что используется формат с прямым порядком байтов)

Как вы читаете это в отладчике неверно

...