联盟和位屏蔽,这是如何工作的?

时间:2011-02-03 09:44:05

标签: c bit-manipulation unions

这里有一些C代码:

float phaseFrac(unsigned int inPhase)
{
    union { unsigned int itemp; float ftemp; } u;
    u.itemp = 0x3F800000 | (0x007FFF80 & ((inPhase)<<7));
    return u.ftemp - 1.f;
}

我不能在这里使用“联盟”。我是否正确地认为,由于uint和float都是32位,因此结合中的结果位模式被重新解释为浮点值?或者这里有其他魔法吗?

...谢谢

4 个答案:

答案 0 :(得分:3)

是的,这是正确的。联合就像一个结构,除了所有数据成员都重叠存储,所以如果你写一个类型的字段,然后读回一些其他类型的字段,它将重新解释第一种类型的位作为第二种类型的值类型。

这里的代码看起来很奇怪,因为联合是在函数内部定义的。通常,人们会在文件范围内声明一个联合,就像声明一个结构一样,但是这里因为目标是位错误而不是数据存储,所以它是在本地完成的。

答案 1 :(得分:1)

从技术上讲,它调用未定义的行为:访问联合的不同成员而不是最后修改的成员。但是,大多数C编译器都会按照您的想法进行操作,并将位模式解释为浮点数,而现在大多数人都使用IEEE格式浮点数。

答案 2 :(得分:0)

不,你是对的。 float和int是32位。我的猜测是,如果你试图将0x3F800000分配给一个浮点数,就像分配1065353216一样,它有一个完全不同的位配置保存为浮点数,这可以解释为什么需要int。

需要浮点数来获得一个特殊的效果,减去1,你不会因为同样的原因从int减去1。

答案 3 :(得分:0)

对于与您的问题类似的示例,这应该会有所帮助:

http://courses.missouristate.edu/KenVollmar/publications/CCSCWeb.doc