[英]Conversion of float to integer in ARM based system
我有以下一段名为main.cpp
的代码,它将 IEE 754 32 位十六进制值转换为浮点数,然后将其转换为无符号短整型。
#include <iostream>
using namespace std;
int main() {
unsigned int input_val = 0xc5dac022;
float f;
*((int*) &f) = input_val;
unsigned short val = (unsigned short) f;
cout <<"Val = 0x" << std::hex << val << endl;
}
我使用以下命令构建并运行代码:
g++ main.cpp -o main
./main
当我在我的普通 PC 上执行代码时,我得到正确的答案,即0xe4a8
。 但是当我在 ARM 处理器上运行相同的代码时,它会给出0x0
的输出。
发生这种情况是因为我正在使用普通 gcc 而不是 aarch64 构建代码吗? 该代码为 ARM 处理器上的其他一些测试用例提供了正确的输出,但为给定的测试值提供了不正确的输出。 我该如何解决这个问题?
首先,如评论中所述,您通过指针的“类型双关语”违反了严格的别名规则。 您可以通过切换到memcpy
来解决这个问题。
接下来,如果我的测试是正确的,作为 IEEE-754 单精度float
的位模式0xc5dac022
对应于大约 -7000 的值。 这被截断为 -7000,它是负数,不能用unsigned short
表示。 因此,根据 C++ 标准 (C++20 N4860) 中的 [7.3.10 p1],尝试将其转换为unsigned short
具有未定义的行为。 请注意,这与尝试将有符号或无符号整数转换为unsigned short
的情况不同,后者具有明确定义的“包装”行为。
所以这里没有“正确答案”。 打印 0 是一个完全合法的结果,并且在某种意义上也是合乎逻辑的,因为 0 是最接近 -7000 的unsigned short
值。 但是,平台/编译器/优化选项之间的结果会有所不同也就不足为奇了,因为这对于 UB 来说很常见。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.