Câu lệnh *(long *) có ý nghĩa gì?

Việc là em đang tìm hiểu về thuật toán quake 3 để tính căn bậc 2 mà tìm mãi vẫn không hiểu câu lệnh *(void *) có nghĩa gì ? nên xin nhờ các cao nhân giúp đỡ :>
Capture

Ghi rõ ở phần chú thích rồi đấy.

// evil floating point bit level hacking

“Ép kiểu” các ô nhớ về kiểu long để thao tác bit thô (raw bit) với kiểu dấu chấm (phẩy) động.
Trước hiết bạn phải hiểu kiểu dấu chấm động (floatdouble) lưu trọng bộ nhớ theo cách nào. https://vi.wikipedia.org/wiki/Số_thực_dấu_phẩy_động
Dòng bạn thắc mắc có thể giải thích như sau:

// Gốc
float f = ...
long l = *(long*)&f;

// Tường minh
float f = ...         // gán giá trị cho 1 biến float
float* fp = &f;       // lấy địa chỉ của biến float cho con trỏ (float*)
long* lp = (long*)fp; // ép kiểu con trỏ từ float* về kiểu long*
long l = *lp;         // lấy giá trị tại con trỏ.

Dòng phía dưới (*(float*)) thì tương tự, nhưng ép ngược về kiêu float.

Bit hacking: dùng các toán tử cấp thấp (toán tử bit) để thực hiện các phép tính phức tạp.

5 Likes

dùng để copy từng bit từng bit một của 1 biến float sang 1 biến long khác ấy :V Gọi là type-punning.

trong cả C lẫn C++ thì câu lệnh này là undefined behavior (UB) nha :V Trong wiki có sửa lại xài “union cast” nè https://en.wikipedia.org/wiki/Fast_inverse_square_root

According to the C standard, reinterpreting a floating point value as an integer by removing the pointer to it is considered to be able to cause unexpected behavior (undefined behavior). This problem could be circumvented using the library function memcpy

lưu ý trong C++ thì union cast lại là UB :V nên wiki xài std::bit_cast cho C++20. C++ cũ hơn thì xài memcpy nha :V

uint32_t i;
std::memcpy(&i, &number, sizeof(float)); // copy từng bit một từ number sang i
//...
std::memcpy(&number, &i, sizeof(float)); // copy từng bit một từ i sang number

xài memcpy thì cả C lẫn C++ đều đúng.

7 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?