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
.
union
işe yaradığını sanmıyorum . memcpy
kesinlikle işe yarıyor, buna rağmen ayrıntılı.
rsqrtss
ve rsqrtps
talimatları bu koddan daha hızlı ve daha doğrudur. ARM NEON vrsqrte
da buna benzer. Ve Quake III'ün bunu kullandığı hesaplamalar ne olursa olsun, muhtemelen bugünlerde GPU'da yapılacaktı.