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 đỡ :>
Câu lệnh *(long *) có ý nghĩa gì?
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 (float
và double
) 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.
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.