2010-11-04 159 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去十進制 - >十六進制