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;