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

时间:2021-01-04 21:16:45

I was reading about Carmack's fast inverse square root algorithm and noticed this:

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

float x;
// ... //
int i = *(int*)&x;

Why would someone choose to use this weird type of casting instead of just the following?

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

int i = (int)x;

2 个解决方案

#1


28  

That's different.

int i = (int) x; will cast float to int, which will simply truncate it.

int i =(int)x;将float转换为int,这将简单地截断它。

int i = *(int *) &x; will load into i the same bits that are currently stored in x. The result is something totally different from truncating x.

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

#2


15  

It's called type punning. It'll interpret the float as an int. Meaning, the bit representation is exactly copied.

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

It's a potentially dangerous operation, since some bit representations of floating point integers might be trap representations as integers (not the case with IEEE-754 floats and 2s complement integers, though).

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

Additionally, it might not work anymore, due to being undefined behaviour as per C standard. It's violating the strict aliasing rule.

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

C only supports accessing variable of a different type via memcpy.

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

This is the valid standard C way of writing the operation:

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

int y; float x = 42.0f;
memcpy(&y, &x, sizeof(x));

C99 added another way of doing this, by using a union:

C99通过使用union来添加另一种方法:

union { int y; float x; } u = { .x = 42.0f };
int y = u.y;

#1


28  

That's different.

int i = (int) x; will cast float to int, which will simply truncate it.

int i =(int)x;将float转换为int,这将简单地截断它。

int i = *(int *) &x; will load into i the same bits that are currently stored in x. The result is something totally different from truncating x.

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

#2


15  

It's called type punning. It'll interpret the float as an int. Meaning, the bit representation is exactly copied.

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

It's a potentially dangerous operation, since some bit representations of floating point integers might be trap representations as integers (not the case with IEEE-754 floats and 2s complement integers, though).

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

Additionally, it might not work anymore, due to being undefined behaviour as per C standard. It's violating the strict aliasing rule.

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

C only supports accessing variable of a different type via memcpy.

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

This is the valid standard C way of writing the operation:

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

int y; float x = 42.0f;
memcpy(&y, &x, sizeof(x));

C99 added another way of doing this, by using a union:

C99通过使用union来添加另一种方法:

union { int y; float x; } u = { .x = 42.0f };
int y = u.y;