Anyone knows why javascript `Number.toString`

function does not represents negative numbers correctly?

```
//If you try
(-3).toString(2); //shows "-11"
// but if you fake a bit shift operation it works as expected
(-3 >>> 0).toString(2); // print "11111111111111111111111111111101"
```

I am really curious why it doesn't work properly or what is the reason it works this way? I've searched it but didn't find anything that helps.

The

`toString()`

function takes the decimal, converts it to binary and adds a "-" sign.A zero fill right shift converts it's operands to signed 32-bit integers in two complements format.

**Question 1:**

```
//If you try
(-3).toString(2); //show "-11"
```

It's in the function `.toString()`

. When you output a number via `.toString()`

:

SyntaxnumObj.toString([radix])

If the numObj is negative, the sign is preserved.This is the case even if the radix is 2; the string returned is the positive binary representation of the numObj preceded by a - sign, not the two's complement of the numObj.

It takes the decimal, converts it to binary and adds a "-" sign.

- Base 10 "3" converted to base 2 is "11"
- Add a sign gives us "-11"

**Question 2:**

```
// but if you fake a bit shift operation it works as expected
(-3 >>> 0).toString(2); // print "11111111111111111111111111111101"
```

A zero fill right shift converts it's operands to signed 32-bit integers. The result of that operation is always an unsigned 32-bit integer.

The operands of all bitwise operators are converted to signed 32-bit integers in two's complement format.

-3 >>> 0 (right logical shift) coerces its arguments to unsigned integers, which is why you get the 32-bit two's complement representation of -3.

```
var binary = (-3 >>> 0).toString(2); // coerced to uint32
console.log(binary);
console.log(parseInt(binary, 2) >> 0); // to int32
```

on jsfiddle

output is

```
11111111111111111111111111111101
-3
```

`.toString()`

is designed to return the sign of the number in the string representation. See EcmaScript 2015, section 7.1.12.1:

- If
mis less than zero, return the String concatenation of the String "-" and ToString(?m).

This rule is no different for when a radix is passed as argument, as can be concluded from section 20.1.3.6:

- Return the String representation of this Number value using the radix specified by
radixNumber. [...] the algorithm should be a generalization of that specified in 7.1.12.1.

Once that is understood, the surprising thing is more as to why it does not do the same with `-3 >>> 0`

.

But *that* behaviour has actually nothing to do with `.toString(2)`

, as the value is already different before calling it:

`console.log (-3 >>> 0); // 4294967293`

It is the consequence of how the `>>>`

operator behaves.

It does not help either that (at the time of writing) the information on mdn is not entirely correct. It says:

The operands of all bitwise operators are converted to signed 32-bit integers in two's complement format.

But this is not true for *all* bitwise operators. The `>>>`

operator is an exception to the rule. This is clear from the evaluation process specified in EcmaScript 2015, section 12.5.8.1:

- Let
lnumbe ToUint32(lval).

The ToUint32 operation has a step where the operand is mapped into the unsigned 32 bit range:

- Let
int32bitbeintmodulo 2^{32}.

When you apply the above mentioned modulo operation (not to be confused with JavaScript's `%`

operator) to the example value of -3, you get indeed 4294967293.

As -3 and 4294967293 are evidently not the same number, it is no surprise that `(-3).toString(2)`

is not the same as `(4294967293).toString(2)`

.

Just to summarize a few points here, if the other answers are a little confusing:

- what we want to obtain is the string representation of a negative number in binary representation; this means the string should show a signed binary number (using 2's complement)
- the expression
`(-3 >>> 0).toString(2)`

, let's call it A, does the job; but we want to know why and how it works - had we used
`var num = -3; num.toString(-3)`

we would have gotten`-11`

, which is simply the unsigned binary representation of the number 3 with a negative sign in front, which is not what we want - expression A works like this:

**1) (-3 >>> 0)**

The `>>>`

operation takes the left operand (-3), which is a signed integer, and simply shifts the bits 0 positions to the left (so the bits are unchanged), and the unsigned number corresponding to these unchanged bits.

The bit sequence of the signed number -3 is the same bit sequence as the unsigned number 4294967293, which is what node gives us if we simply type `-3 >>> 0`

into the REPL.

**2) (-3 >>> 0).toString**

Now, if we call `toString`

on this unsigned number, we will just get the string representation of the bits of the number, which is the same sequence of bits as -3.

What we effectively did was say "hey toString, you have normal behavior when I tell you to print out the bits of an unsigned integer, so since I want to print out a signed integer, I'll just convert it to an unsigned integer, and you print the bits out for me."

©2020 All rights reserved.