Dies ist nur, um meine eigene Neugier zu befriedigen.
Gibt es eine Implementierung davon:
float InvSqrt (float x)
{
float xhalf = 0.5f*x;
int i = *(int*)&x;
i = 0x5f3759df - (i>>1);
x = *(float*)&i;
x = x*(1.5f - xhalf*x*x);
return x;
}
in Rust? Wenn es existiert, geben Sie den Code ein.
Ich habe es versucht und bin gescheitert. Ich weiß nicht, wie ich die Gleitkommazahl im Ganzzahlformat codieren soll. Hier ist mein Versuch:
fn main() {
println!("Hello, world!");
println!("sqrt1: {}, ",sqrt2(100f64));
}
fn sqrt1(x: f64) -> f64 {
x.sqrt()
}
fn sqrt2(x: f64) -> f64 {
let mut x = x;
let xhalf = 0.5*x;
let mut i = x as i64;
println!("sqrt1: {}, ", i);
i = 0x5f375a86 as i64 - (i>>1);
x = i as f64;
x = x*(1.5f64 - xhalf*x*x);
1.0/x
}
Referenz:
1. Ursprung von Quake3s Fast InvSqrt () - Page 1
2. Grundlegendes zu Quakes Fast Inverse Square Root
3. FAST INVERSE SQUARE ROOT.pdf
4. Quellcode: q_math.c # L552-L572
union
.
union
funktioniert. memcpy
funktioniert definitiv, obwohl es ausführlich ist.
rsqrtss
und rsqrtps
Anweisungen, im Jahr 1999 mit dem Pentium III eingeführt, sind schneller und genauer als dieser Code. ARM NEON hat vrsqrte
was ähnlich ist. Und für welche Berechnungen Quake III dies auch verwendete, würde es heutzutage wahrscheinlich sowieso auf der GPU durchgeführt werden.