4

求浮点数绝对值的算法在这里。这是如何运作的?

//find absolute value
double x;
*(((int *) &x) + 1) &= 0x7fffffff;

我不明白为什么 1 的偏移量是必要的。它说:

IA32 64 位符号位为 0x80000000,int 地址偏移量为 +1。

有人可以分解并解释吗?

4

3 回答 3

8

该代码在技术上是无效的 C,因为它违反了严格的别名规则。但是,如果您告诉编译器不要滥用别名规则,并且可以保证doubles 和ints 像在 x86 上一样在内存中布局:

(int *)&x是指向 的指针x。加 1 将指针向前移动 4 个字节。取消引用它会为您提供double. 你屏蔽掉它的高位,因为那是double.

顺便说一句,您可以通过使用 a 并添加 7 而不是 1 来阻止这种混叠违规char *。它仍然非常不可移植。

于 2013-08-20T05:33:07.673 回答
7

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为其绝对值。

于 2013-08-20T05:34:33.493 回答
1

这是高度依赖于平台的。

无论如何,您有一个双精度位,其中最高位是符号位。

如果您的 double 有 8 个字节,而您的 int 有 4 个字节,并且您在 LE 系统上,则最高位是最后一个字节或第二个整数的最高位。

所以你取第二个整数(你也可以写((int *)&x)[1] &= 0x7fffffff)并清除它的最高位。

于 2013-08-20T05:33:45.263 回答