I've run into an issue that seems a bit weird and am wondering if anyone might be able to help with it.
I'm using JavaScript to store some integers via node.js and would like to use the full range of integers from Number.MIN_SAFE_INTEGER
through Number.MAX_SAFE_INTEGER
just calling negative zero a zero.
From w3schools it appears there are only 52 bits allowed (the first 52 bits), ignoring the sign, to retrieve Number.MAX_SAFE_INTEGER
however it is clearly equal to (2 ^ 53) - 1
.
The ECMA spec on the otherhand says there are (2 ^ 53) - 2
values (appearing to use -0
as NaN
.
I'm trying to pack integers into the smallest bitspace possible, 1-bit (1) sign, 1-bit (2) for null and the remaining bits for successively larger numbers. This works great just adding more lines up until the last line of:
// sign is 0 for positive, 1 for negative and 2 for null
byte[0] = ((temp << 2) & 255) + sign;
byte[1] = (temp >> 6) & 255;
byte[2] = (temp >> 14) & 255;
byte[3] = (temp >> 22) & 255;
byte[4] = (temp >> 30) & 255;
byte[5] = (temp >> 38) & 255;
byte[6] = (temp >> 46) & 255; // produces a negative value prior to applying byte mask
Here's a fiddle with some relevant code incase it helps.
The IEEE floating point format has an implied leading 1
bit on the mantissa, but it's not actually present. In other words, all valid values have a leading 1 bit, so there's no point actually having it be explicitly stored.
You can look at this jsfiddle I did the other day to see how values are represented. Integers are represented as binary fractions multiplied by 2
raised to a power larger than 1
, except of course for the integer 1
, which has a mantissa of all zeros because of that leading implied 1
bit. (Actually every power of 2
is all-zeros in the mantissa.)
edit — for reference, the most sure-fire way I know to get directly at the bits in a floating-point value is to use typed arrays:
var f64 = new Float64Array(1);
var u8 = new Uint8Array(f64.buffer);
That gives you a one-element 64-bit array, and an 8 element unsigned 8-bit int array. Put a number in the f64
array:
f64[0] = Math.sin(x); // or whatever
Then the u8
array gives you the 8 bytes of that value, with the most significant byte (where the sign bit and exponent are) at u8[7]
. IE versions less than 10 don't support typed arrays, nor does Opera Mini.