为什么有人会在C中使用这种类型的演员?float的引用被强制转换为int指针,然后解除引用

use*_*507 9 c pointers casting

我正在阅读Carmack的快速反平方根算法,并注意到这一点:

float x;
// ... //
int i = *(int*)&x;
Run Code Online (Sandbox Code Playgroud)

为什么有人会选择使用这种奇怪的铸造而不仅仅是以下?

int i = (int)x;
Run Code Online (Sandbox Code Playgroud)

ara*_*aer 28

那不一样.

int i = (int) x;将转换floatint,这将简单地截断它.

int i = *(int *) &x;将加载到i当前存储的相同位x.结果与截断完全不同x.

  • 一个小细节:`(int)x`将截断,而不是圆. (21认同)
  • 操作浮点的位表示就好像它是一个int是算法背后的整个想法.它以巧妙的方式利用位格式进行计算. (13认同)
  • 这就是我的想法. (10认同)
  • 是的,这就是主意.我很好奇,因为它似乎是一个非常无用的想法,除非你已经知道特征/尾数浮动格式,但https://en.wikipedia.org/wiki/Fast_inverse_square_root解释了这一点. (2认同)

Lea*_*ros 15

它被称为类型双关语.它会将其解释floatint.意思是,位表示被完全复制.

这是一个潜在危险的操作,因为浮点整数的某些位表示可能是陷阱表示为整数(不是IEEE-754浮点数和2s补码整数的情况).

此外,由于根据C标准的未定义行为,它可能不再起作用.它违反了严格的别名规则.

C仅支持通过访问不同类型的变量memcpy.

这是编写操作的有效标准C方式:

int y; float x = 42.0f;
memcpy(&y, &x, sizeof(x));
Run Code Online (Sandbox Code Playgroud)

C99通过使用以下方法添加了另一种方法union:

union { int y; float x; } u = { .x = 42.0f };
int y = u.y;
Run Code Online (Sandbox Code Playgroud)