重新解释从float到int的转换

ire*_*zwi -3 c++

float f = 12.5;
unsigned int _f = *reinterpret_cast<int*>(&f);
std::cout << _f << std::endl; // result: 1095237632
Run Code Online (Sandbox Code Playgroud)

有人可以解释一下这种铸造的原理吗?代表_f什么?

编辑 所以我1095237632转换为二进制后得到的这个数字是0b1000001010010000000000000000000,这个二进制数字是12.5在IEEE-754中。我说对了吗?

for*_*818 6

没有人可以解释(*),因为它不起作用。

来自cppreference

与static_cast不同,但与const_cast不同,reinterpret_cast表达式不会编译为任何CPU指令(在整数和指针之间进行转换时,或者在指针表示形式取决于其类型的晦涩架构上除外)。它纯粹是一个编译时指令,它指示编译器将表达式视为具有new_type类型。

使用reinterpret_cast只能进行以下转换,除非这种转换会消除常量性或易变性。

然后遵循一系列规则,涵盖允许重新解释强制类型转换的内容。将类型A转换为完全不相关的类型B不在其中,并且您的代码表现出不确定的行为。

(*)严格来说是不正确的。您将float视为一个int,如果您查看它们在硬件上的表示形式,并且检查编译器的输出,则可以弄清楚为什么获得值,尽管未定义行为是未定义的,因此不值得输入详细信息除非您愿意编写不可移植的代码。


J. *_*rez 6

我们来看两个函数。其中之一定期将 float 转换为 int ,其中之一使用 reinterpret_cast 重新解释它:

int cast_to_int(float f) {
    // Rounds f to an int, rounding towards 0
    return (int)f; 
}
int reinterpret_cast_to_int(float i) {
    // Just copies the bits
    return *reinterpret_cast<int*>(&i); 
}
Run Code Online (Sandbox Code Playgroud)

那么到底发生了什么?我们来看看装配图:

cast_to_int(float):
    cvttss2si       eax, xmm0   // We cast to an int
    ret
reinterpret_cast_to_int(float):
    movd    eax, xmm0           // We directly copy the bits
    ret
Run Code Online (Sandbox Code Playgroud)

在第一种情况下,有一条执行转换的汇编指令:

cast_to_int(0.7) -> 0
cast_to_int(1.0) -> 1
cast_to_int(1.5) -> 1
cast_to_int(2.1) -> 2
Run Code Online (Sandbox Code Playgroud)

在第二种情况下,reinterpret_cast只是直接转换位的底层表示。它实际上没有做任何事情,该函数只是将输入寄存器复制到输出寄存器。

在幕后,floats 的位表示与ints 非常不同,这就是为什么你会得到奇怪的数字。