Why JavaScript treats a number as octal if it has a leading zero
I think my answer here answers the question, but the question is not exactly a duplicate, so I include a copy of my answer.
History
The problem is that decimal integer literals can't have leading zeros:
DecimalIntegerLiteral ::
0
NonZeroDigit DecimalDigits(opt)
However, ECMAScript 3 allowed (as an optional extension) to parse literals with leading zeros in base 8:
OctalIntegerLiteral ::
0 OctalDigit
OctalIntegerLiteral OctalDigit
But ECMAScript 5 forbade doing that in strict-mode:
A conforming implementation, when processing strict mode code (see
10.1.1), must not extend the syntax of NumericLiteral to include OctalIntegerLiteral as described in B.1.1.
ECMAScript 6 introduces BinaryIntegerLiteral and OctalIntegerLiteral, so now we have more coherent literals:
- BinaryIntegerLiteral, prefixed with
0b
or0B
. - OctalIntegerLiteral, prefixed with
0o
or0O
. - HexIntegerLiteral, prefixed with
0x
or0X
.
The old OctalIntegerLiteral extension has been renamed to LegacyOctalIntegerLiteral, which is still allowed in non-strict mode.
Conclusion
Therefore, if you want to parse a number in base 8, use the 0o
or 0O
prefixes (not supported by old browsers), or use parseInt
.
And if you want to be sure your numbers will be parsed in base 10, remove leading zeros, or use parseInt
.
Examples
010
- In strict mode (requires ECMAScript 5), it throws.
- In non strict mode, it may throw or return
8
(implementation dependent).
0o10
,0O10
- Before ECMAScript 6, they throw.
- In ECMAScript 6, they return
8
.
parseInt('010', 8)
- It returns
8
.
- It returns
parseInt('010', 10)
- It returns
10
.
- It returns
Why does adding a zero before a number change its value?
Adding a zero before a number tells javascript to interpret it as an octal (base 8) value.
According to the MDN documentation on number literals, you can use the following to represent numbers on different base:
- decimal: numbers starting with any digit other than zero are decimal.
- binary: numbers starting with
0b
or0B
- octal: numbers starting with
0
- hexadecimal starting with
0x
or 0X` - exponentiation ending with
e
followed by a number (1e3
= 1x103)
Why are leading zeroes used to represent octal numbers?
All modern languages import this convention from C, which imported it from B, which imported it from BCPL.
Except BCPL used #1234
for octal and #x1234
for hexadecimal. B has departed from this convention because # was an unary operator in B (integer to floating point conversion), so #1234 could not be used, and # as a base indicator was replaced with 0.
The designers of B tried to make the syntax very compact. I guess this is the reason they did not use a two-character prefix.
What's the issue with +0 in javascript?
Starting a number with 0
declares that is an octal (base 8) and not a decimal (base 10).
Javascript, why treated as octal
If you receive your parameters as string objects, it should work to use
parseInt(string, 10)
to interpret strings as decimal, even if they are beginning with 0.
In your test, you pass the parseInt method a number, not a string, maybe that's why it doesn't return the expected result.
Try
parseInt('0000022115', 10)
instead of
parseInt(0000022115, 10)
that does return 221115 for me.
Number with leading zero in JavaScript
With a leading zero, the number is interpreted as octal and 4 * 8 = 32
.
How to remove leading zeros from a number within a function parameter
The reason this is happening is because leading a number with a zero makes javascript interpret the number in octal format. There is no way that you can change this interpretation, but if you're getting the value from somewhere as a string you could use parseInt(string, 10)
We can do this string conversion ourselves and then parse it in base 10 like so:
let number = 0011console.log(parseInt(number.toString(8),10))
ParseInt() strange octal behavior
In this code, you can defined a number (rather than a string) in octal format, then passed it to parseInt
. Then parseInt
casts that number to a string ("83"
), and parses it again.
If you pass a string to parseInt
you will get the expected result:
console.log(parseInt('0123'))
Related Topics
How to Pass Data from a Page to Another Page Using React Router
Is There a Better Way to Do Optional Function Parameters in JavaScript
Preserving a Reference to "This" in JavaScript Prototype Functions
How to Use Jquery for Xml Parsing with Namespaces
Transform Numbers to Words in Lakh/Crore System
Pass Props in Link React-Router
Declaring Variables Without Var Keyword
Why Is [1,2] + [3,4] = "1,23,4" in JavaScript
How to Add a Custom Right-Click Menu to a Webpage
Why and When Do We Need to Bind Functions and Eventhandlers in React
Long Processing Time Likely Due to Getvalue and Cell Inserts
Constructors in JavaScript Objects
Defining Methods via Prototype VS Using This in the Constructor - Really a Performance Difference
"Innerhtml += ..." VS "Appendchild(Txtnode)"
How to Move Cursor to End of Contenteditable Entity