Fast Inverse Square Root z Quake III wydaje się używać sztuczki zmiennoprzecinkowej. Jak rozumiem, reprezentacja zmiennoprzecinkowa może mieć kilka różnych implementacji.
Czy można zaimplementować Fast Inverse Square Root w Javascript?
Czy zwróci ten sam wynik?
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
źródło
źródło
Odpowiedzi:
Trik polega na ponownej interpretacji bitów liczb zmiennoprzecinkowych jako liczb całkowitych iz powrotem, co jest możliwe w JavaScript przy użyciu narzędzia Typed Arrays , w celu utworzenia bufora surowych bajtów z wieloma widokami numerycznymi.
Oto dosłowna konwersja podanego kodu; Zwróć uwagę, że nie jest dokładnie taki sam, ponieważ wszystkie operacje arytmetyczne w JavaScript są 64-bitowe zmiennoprzecinkowe, a nie 32-bitowe, więc dane wejściowe muszą zostać przekonwertowane. Podobnie jak oryginalny kod, jest to zależne od platformy , ponieważ daje nonsensowne wyniki, jeśli architektura procesora używa innej kolejności bajtów; jeśli musisz zrobić coś takiego, zalecamy, aby aplikacja najpierw wykonała test, aby ustalić, czy liczby całkowite i zmiennoprzecinkowe mają oczekiwaną reprezentację bajtów.
Potwierdziłem, patrząc na wykres, że daje to rozsądne wyniki liczbowe. Jednak nie jest oczywiste, że w ogóle poprawi to wydajność, ponieważ wykonujemy więcej operacji JavaScript na wysokim poziomie. Uruchomiłem testy porównawcze w przeglądarkach, które mam pod ręką i stwierdziłem, że
Q_rsqrt(number)
zajmuje to od 50% do 80% czasu1/sqrt(number)
(Chrome, Firefox i Safari na macOS, od kwietnia 2018 r.). Oto moja kompletna konfiguracja testowa:źródło
In classic JavaScript, it is not possible to... reinterpreting the bits of a floating-point number as an integer
naprawdę? To było lata temu, więc nie pamiętam dokładnie, jakich operacji używałem, ale kiedyś napisałem parser danych w JavaScript, który przekształciłby ciąg bajtów w serię liczb całkowitych N-bitowych (N zostało zdefiniowane w nagłówku). To całkiem podobne.