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