Questo è solo per soddisfare la mia curiosità.
C'è un'implementazione di questo:
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 ruggine? Se esiste, pubblica il codice.
L'ho provato e non ci sono riuscito. Non so come codificare il numero float usando il formato intero. Ecco il mio tentativo:
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
}
Riferimento:
1. Origine di Fast InvSqrt di Quake3 () - Pagina 1
2. Comprensione della radice quadrata inversa veloce di Quake
3. FAST INVERSE SQUARE ROOT.pdf
4. codice sorgente: q_math.c # L552-L572
union
.
union
neanche. memcpy
sicuramente funziona, anche se è prolisso.
rsqrtss
e rsqrtps
, introdotte con Pentium III nel 1999, sono più veloci e più accurate di questo codice. ARM NEON ha vrsqrte
quale è simile. E qualunque sia il calcolo utilizzato da Quake III per questo, probabilmente verrebbe comunque eseguito sulla GPU in questi giorni.