开发者

What does this code do: static union MSVC_EVIL_FLOAT_HACK INFINITY_HACK = {{0x00, 0x00, 0x80, 0x7F}};

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

I'm currently getting started with the Chipmunk physics engine and found this in a header file

INFINITY is used to set infinite momentum for objects, however I don't understand what this code above does!


It sets INFINITY to the float value represented by the hex bits 0x7f800000, which is +INF. Visual Studio doesn't define INFINITY for some reason.


The code above effectively defines a floating-point constant with some very specific bytes representation.

Every float is represented with a set of bytes, but when you define float constants you're forced to use decimal representation and can't define a constant with value say 0xFFFFFFFF (I don't know if that constant is a legal float number).

The code above bypasses that limitation - it first sets a byte array inside the union and then "accesses" the same byte array as if it was a float number. This by the way is illegal - only the union member previously set can be legally accessed, but it might work on that specific implementation.


It create a variable INFINITY_HACK, of type MSVC_EVIL_FLOAT_HACK. it sets the Bytes array to have values of the respective hex values. It then converts those bytes to a floating-point number (union only allows you to use one of the underlying values within so by referencing .value it is converting the data that INIFITY_HACK points to, to float) by following the IEEE-754 Floating-Point Standard (note that the bytes are taken in reverse) for binary->float conversion.

There's a nice little calculator that can explain it if you don't know how it works: http://babbage.cs.qc.cuny.edu/IEEE-754/32bit.html (if you enter 7F800000, you'll get Infinity, but try entering 4048F5C2 (you'll get close to 3.14) This calculator goes decimal->hex.


Its a way to initialise the memory occupied by a float variable to 0x7f800000. As @Jim says, this is +infinity in the float.

The code is roughly equivalent to:

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

First the original code defines a union that allows you to manipulate four bytes of memory as either an array of four bytes, or as a single float (which we assume also occupies four bytes):

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

Then it allocates an instance of the union named INFINITY_HACK and sets the values of its Bytes array to the hex values specified.:

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

This has the effect of initialising the float Value field because it also occupies the same memory as the byte array.

Finally it defines a proprocessor constant named INFINITY as the float value.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜