Open DelSquared opened 6 years ago
Posting the original code here would be helpful
Here's an article on Wikipedia: https://en.wikipedia.org/wiki/Fast_inverse_square_root With an overview of the code and a worked example: https://en.wikipedia.org/wiki/Fast_inverse_square_root#Overview_of_the_code
Posting the original code here would be helpful
I edited my post with the code provided on Wikipedia as well as the link that I sourced it from. Thanks for your suggestion @nhuyvan1106 :)
So if i understand this correctly then floating point numbers are stored in scientific notation, in the form of significand and exponent. In the above algorithm we are dividing the exponent part of the floating number in half leading to square root of the number. So basically we have shifted the hard part of the calculation on the implementation of floating point numbers. Is this right?
@DelSquared I often use bit shifting and bitwise-and to manipulate RGB pixels
For example, generating a random pixel
(Javascript)
const r = (Math.random() * 256) & 0xff;
const g = (Math.random() * 256) & 0xff;
const b = (Math.random() * 256) & 0xff;
const pixel = (r << 16) | (g << 8) | b;
console.log(pixel)
The equivalent code in Javascript, one important thing to note here is that because all numbers in Javascript are already represented as double-precision IEEE-754 float point numbers, and there is no specific type for integers, no need to convert back to float.
function Q_rsqrt(num) {
let i, x2, y;
const threehalfs = 1.5;
x2 = num * 0.5;
y = num;
i = y | 0;
i = 0x5f3759df - ( i >> 1);
y = i;
y = y * ( threehalfs - ( x2 * y * y ) );
y = y * ( threehalfs - ( x2 * y * y ) );
return y;
}
Java
float inverseSquare(float num) {
int i;
float x2, y;
final float threehalfs = 1.5;
x2 = num * 0.5;
y = num;
i = (int) y;
i = 0x5f3759df - ( i >> 1);
y = (float) i;
y = y * ( threehalfs - ( x2 * y * y ) );
y = y * ( threehalfs - ( x2 * y * y ) );
return y;
}
@nhuyvan1106 Your JavaScript code does not seem to work.
@ShivanshuKantPrasad
It is probably because the statement i = * ( long * ) &y;
simply is not a mere cast from float to long, the C compiler may do something else which I have no clue about, after reading the wikipedia article, that seems to be the case
@DelSquared I often use bit shifting and bitwise-and to manipulate RGB pixels
For example, generating a random pixel
(Javascript)
const r = (Math.random() * 256) & 0xff; const g = (Math.random() * 256) & 0xff; const b = (Math.random() * 256) & 0xff; const pixel = (r << 16) | (g << 8) | b; console.log(pixel)
The equivalent code in Javascript, one important thing to note here is that because all numbers in Javascript are already represented as double-precision IEEE-754 float point numbers, and there is no specific type for integers, no need to convert back to float.
function Q_rsqrt(num) { let i, x2, y; const threehalfs = 1.5; x2 = num * 0.5; y = num; i = y | 0; i = 0x5f3759df - ( i >> 1); y = i; y = y * ( threehalfs - ( x2 * y * y ) ); y = y * ( threehalfs - ( x2 * y * y ) ); return y; }
Java
float inverseSquare(float num) { int i; float x2, y; final float threehalfs = 1.5; x2 = num * 0.5; y = num; i = (int) y; i = 0x5f3759df - ( i >> 1); y = (float) i; y = y * ( threehalfs - ( x2 * y * y ) ); y = y * ( threehalfs - ( x2 * y * y ) ); return y; }
What is the |
operator in JS? I have never come across it @nhuyvan1106 .
@DelSquared It is called Bitwise-OR
Back in the late 90s, the game Quake III was very influential in the computer graphics sector by taking huge advantage of bit-shifting in order to estimate the value of y=1/√x many times per frame for lighting calculations and to normalise vectors.
The original code was written in C meaning it makes heavy use of pointers so off the top of my head I don't know if an equivalent algorithm can be implemented in Java/Javascript. However if so, it would be a good way to demonstrate the power of bit-shifting beyond the 8 segment display and simple halving.
Because the code was requested in the comments (copied from here and re-commented):