diffusion
Version:
Diffusion JavaScript client
113 lines (91 loc) • 2.83 kB
JavaScript
function leadingZeros(i) {
if (i === 0) {
return 32;
}
var n = 1;
if (i >>> 16 === 0) { n += 16; i <<= 16; }
if (i >>> 24 === 0) { n += 8; i <<= 8; }
if (i >>> 28 === 0) { n += 4; i <<= 4; }
if (i >>> 30 === 0) { n += 2; i <<= 2; }
n -= i >>> 31;
return n;
}
/**
* Cheap approximation to a square root.
*
* @param {Number} value - value from which to find the approx square root
* @return {Number} a power of two that approximates the square root of a value
*/
module.exports.approximateSquareRoot = function(value) {
if (value < 0) {
throw new Error("Value must be greater or equal to 0");
}
if (value === 0) {
return 0;
}
var result = 1;
for (var i = value; i > 0; i >>= 2) {
result *= 2;
}
return result;
};
module.exports.approximateCubeRoot = function(value) {
if (value < 0) {
throw new Error("Value must be great or equal to 0");
}
if (value === 0) {
return 0;
}
var h = 32 - leadingZeros(value);
return 1 << h / 3;
};
/**
* Find the next integer, equal or higher to the value, which is a power of two.
*
* @param {Number} value - the value to search from
* @returns {Number} the next power of two
*/
module.exports.findNextPowerOfTwo = function(value) {
if (value < 0 || value > 1 << 30) {
throw new Error("Illegal argument: " + value);
}
// See: https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
value--;
value |= value >> 1;
value |= value >> 2;
value |= value >> 4;
value |= value >> 8;
value |= value >> 16;
value++;
return value;
};
/**
* Converts an integer conforming to IEEE 754 Single bit format to a floating point value. This is similar to Java's
* Float#intBitsToFloat.
* <P>
* See https://en.wikipedia.org/wiki/Single-precision_floating-point_format for detail on the bit layout.
* <P>
* Code taken from http://stackoverflow.com/a/16001019 - most succinct implementation I could find that avoided
* unnecessary loops or reads.
*
* @param {Number} bytes - integer containing IEEE-754 value bytes
* @returns {Number} result - the resulting float
*/
module.exports.intBitsToFloat = function(bytes) {
var sign = (bytes & 0x80000000) ? -1 : 1;
var exponent = ((bytes >> 23) & 0xFF) - 127;
var significand = (bytes & ~(-1 << 23));
if (exponent === 128) {
return sign * ((significand) ? Number.NaN : Number.POSITIVE_INFINITY);
}
if (exponent === -127) {
if (significand === 0) {
return sign * 0.0;
}
exponent = -126;
significand /= (1 << 22);
} else {
significand = (significand | (1 << 23)) / (1 << 23);
}
return sign * significand * Math.pow(2, exponent);
};