JS Quirks: stringified numbers
Table of Contents
When I was working on Node.js PR 9492, this comment
This should probably test for a wider range of values.
test/parallel/test-net-internal.jshas some good examples.
made me look at that file. As I was going through the test, few of the bad values were interesting. I normally test with stringified positive decimal numbers and negative decimal numbers. But I saw stringified negative octal, binary, and hexa decimal numbers.
I got curious as I have never used them before, I just wanted to see their corresponding negative values. So I wrote a program like this
1[-0x1, '-0x1', -0o1, '-0o1', -0b1, '-0b1'].forEach(item => console.log(item, +item));and I was expecting to see the result
but all I got was
The unary - operator simply negates the magnitude of the numbers. The stringified numbers were not processed in the same way as their number counterparts. So I looked at the ECMAScript specification's ToNumber Applied to the String Type section (which is actually responsible for converting strings to numbers).
Only the StrDecimalLiteral production allows signed numbers. If we look at the definition of others in the Numeric Literals section,
1BinaryIntegerLiteral ::
2 0b BinaryDigits
3 0B BinaryDigits
4
5BinaryDigits ::
6 BinaryDigit
7 BinaryDigits BinaryDigit
8
9BinaryDigit :: one of
10 0 1
11
12OctalIntegerLiteral ::
13 0o OctalDigits
14 0O OctalDigits
15
16OctalDigits ::
17 OctalDigit
18 OctalDigits OctalDigit
19
20OctalDigit :: one of
21 0 1 2 3 4 5 6 7
22
23HexIntegerLiteral ::
24 0x HexDigits
25 0X HexDigits
26
27HexDigits ::
28 HexDigit
29 HexDigits HexDigit
30
31HexDigit :: one of
32 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E FSo, as per the specification, only the decimal numbers can have signs in the stringified number form. That is why the others are not considered as numbers.