2016-03-23 87 views
1

我正在寻找地震中使用的反转sqrt的示例代码。这是什么意思*(int *)&x当typecasting?

我看到float类型的变量:float x = 16;

并且然后int可变借此表达式的值:int i = *(int*)&a;

我理解(从右到左)的方式是,它需要的将变量a的地址类型化为一个整型指针,然后获取该指针的值并将其分配给i

当我在控制台输出变量i这是一个很大的整数值。 有人能解释一下这里发生了什么吗?

因为我预计变量i16

+1

此代码演示了由于严格的别名违反规则而导致的未定义行为,这可能是您需要了解的唯一一件事。 – SergeyA

回答

9

&a取地址为a,浮点数; (int *)保持相同的地址,但现在告诉编译器假装int存储在那里; int i = *然后从该地址加载int

所以你得到一个与float相同的位模式的整数。浮动和整数具有非常不同的编码,所以您最终会得到一个非常不同的值。

浮动可能会制定like this,但它不是必需的;你的架构可能会做别的。可能作者正在做一个特定于平台的优化版本frexp

int i = (int)x;将简单地将float转换为int,给你16

+1

我编辑过,以表明它可能是一个优化的尝试,以拉出尾数和/或指数。从浮点到整数的转换是昂贵的(相对而言,你知道),但假设你知道你的值总是在0到1的范围内,也就是说你已经知道指数,你可能想直接获取尾数作为位你的int。经典的例子是CPU上的图像处理:如果所有的颜色都以[0.0,1.0)中的数字开始,那么通常你的输出也是[0.0,1.0),但你需要发送整数字节到显卡。 – Tommy

+1

你没有提到的一件事是,由于违反严格的别名规则,代码是未定义的行为。 – SergeyA

+0

@SergeyA确实,我觉得完全没有资格做出合适的编辑。从C99开始,6.2.7定义了兼容类型,以便不包含int和float,并且6.5.16强制在指针分配中需要兼容的指向类型,但只能在混合中使用赋值运算符。我很难找到最终的链接,以显示在中间没有临时任务时适用相同的规则。所以我标记为社区维基。请先潜入 – Tommy