我正在尝试在 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/