2010-11-04 38 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 

tôi đang bắt đầu với động cơ vật lý Chipmunk và thấy điều này trong một tập tin headerMã này làm gì?

INFINITY được sử dụng để thiết lập đà vô hạn cho các đối tượng, tuy nhiên tôi không hiểu những gì mã này ở trên không!

Trả lời

6

Mã ở trên xác định có hiệu quả hằng số dấu phẩy động với một số biểu diễn byte rất cụ thể.

Mỗi float được thể hiện với một bộ các byte, nhưng khi bạn xác định float hằng bạn buộc phải sử dụng đại diện thập phân và không thể xác định một hằng số có giá trị nói 0xFFFFFFFF (Tôi không biết nếu thường xuyên đó là một hợp pháp float số).

Đoạn mã trên vượt qua giới hạn đó - trước tiên nó đặt một mảng byte bên trong liên kết và sau đó "truy cập" cùng một mảng byte như thể đó là số float. Điều này bằng cách này là bất hợp pháp - chỉ có các thành viên công đoàn trước đó thiết lập có thể được truy cập hợp pháp, nhưng nó có thể làm việc trên thực hiện cụ thể.

15

Nó đặt INFINITY thành giá trị nổi được biểu thị bằng các bit hex 0x7f800000, là +INF. Visual Studio không xác định INFINITY vì một lý do nào đó.

+0

Ngoài ra, nó được khai báo theo thứ tự ngược {0x00, 0x00, 0x80, 0x7F} vì x86 sử dụng số ít nhỏ. – jfs

+2

Đó có phải là '+/- INF' trong câu trả lời của bạn không?Bởi vì tôi khá chắc chắn rằng mô hình bit chỉ là '+ Inf' :-) – paxdiablo

+0

Đừng bận tâm, tôi sẽ tự khắc phục nó. Tôi không thể chấp nhận một câu trả lời sai có quá nhiều phiếu bầu :-) – paxdiablo

1

Đó là cách khởi tạo bộ nhớ bị chiếm bởi biến nổi tới 0x7f800000. Như @Jim nói, đây là + vô cực trong phao.

Mã này tương đương với:

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

Đầu tiên mã gốc xác định một liên minh cho phép bạn thao tác bốn byte của bộ nhớ như là một mảng bốn byte, hoặc như một phao duy nhất (mà chúng tôi giả cũng chiếm bốn byte):

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

Sau đó, nó phân bổ một thể hiện của sự kết hợp tên INFINITY_HACK và thiết lập các giá trị của mảng Bytes của nó với các giá trị hex quy định .:

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

Điều này có tác dụng khởi tạo trường Giá trị nổi bởi vì nó cũng chiếm cùng bộ nhớ với mảng byte.

Cuối cùng, nó xác định hằng số proprocessor có tên là INFINITY làm giá trị float.

2

Nó tạo INFINITY_HACK biến, thuộc loại MSVC_EVIL_FLOAT_HACK. nó đặt mảng Bytes để có giá trị của các giá trị hex tương ứng. Sau đó nó chuyển đổi các byte đó thành một số dấu phẩy động (công đoàn chỉ cho phép bạn sử dụng một trong các giá trị cơ bản bên trong vì vậy bằng cách tham chiếu .value nó chuyển đổi dữ liệu INIFITY_HACK trỏ tới, để làm nổi) bằng cách theo sau IEEE-754 Floating-Point Standard (lưu ý rằng byte được lấy ngược lại) để chuyển đổi nhị phân-> float. Có một máy tính nhỏ gọn có thể giải thích nếu bạn không biết cách hoạt động: http://babbage.cs.qc.cuny.edu/IEEE-754/32bit.html (nếu bạn nhập 7F800000, bạn sẽ nhận được Infinity, nhưng hãy thử nhập 4048F5C2 (bạn sẽ nhận được gần 3,14) This calculator đi decimal-> hex.