Penukaran Float-to-Int Jenis-Punning: Menyelesaikan Isu-Isu Pengasingan Tegas dengan Memcpy
Dalam pengaturcaraan, type-punning merujuk kepada mengakses data satu jenis melalui rujukan kepada jenis yang berbeza. Walaupun mudah untuk pengoptimuman prestasi, tebukan taip boleh memperkenalkan pelanggaran alias ketat dalam penyusun yang dioptimumkan seperti GCC C .
Pertimbangkan kod di bawah, yang melakukan operasi punca kuasa dua songsang menggunakan penggodaman bit:
float InverseSquareRoot(float x) { float xhalf = 0.5f*x; int32_t i = *(int32_t*)&x; // Dereferencing type-punned pointer, breaking strict-aliasing rules i = 0x5f3759df - (i >> 1); x = *(float*)&i; x = x*(1.5f - xhalf*x*x); return x; }
Kod ini menjana amaran daripada GCC mengenai peraturan penyamaran yang ketat. Untuk menangani isu ini, kod harus diubah suai untuk mengelakkan mengakses objek apungan melalui nilai int32_t. Sebaliknya, memcpy() boleh digunakan untuk menyalin bait dengan selamat antara objek apungan dan int32_t.
float InverseSquareRoot(float x) { float xhalf = 0.5f*x; uint32_t i; assert(sizeof(x) == sizeof(i)); std::memcpy(&i, &x, sizeof(i)); // Use memcpy to safely copy bytes i = 0x5f375a86 - (i >> 1); std::memcpy(&x, &i, sizeof(i)); x = x*(1.5f - xhalf*x*x); return x; }
Dengan bergantung pada memcpy, kod ini mengekalkan integriti data sambil memastikan keselamatan jenis dan pematuhan kepada peraturan alias yang ketat .
Atas ialah kandungan terperinci Bagaimanakah `memcpy` Boleh Menyelesaikan Isu Pengelasan Ketat dalam Penukaran Float-ke-Int Jenis-Punning?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!