I implemented the famous Quake inverse sqrt function in Rust!
So, I recently started learning the Rust language about 2 weeks ago, and I have been exploring some more advanced concepts of memory management and bit manipulation. (Including potentially the most dangerous of them all, std::mem::transmute)
TL;DR: Here is the code, more context and explanation below.
fn quake_rsqrt(number: f32) -> f32 {
let mut y: f32 = number;
unsafe {
let mut i: i32 = std::mem::transmute::<f32, i32>(y);
i = 0x5F375A86 - (i >> 1);
y = std::mem::transmute::<i32, f32>(i);
}
y * (1.5 - (number * 0.5 * y * y))
}
As a way to practice and apply what I have learned, I implemented the infamous, bit-hacking, most-memory-unsafe Quake inverse square root function, with a few variations for speed and accuracy! I have eliminated 2 of the variable allocations, saving a few instructions, as well as reducing the revisions to only one in the process. It is also using the derived, more-accurate "0x5F375A86" constant instead of the original "0x5F3759DF". Because of this, even with only one iterative revision, the resulting answer is within about 0.1% of the correct answer! If anyone would like a better explanation for the how the algorithm works, here is a link to a video from Nemean on YouTube. He gives a great explanation of the whole thing. https://www.youtube.com/watch?v=p8u\_k2LIZyo
That's all I've got for now, but I thought it was a fun thought experiment to try doing the most unsafe memory hacks with the most type-safe, memory-safe language I could think of! lol Hope you all have a great day!
Edit: Updated with even better code using the to\_bits and from\_bits functions. Full credit to /u/Shadow0133!
fn quake_rsqrt(number: f32) -> f32 {
let mut i: i32 = number.to_bits() as i32;
i = 0x5F375A86 - (i >> 1);
let y = f32::from_bits(i as u32);
y * (1.5 - (number * 0.5 * y * y))
}