Это просто для удовлетворения моего собственного любопытства.
Есть ли реализация этого:
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;
}
в ржавчине? Если он существует, отправьте код.
Я попробовал это и потерпел неудачу. Я не знаю, как кодировать число с плавающей точкой, используя целочисленный формат. Вот моя попытка:
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
}
Ссылка:
1. Происхождение Быстрого InvSqrt () Quake3 - Страница 1
2. Понимание быстрого обратного квадратного корня Quake
3. БЫСТРАЯ ОБРАТНАЯ КВАДРАТНАЯ КОРНА.pdf
4. Исходный код: q_math.c # L552-L572
union
.
union
работает. memcpy
определенно работает, хотя это многословно.
rsqrtss
и rsqrtps
инструкция, введенная с Pentium III в 1999 году, быстрее и точнее , чем этот код. ARM NEON имеет vrsqrte
что похоже. И какие бы вычисления Quake III ни использовал для этого, в любом случае, вероятно, в наши дни будет сделано на GPU.