Skip to main content
2 of 2
Minor edition
Teocci
  • 9.4k
  • 1
  • 72
  • 56

I’d like to see integers, positive or negative, in binary.

This is an old question and I think there are very nice solutions here but there is no explanation about the use of these clever solutions.

First, we need to understand that a number can be positive or negative. Also, JavaScript provides a MAX_SAFE_INTEGER constant that has a value of 9007199254740991. The reasoning behind that number is that JavaScript uses double-precision floating-point format numbers as specified in IEEE 754 and can only safely represent integers between -(2^53 - 1) and 2^53 - 1.

So, now we know the range where numbers are "safe". Also, JavaScript ES6 has the built-in method Number.isSafeInteger() to check if a number is a safe integer.

Logically, if we want to represent a number n as binary, this number needs a length of 53 bits, but for better presentation lets use 7 groups of 8 bits = 56 bits and fill the left side with 0 or 1 based on its sign using the padStart function.

Next, we need to handle positive and negative numbers: positive numbers will add 0s to the left while negative numbers will add 1s. Also, negative numbers will need a two's-complement representation. We can easily fix this by adding Number.MAX_SAFE_INTEGER + 1 to the number.

For example, we want to represent -3 as binary, lets assume that Number.MAX_SAFE_INTEGER is 00000000 11111111 (255) then Number.MAX_SAFE_INTEGER + 1 will be 00000001 00000000 (256). Now lets add the number Number.MAX_SAFE_INTEGER + 1 - 3 this will be 00000000 11111101 (253) but as we said we will fill with the left side with 1 like this 11111111 11111101 (-3), this represent -3 in binary.

Another algorithm will be we add 1 to the number and invert the sign like this -(-3 + 1) = 2 this will be 00000000 00000010 (2). Now we invert every bit like this 11111111 11111101 (-3) again we have a binary representation of -3.

Here we have a working snippet of these algos:

function dec2binA(n) {
    if (!Number.isSafeInteger(n)) throw new TypeError('n value must be a safe integer')
    if (n > 2**31) throw 'number too large. number should not be greater than 2**31'
    if (n < -1*(2**31)) throw 'number too far negative, number should not be lesser than 2**31'

    const bin = n < 0 ? Number.MAX_SAFE_INTEGER + 1 + n : n
    const signBit = n < 0 ? '1' : '0'

    return parseInt(bin, 10).toString(2)
        .padStart(56, signBit)
        .replace(/\B(?=(.{8})+(?!.))/g, ' ')
}


function dec2binB(n) {
    if (!Number.isSafeInteger(n)) throw new TypeError('n value must be a safe integer')
    if (n > 2**31) throw 'number too large. number should not be greater than 2**31'
    if (n < -1*(2**31)) throw 'number too far negative, number should not be lesser than 2**31'

    const bin = n < 0 ?  -(1 + n) : n
    const signBit = n < 0 ? '1' : '0'

    return parseInt(bin, 10).toString(2)
        .replace(/[01]/g, d => +!+d)
        .padStart(56, signBit)
        .replace(/\B(?=(.{8})+(?!.))/g, ' ')
}



const a = -805306368
console.log(a)
console.log('dec2binA:', dec2binA(a))
console.log('dec2binB:', dec2binB(a))

const b = -3
console.log(b)
console.log('dec2binA:', dec2binA(b))
console.log('dec2binB:', dec2binB(b))

Teocci
  • 9.4k
  • 1
  • 72
  • 56