这段代码有什么作用?

时间:2010-11-04 10:20:04

标签: c++

#ifndef INFINITY
#ifdef _MSC_VER
    union MSVC_EVIL_FLOAT_HACK
    {
        unsigned __int8 Bytes[4];
        float Value;
    };
    static union MSVC_EVIL_FLOAT_HACK INFINITY_HACK = {{0x00, 0x00, 0x80, 0x7F}};
    #define INFINITY (INFINITY_HACK.Value)
#endif

我目前正在开始使用Chipmunk物理引擎并在头文件中找到它

INFINITY用于为对象设置无限动量,但我不明白上面的代码是做什么的!

4 个答案:

答案 0 :(得分:15)

它将INFINITY设置为由十六进制位0x7f800000表示的浮点值,即+INF。 Visual Studio由于某种原因未定义INFINITY。

答案 1 :(得分:6)

上面的代码有效地定义了一个浮点常量,其中包含一些非常特定的字节表示。

每个float都用一组字节表示,但是当你定义float个常量时,你被迫使用十进制表示而不能定义一个值为0xFFFFFFFF的常量(我不知道该常数是否是合法的float数字。)

上面的代码绕过了这个限制 - 它首先在union中设置一个字节数组,然后“访问”相同的字节数组,就好像它是float个数字一样。顺便说一句,这是非法的 - 只有先前设置的工会成员可以合法访问,但它可能适用于该特定实现。

答案 2 :(得分:2)

它创建一个类型为MSVC_EVIL_FLOAT_HACK的变量INFINITY_HACK。它将Bytes数组设置为具有相应十六进制值的值。然后,它将这些字节转换为浮点数(union只允许您使用其中一个基础值,通过引用.value将INIFITY_HACK指向的数据转换为浮点数),方法是遵循IEEE-754 Floating-Point Standard (注意,字节是反向的)用于二进制 - >浮点转换。

如果你不知道它是如何工作的,有一个很好的小计算器可以解释它: http://babbage.cs.qc.cuny.edu/IEEE-754/32bit.html(如果您输入7F800000,您将获得无限,但尝试输入4048F5C2(您将接近3.14)This calculator将进入十进制 - >十六进制。

答案 3 :(得分:1)

它是一种将float变量占用的内存初始化为0x7f800000的方法。正如@Jim所说,这是浮点数中的+无穷大。

代码大致相当于:

byte Bytes[4] = { 0x00, 0x00, 0x80, 0x7F };
float Value;
memcpy(&Value, Bytes, 4);
#define INFINITY_HACK (Value)

首先,原始代码定义了一个联合,它允许您将四个字节的内存操作为四个字节的数组,或者作为一个浮点数(我们假设它也占用四个字节):

union MSVC_EVIL_FLOAT_HACK
    {
        unsigned __int8 Bytes[4];
        float Value;
    };

然后它分配名为INFINITY_HACK的联合的实例,并将其Bytes数组的值设置为指定的十六进制值。:

static union MSVC_EVIL_FLOAT_HACK INFINITY_HACK = {{0x00, 0x00, 0x80, 0x7F}};

这具有初始化浮点值字段的效果,因为它也占用与字节数组相同的内存。

最后,它将名为INFINITY的预处理器常量定义为浮点值。