.toString()
is designed to return the sign of the number in the string representation. See EcmaScript 2015, section 7.1.12.1:
- If m is 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 lnum be ToUint32(lval).
The ToUint32 operation has a step where the operand is mapped into the unsigned 32 bit range:
- Let int32bit be int modulo 232.
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)
.