24

I just want to understand js logic with 0-s in beginning of number. For example

var x = 09.3
// here x == 9.3
// other example
09.3 == 9.3
// returns true

// but check this one
var x = 02.5
// Uncaught SyntaxError: Unexpected number
// or this one
02.5 == 2.5 
// same error here

Can anyone explain, how it works, why in first example it works, and ignores leading zeros, but in second example it gives me a SyntaxError

Thank you

Gor
  • 2,808
  • 6
  • 25
  • 46
  • 6
    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Integers – hindmost Jan 27 '16 at 21:06
  • 3
    In my browser, `09.3` is definitely not equal to `0.3`. What browser (or environment) are you using? – Pointy Jan 27 '16 at 21:10
  • Pointy, sorry for mistake , I mean 9.3 – Gor Jan 27 '16 at 21:10
  • 4
    Why would you type numbers with leading zeros anyway, and if you're getting them this way, they are strings, not numbers. The reason the first one works, is because octal is base 8, it only uses the numbers 0 to 7, so a number starting with 09 is clearly not base 8, but base 10, something javascript seems to understand most of the time – adeneo Jan 27 '16 at 21:15
  • @Gor refer this https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Numeric_literals https://bugzilla.mozilla.org/show_bug.cgi?id=957513. +1 to adeneo – pratikpawar Jan 27 '16 at 21:22

3 Answers3

36

Leading 0 on a numerical literal indicates that an octal integer is the intention, unless the second digit is 8 or 9. In that case, the leading 0 is ignored.

Because octal numeric literals must be integers, 02.5 is erroneous.

This behavior was logged as a bug in Firefox in 2014, but because there's so much JavaScript code in the world and so much of it (probably inadvertently) relies on 09.3 not being a syntax error, the bug was marked "WONTFIX".

As pointed out in a comment below, in "strict" mode octal constants are disallowed entirely.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • 5
    Not just the second digit -- if any digit is 8 or 9, the leading 0 is ignored. – Barmar Jan 27 '16 at 21:18
  • It also might be informative to mention that the syntax was deprecated in ES5, so is invalid for years at the moment. – zerkms Jan 27 '16 at 21:25
  • @Barmar hmm MDN implies that the second digit is important; I'll check the spec again. *edit* looks like MDN is wrong (or badly-worded). – Pointy Jan 27 '16 at 21:27
  • @zerkms well leading-zero octal constants are not deprecated; I think it's `parseInt()` that changed. – Pointy Jan 27 '16 at 21:28
  • 1
    @Pointy they are deprecated - the syntax for octal literals was removed from ES5 https://es5.github.io/#B.1 – zerkms Jan 27 '16 at 21:29
  • Maybe it's browser-dependent. In Chrome, `0129.3` is `129.3`. – Barmar Jan 27 '16 at 21:32
  • As far as I can tell in Firefox, it's octal if all the digits are good octal digits. And zerkms is right, in strict mode octal is a syntax error. – Pointy Jan 27 '16 at 21:33
  • @Barmar I don't think so I just checked in chrome it's not equal – Lokesh Pandey Apr 06 '18 at 06:33
  • @Lokesh I just tried it again in the current version of Chrome. I typed `0129.3 === 129.3` in the console, and it replied `true`. – Barmar Apr 06 '18 at 15:39
  • @Lokesh The last line of my answer talks about strict mode. – Barmar Apr 06 '18 at 16:57
6

A leading zero indicates an octal (base 8) number (as opposed to a decimal - base 10 - number).

A leading 0x indicates a hexadecimal number, and a leading 0b a binary number.

Therefore 09.3 defaults to decimal because the digit '9' doesn't exist in octal notation.

Edit (credit Evan Trimboli, below): 02.5 throws an exception because octal literals must be integers.

andydavies
  • 3,081
  • 4
  • 29
  • 35
0

It's late for this answer but still an update from my side. As said by Pointy in strict mode octal constant are not allowed.

'use strict'
if(022 == 22){
  console.log("True");
}
console.log("Failed")

throws an exception

{
  "message": "Uncaught SyntaxError: Octal literals are not allowed in strict mode.",
  "filename": "https://stacksnippets.net/js",
  "lineno": 14,
  "colno": 4
}

Even if we add the second digit as 8 or 9 still the leading 0 are not allowed in strict mode

'use strict'
if(029 == 29){
  console.log("True");
}
console.log("Failed")

It also throws an exception

{
  "message": "Uncaught SyntaxError: Decimals with leading zeros are not allowed in strict mode.",
  "filename": "https://stacksnippets.net/js",
  "lineno": 14,
  "colno": 4
}

Also it didn't make any sense because the leading zeros are the same values without leading zeros. But it needs to be take care when receiving the values from other side.

Lokesh Pandey
  • 1,739
  • 23
  • 50