2010-11-04 181 views
7
#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 

我目前入门与花栗鼠物理引擎,发现这头文件这段代码做了什么?

INFINITY用于设置无限动能的对象,但我不明白上面这段代码!

回答

6

上面的代码有效地定义了一些具有特定字节表示的浮点常量。

float表示一组字节,但是一旦你定义float常量你不得不使用十进制表示,并不能定义与价值恒定说0xFFFFFFFF(我不知道这是否常量是一个法律float号码)。

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

15

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

+0

此外,它是以相反的顺序声明{0x00,0x00,0x80,0x7F},因为x86使用little-endian。 – jfs 2010-11-04 10:35:34

+2

在你的答案中是“+/- INF”吗?因为我很确定位模式只是'+ Inf' :-) – paxdiablo 2010-11-04 10:37:30

+0

没关系,我会自己修复它。我不能忍受有这么多票的错误答案:-) – paxdiablo 2010-11-04 10:59:41

1

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

的代码是大致等效于:

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

首先,原始代码定义的联合,允许你操纵四个字节的存储器化为或者是四个字节的阵列,或者作为单个浮子(我们假设也占4个字节):

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}}; 

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

最后它定义了一个名为INFINITY的协处理器常量作为float值。

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去十进制 - >十六进制