Die Fast Inverse Square Root von Quake III scheint einen Gleitkomma-Trick zu verwenden. Soweit ich weiß, kann die Gleitkommadarstellung verschiedene Implementierungen haben.
Ist es also möglich, die schnelle inverse Quadratwurzel in Javascript zu implementieren?
Würde es das gleiche Ergebnis zurückgeben?
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
quelle
quelle
Antworten:
Der Trick hängt davon ab, dass die Bits einer Gleitkommazahl als Ganzzahl und wieder zurück interpretiert werden. Dies ist in JavaScript mithilfe der Funktion Typed Arrays möglich , um einen Rohbytepuffer mit mehreren numerischen Ansichten darauf zu erstellen.
Hier ist eine wörtliche Konvertierung des von Ihnen angegebenen Codes. Beachten Sie, dass dies nicht genau dasselbe ist, da alle arithmetischen Operationen in JavaScript 64-Bit-Gleitkommazahlen und keine 32-Bit-Operationen sind, sodass die Eingabe unbedingt konvertiert werden muss. Ebenso wie der ursprüngliche Code ist dies plattformabhängig , da es unsinnige Ergebnisse liefert, wenn die Prozessorarchitektur eine andere Bytereihenfolge verwendet. Wenn Sie solche Dinge tun müssen, empfehle ich, dass Ihre Anwendung zuerst einen Testfall ausführt, um festzustellen, ob Ganzzahlen und Gleitkommazahlen die erwarteten Bytedarstellungen haben.
Ich habe durch Betrachten eines Diagramms bestätigt, dass dies vernünftige numerische Ergebnisse liefert. Es ist jedoch nicht offensichtlich, dass dies die Leistung überhaupt verbessern wird, da wir mehr JavaScript-Operationen auf höherer Ebene ausführen. Ich habe Benchmarks für die Browser ausgeführt, die ich zur Hand habe, und festgestellt, dass dies
Q_rsqrt(number)
50% bis 80% der Zeit in1/sqrt(number)
Anspruch nimmt (Chrome, Firefox und Safari unter macOS, Stand April 2018). Hier ist mein kompletter Testaufbau:quelle
In classic JavaScript, it is not possible to... reinterpreting the bits of a floating-point number as an integer
Ja wirklich? Es war vor Jahren, also erinnere ich mich nicht genau, welche Operationen ich verwendet habe, aber ich habe einmal einen Datenparser in JavaScript geschrieben, der eine Folge von Bytes in eine Reihe von N-Bit-Ganzzahlen (N wurde im Header definiert) konvertiert. Das ist ziemlich ähnlich.