# Convert integers to binary strings

If you want to visualize the binary digits of a number in JavaScript, you need to decode the floating point format as you build your string.

The simplest, but least accurate method is to use the built-in `Number.toString(2)`.

JavaScript

``````let n = 254;
let nStr = n.toString(2);
console.log(nStr);
// outputs "11111110"
``````

There are two issues with that output.

1. It doesn't pad the result correctly, giving the false impression that `254` is stored in memory using only 8 bits.
2. Negative numbers won't be in two's-complement format. Instead, `toString()` converts the number's absolute value to binary, then prepends a '-'.

(1) is relatively simple to handle with `String.padStart()`. (2) can be solved with a quirk of the `>>>` operator:

``````let n = -255;
let nStr = (n >>> 0).toString(2);
console.log(nStr);
// outputs "11111111111111111111111100000001"
``````

"`>>>`" apparently forces a conversion to an unsigned integer, whose bits are treated as-is by `toString()`.

That result is pretty decent, but it won't cover numbers closer to the Number.MAXSAFEINTEGER range. The output above was only 32 bits long, but JavaScript numbers actually offer 52 bits of precision.

To get an accurate representation of any integer in the range [`Number.MIN_SAFE_INTEGER`, `Number.MAX_SAFE_INTEGER`], you'll need to do more work to decode the floating point container format.

This SO answer has an excellent solution:

JavaScript

``````// IIFE to scope internal variables
var float64ToInt64Binary = (function () {
// create union
var flt64 = new Float64Array(1);
var uint16 = new Uint16Array(flt64.buffer);
// 2**53-1
var MAX_SAFE = 9007199254740991;
// 2**31
var MAX_INT32 = 2147483648;

function uint16ToBinary() {
var bin64 = "";
// generate padded binary string a word at a time
for (var word = 0; word < 4; word++) {
bin64 = uint16[word].toString(2).padStart(16, 0) + bin64;
}
return bin64;
}
return function float64ToInt64Binary(number) {
// NaN would pass through Math.abs(number) > MAX_SAFE
if (!(Math.abs(number) <= MAX_SAFE)) {
throw new RangeError("Absolute value must be less than 2**53");
}
var sign = number < 0 ? 1 : 0;
// shortcut using other answer for sufficiently small range
if (Math.abs(number) <= MAX_INT32) {
}
// little endian byte ordering
flt64 = number;
// subtract bias from exponent bits
var exponent = ((uint16 & 0x7ff0) >> 4) - 1023;
// encode implicit leading bit of mantissa
uint16 |= 0x10;
// clear exponent and sign bit
uint16 &= 0x1f;
// check sign bit
if (sign === 1) {
// apply two's complement
uint16 ^= 0xffff;
uint16 ^= 0xffff;
uint16 ^= 0xffff;
uint16 ^= 0xffff;
// propagate carry bit
for (var word = 0; word < 3 && uint16[word] === 0xffff; word++) {
// apply integer overflow
uint16[word] = 0;
}
// complete increment
uint16[word]++;
}
// only keep integer part of mantissa
var bin64 = uint16ToBinary().substr(11, Math.max(exponent, 0));
// sign-extend binary string
Using `float64ToInt64Binary` will give you a bitwise-correct integer in the full valid range. His solution relies heavily on knowledge of the floating point format. The Wikipedia entry is pretty dense, so I recommend "The Floating-Point Guide" if you want to learn more.