c++ - 十六进制到 float IEEE 754 double c++

标签 c++ hex

我正在尝试在 C++ 中使用 IEEE 754 double 从十六进制转换为 float64。 这是我第一次玩位,所以可能我的代码不够干净。 我不知道为什么我的尾数会给我奇怪的结果,但我认为我做错了什么。

long int raw = 0x40000F0000000001;
int sign = raw >> 63;
long int mantissa = (raw & 0xFFFFFFFFFFFFF);
mantissa +=1;
double exp = ((raw >> 52) & 0x7FF) - 1023;
double result = pow(-1., sign) * mantissa * pow(2.0, exp);
cout << "MANTISSA: " << mantissa << " EXP: " << exp << endl;
cout << "RESULT: " << result << endl;

输出是:

MANTISSA: 16492674416642 EXP: 1
RESULT: 3.29853e+13

有人知道怎么做吗?

谢谢

最佳答案

long int raw = 0x40000F0000000001;

是否long是实现指定的足够长以容纳这么多位(通常在 Windows 上不是,在 Linux 上如果你编译 64 位程序而不是 32 位程序。)

int sign = raw >> 63;

如果设置了符号位,则此行具有实现定义的行为。 (合理的结果是 1 和 -1,但没有什么可以阻止指定“42”的实现。)你最好定义 raw作为uint64_t

long int mantissa = (raw & 0xFFFFFFFFFFFFF);
mantissa +=1;

这是你的问题。丢失的“1”位在所有位的前面。您需要添加 0x1000000000000(或者更好,定义一个常量 const uint64_t MantissaOffset = 1uLL << 52; 和另一个 const uint64_t MantissaMask = MantissaOffset-1; - 这样您就不必计算所有这些 F s 和 0 s。)

然后您将得到一个太大的 2**52 尾数(因此您需要在计算指数时考虑到这一点。

double exp = ((raw >> 52) & 0x7FF) - 1023;
double result = pow(-1., sign) * mantissa * pow(2.0, exp);

...当然,这不考虑非规范化、NAN 和 INF。

cout << "MANTISSA: " << mantissa << " EXP: " << exp << endl;
cout << "RESULT: " << result << endl;

关于c++ - 十六进制到 float IEEE 754 double c++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45567479/

相关文章:

从二进制文件的十六进制表示创建二进制文件的副本

c++ - 在远程进程中隐藏控制台窗口

c++ - 图像写入功能未执行

使用 Stringstream 的 C++ Hex 到 Int

c - C语言中如何交换十六进制数?

c - 使用 C 程序解析 MIDI 文件时出现问题

c++ - 处理内存,垃圾收集器之类的

c++ - 如何创建n维测试数据进行聚类分析?

c++ - 我可以通过 reinterpret_cast 将 int 的空指针转换为 long 类型吗

perl - 二进制sed替换