переинтерпретировать int32 для плавания - PullRequest
0 голосов
/ 28 мая 2018

Мне нужно сохранить значение с плавающей запятой, которое является скопированной памятью, из целочисленного значения.В функции reinterpretedFloat я сделал примерное целое число и скопировал память в переменную типа float.Дело в том, что значение изменяется, когда значение с плавающей запятой memcpy возвращает .

Вот пример кода.

#include <stdio.h>
#include <stdint.h>

void printHex(const unsigned char* buff, int count)
{
    printf("0X");
    for (int i = 0; i < count; ++i)
    {
        printf("\t%X", buff[i]);
    }
    printf("\n");
}

float reinterpretedFloat()
{
    int32_t value = 0x7F845E58;
    float tmp;
    memcpy(&tmp, &value, sizeof(float));
    printHex(reinterpret_cast<const unsigned char*>(&tmp), 4); //memcpy
    return tmp;
}

int main()
{
    float newFloat = reinterpretedFloat();
    printHex(reinterpret_cast<const unsigned char*>(&newFloat), 4); //returned value

    return 0;
}

Это результат.

0X      58      5E      84      7F(memcpy)
0X      58      5E      C4      7F(returned value)

То, что я ожидал, было 0X 58 5E 84 7F ...

Любое тело может объяснить, почему это происходит?В конфигурации x64 этого не происходит.

1 Ответ

0 голосов
/ 28 мая 2018

0x7f845e58 - это сигнализация NaN .Он нормализуется до 0x7fc45e58, который является тихим NaN с той же полезной нагрузкой.

Разница между x86-64 и 32-битными x86-результатами заключается в том, что в первом режиме возвращается значение float из *Функция 1006 *, инструкция MOVSS из расширения SSE ISA загружает значение в регистр xmm0 без каких-либо преобразований, в то время как для последнего используется FLD dword [...], который преобразует из 32-битного float в x87 внутренний 80-битный long double формат, нормализующий состояние сигнализации до тихого *.

Различие в механизме связано с тем, что архитектура x86-64 гарантирует поддержкудля SSE, поэтому ABI использует его, в то время как i386 ABI не требует его, поскольку не все процессоры x86 поддерживают его.

* Технически преобразование вызывает исключение Invalid Operation, но, поскольку оно маскируется(по умолчанию), вы получите нормализованный результат удаления статуса сигнализации из NaN

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