Numeric Literals Prepended with '0'

Numeric literals prepended with `0`

If the number has a zero in front of it, ruby treats it as an octal number (base 8)

You can do similar with binary/hexadecimal too

0x20 => 32 (hexadecimal)
020 => 16 (octal)
0b10 => 2 (binary)
080 => Invalid octal digit

Number literal with leading zero does not result in expected value

In JavaScript, numeric literals that begin with a 0 are treated as octal.

From the MDN docs:

Octal number syntax uses a leading zero. If the digits after the 0 are outside the range 0 through 7, the number will be interpreted as a decimal number.

Using C am I right in thinking that literals beginning with multiple zeros are considered octal?

From C Standard, 6.4.4.1 Paragraph 3:

An octal constant consists of the prefix 0 optionally followed by a sequence of the digits 0 through 7 only

Starting numeric literal with 0 in php

Starting a numeric literal with 0 indicates octal notation. In the octal numeral system (base 8), there's no 9. The number 99 doesn't exist in octal.

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.

JS ES6 template literals and leading/suffix zeros to number

You can use the string function padStart by converting the number to string with toString() and then padding with padStart where the first argument is the length and the second is what to pad with.

let n = 1;
n.toString().padStart(2, "0")
//=>"01"

Why is _ getting removed from a number in javascript?

You got a numeric separator which is a proposal and actual shipping in V8 v7.5/Chrome 75.

This feature enables developers to make their numeric literals more readable by creating a visual separation between groups of digits. Large numeric literals are difficult for the human eye to parse quickly, especially when there are long digit repetitions. This impairs both the ability to get the correct value / order of magnitude...

1000000000   // Is this a billion? a hundred millions? Ten millions?
101475938.38 // what scale is this? what power of 10?

...but also fails to convey some use-case information, such as fixed-point arithmetic using integers. For instance, financial computations often work in 4- to 6-digit fixed-point arithmetics, but even storing amounts as cents is not immediately obvious without separators in literals:

const FEE = 12300;
// is this 12,300? Or 123, because it's in cents?

const AMOUNT = 1234500;
// is this 1,234,500? Or cents, hence 12,345? Or financial, 4-fixed 123.45?

Using underscores (_, U+005F) as separators helps improve readability for numeric literals, both integers and floating-point (and in JS, it's all floating-point anyway):

1_000_000_000           // Ah, so a billion
101_475_938.38 // And this is hundreds of millions

let fee = 123_00; // $123 (12300 cents, apparently)
let fee = 12_300; // $12,300 (woah, that fee!)
let amount = 12345_00; // 12,345 (1234500 cents, apparently)
let amount = 123_4500; // 123.45 (4-fixed financial)
let amount = 1_234_500; // 1,234,500

Also, this works on the fractional and exponent parts, too:

0.000_001 // 1 millionth
1e10_000 // 10^10000 -- granted, far less useful / in-range...

Some more sources:

  • ES proposal: numeric separators
  • Numeric separators

var a = 1_000;
console.log(a);

How does C Handle Integer Literals with Leading Zeros, and What About atoi?

Leading zeros indicate that the number is expressed in octal, or base 8; thus, 010 = 8. Adding additional leading zeros has no effect; just as you would expect in math, x + 0*8^n = x; there's no change to the value by making its representation longer.

One place you often see this is in UNIX file modes; 0755 actually means 7*8^2+5*8+5 = 493; or with umasks such as 0022 = 2*8+2 = 10.

atoi(nptr) is defined as equivalent to strtol(nptr, (char **) NULL, 10), except that it does not detect errors - as such, atoi() always uses decimal (and thus ignores leading zeros). strtol(nptr, anything, 0) does the following:

The string may begin with an arbitrary
amount of white space (as determined
by isspace(3)) followed by a single
optional '+' or '-' sign. If base is
zero or 16, the string may then
include a "0x" prefix, and the number
will be read in base 16; otherwise, a
zero base is taken as 10 (decimal)
unless the next character is '0', in
which case it is taken as 8 (octal).

So it uses the same rules as the C compiler.



Related Topics



Leave a reply



Submit