Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Number with leading zero in JavaScript

Tags:

javascript

Try this:

var num = 040;
console.log(num); // 32

Since when is 40 = 32?

like image 912
Hein du Plessis Avatar asked Jun 28 '11 10:06

Hein du Plessis


People also ask

How can I pad a value with leading zeros?

To pad an integer with leading zeros to a specific length To display the integer as a decimal value, call its ToString(String) method, and pass the string "Dn" as the value of the format parameter, where n represents the minimum length of the string.

How do you add leading zeros in HTML?

If you are using a text input you have to add the leading 0 on the 10 first values by javascript. Show activity on this post. The correct, modern solution to OP's problem would be to use a input with type=time and then they don't have to worry about leading zeros or any of this other stuffs.


2 Answers

With a leading zero, the number is interpreted as octal and 4 * 8 = 32.

like image 131
Florian Avatar answered Sep 22 '22 13:09

Florian


TL;DR

It's being treated as octal (base 8) because of the leading 0, just like a leading 0x would make it hex (base 16). This has a long and tortured history and is no longer how octal numbers are written in modern JavaScript. In modern JavaScript using strict mode, the "legacy" octal format is a syntax error; octal numbers are written with an 0o prefix.

History

Early on (in the initial language from Netscape and the first and second ECMAScript specifications), a leading 0 on a numeric literal officially meant octal (base 8), just as a leading 0x means hexadecimal (base 16):

OctalIntegerLiteral ::
    0 OctalDigit
    OctalIntegerLiteral OctalDigit

E.g., 10, 012, and 0xA were all ways of writing the decimal number ten. This is in keeping with some other languages with syntax similar to JavaScript (C, C++, Java, ...), but it's highly confusing.

As of ECMAScript 3, that form of octal literal was downgraded to an optional extension, and decimal integer literals were changed so that they can't have leading zeros (unless the implementation includes the extension):

DecimalIntegerLiteral ::
    0
    NonZeroDigit DecimalDigits(opt)

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 (ECMAScript 2015) 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's a syntax error.
    • In non-strict mode, it may be a syntax error or return 8 (implementation dependent).
  • 0o10, 0O10
    • Before ECMAScript 6, they're syntax errors.
    • In ECMAScript 6, they return 8.
  • parseInt('010', 8)
    • It returns 8.
  • parseInt('010', 10)
    • It returns 10.

If you're interested, you can find the current living specification here, and historical versions here.

like image 20
Oriol Avatar answered Sep 23 '22 13:09

Oriol