求浮点数绝对值的算法在这里。这是如何运作的?
//find absolute value
double x;
*(((int *) &x) + 1) &= 0x7fffffff;
我不明白为什么 1 的偏移量是必要的。它说:
IA32 64 位符号位为 0x80000000,int 地址偏移量为 +1。
有人可以分解并解释吗?
求浮点数绝对值的算法在这里。这是如何运作的?
//find absolute value
double x;
*(((int *) &x) + 1) &= 0x7fffffff;
我不明白为什么 1 的偏移量是必要的。它说:
IA32 64 位符号位为 0x80000000,int 地址偏移量为 +1。
有人可以分解并解释吗?
该代码在技术上是无效的 C,因为它违反了严格的别名规则。但是,如果您告诉编译器不要滥用别名规则,并且可以保证double
s 和int
s 像在 x86 上一样在内存中布局:
(int *)&x
是指向 的指针x
。加 1 将指针向前移动 4 个字节。取消引用它会为您提供double
. 你屏蔽掉它的高位,因为那是double
.
顺便说一句,您可以通过使用 a 并添加 7 而不是 1 来阻止这种混叠违规char *
。它仍然非常不可移植。
Adouble
为 8 字节宽,格式如下:
您显示的代码假定它int
是 4 个字节宽,并且两者int
都是double
小端序(意味着 0-7 位存储在字节 0 中,8-15 位存储在字节 1 中,依此类推)。
Ifx
是指向的指针double
:
*(((int *) &x) + 0) addresses bits 0 through 31;
*(((int *) &x) + 1) addresses bits 32 through 63.
因此,*(((int *) &x) + 1) &= 0x7fffffff
将第 63 位设置为零,更改x
为其绝对值。
这是高度依赖于平台的。
无论如何,您有一个双精度位,其中最高位是符号位。
如果您的 double 有 8 个字节,而您的 int 有 4 个字节,并且您在 LE 系统上,则最高位是最后一个字节或第二个整数的最高位。
所以你取第二个整数(你也可以写((int *)&x)[1] &= 0x7fffffff
)并清除它的最高位。