Bu sadece kendi merakımı tatmin etmek için.
Bunun bir uygulaması var mı:
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;
}
Rust bölgesinde bulundunuz mu? Varsa, kodu gönderin.
Denedim ve başarısız oldum. Tamsayı biçimini kullanarak kayan nokta numarasını nasıl kodlayacağımı bilmiyorum. İşte benim girişimim:
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
}
Referans:
1. Quake3'ün Hızlı InvSqrt () kaynağının kökeni () - Sayfa 1
2. Quake'in Hızlı Ters Kare Kökünü Anlama
3. HIZLI İNVERSE KARE ROOT.pdf
4. kaynak kodu: q_math.c # L552-L572
union.
unionişe yaradığını sanmıyorum . memcpykesinlikle işe yarıyor, buna rağmen ayrıntılı.
rsqrtssve rsqrtpstalimatları bu koddan daha hızlı ve daha doğrudur. ARM NEON vrsqrteda buna benzer. Ve Quake III'ün bunu kullandığı hesaplamalar ne olursa olsun, muhtemelen bugünlerde GPU'da yapılacaktı.