@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
49 lines (41 loc) • 1.37 kB
JavaScript
/**
* Decomposes a floating-point number into a normalized fraction and an integer power of 2.
* Similar to C's frexp function.
* @param {number} value - The floating-point number to decompose
* @param {number[]} exponent where to write exponent to
* @param {number} [offset_into_exponent]
* @returns {number} mantissa
*/
export function frexp(
value,
exponent,
offset_into_exponent = 0
) {
if (value === 0 || Number.isFinite(value) === false) {
exponent[offset_into_exponent] = 0;
return value;
}
let abs_value = Math.abs(value);
// Get the exponent using Math.log2 and floor it
let exp = Math.max(
-1023,
Math.floor(Math.log2(abs_value)) + 1
);
// Calculate the mantissa by dividing by 2^exp
let mantissa = abs_value * Math.pow(2, -exp);
// These while loops compensate for rounding errors that sometimes occur because of ECMAScript's Math.log2's undefined precision
// and also works around the issue of Math.pow(2, -exp) === Infinity when exp <= -1024
while (mantissa < 0.5) {
mantissa *= 2;
exp--;
}
while (mantissa >= 1) {
mantissa *= 0.5;
exp++;
}
if (value < 0) {
mantissa = -mantissa;
}
exponent[offset_into_exponent] = exp;
return mantissa;
}