Why JavaScript Treats a Number as Octal If It Has a Leading Zero

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 or 0B.
  • OctalIntegerLiteral, prefixed with 0o or 0O.
  • HexIntegerLiteral, prefixed with 0x or 0X.

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.
  • parseInt('010', 10)
    • It returns 10.

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 or 0B
  • 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



Leave a reply



Submit