Fast Inverse Square Root dari Quake III tampaknya menggunakan trik floating-point. Seperti yang saya pahami, representasi floating-point dapat memiliki beberapa implementasi yang berbeda.
Jadi mungkinkah menerapkan Fast Inverse Square Root di Javascript?
Apakah akan mengembalikan hasil yang sama?
float Q_rsqrt(float number) {
long i;
float x2, y;
const float threehalfs = 1.5F;
x2 = number * 0.5F;
y = number;
i = * ( long * ) &y;
i = 0x5f3759df - ( i >> 1 );
y = * ( float * ) &i;
y = y * ( threehalfs - ( x2 * y * y ) );
return y;
}
javascript
Atav32
sumber
sumber
Jawaban:
Triknya tergantung pada penafsiran kembali bit dari angka floating-point sebagai integer dan kembali lagi, yang dimungkinkan dalam JavaScript dengan menggunakan fasilitas Typed Array , untuk membuat buffer byte mentah dengan beberapa tampilan numerik.
Berikut ini adalah konversi kode yang Anda berikan secara literal; perhatikan bahwa ini tidak persis sama, karena semua operasi aritmatika dalam JavaScript adalah titik apung 64-bit, bukan 32-bit, sehingga input akan selalu dikonversi. Juga, seperti kode asli, ini bergantung pada platform karena akan memberikan hasil yang tidak masuk akal jika arsitektur prosesor menggunakan urutan byte yang berbeda; jika Anda harus melakukan hal-hal seperti ini, saya sarankan agar aplikasi Anda terlebih dahulu menjalankan test case untuk menentukan bahwa integer dan float memiliki representasi byte yang Anda harapkan.
Saya telah mengkonfirmasi dengan melihat grafik bahwa ini memberikan hasil numerik yang masuk akal. Namun, tidak jelas bahwa ini akan meningkatkan kinerja sama sekali, karena kami melakukan lebih banyak operasi JavaScript tingkat tinggi. Saya telah menjalankan benchmark pada browser yang saya miliki dan menemukan bahwa
Q_rsqrt(number)
dibutuhkan 50% hingga 80% dari waktu yang diambil1/sqrt(number)
(Chrome, Firefox, dan Safari di macOS, per April 2018). Ini adalah pengaturan pengujian lengkap saya:sumber
In classic JavaScript, it is not possible to... reinterpreting the bits of a floating-point number as an integer
Betulkah? Itu tahun yang lalu jadi saya tidak ingat persis operasi apa yang saya gunakan, tapi saya pernah menulis parser data dalam JavaScript yang akan mengubah serangkaian byte menjadi serangkaian N-bit (N didefinisikan dalam header) integer. Itu sangat mirip.