Why Are Integer Literals With Leading Zeroes Interpreted Strangely

Why are integer literals with leading zeroes interpreted strangely?

A leading zero denotes that the literal is expressed using octal (a base-8 number).

0123 can be converted by doing (1 * 8 * 8) + (2 * 8) + (3), which equals 83 in decimal.
For some reason, octal floats are not available.

Just don't use the leading zero if you don't intend the literal to be expressed in octal.

There is also a 0x prefix which denotes that the literal is expressed in hexadecimal (base 16).

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.

Why Integers change their value when zeros are added to the left?

A leading zero mean octal. Just like a leading 0x mean hexadecimal

Why is this happening with int?

045 is an octal (base 8):

8^2 * 0 + 8^1 * 4 + 5 = 37

45 is a decimal (base 10).


Try running this:

int j = 049;
System.out.println("j:>>" + j);

you will get "The literal 049 of type int is out of range", because octal numbers can just have digits from 0 to 7(this is why it is base 8).

Edit:

As @Gleen mentioned in a comment, an hexadecimal is leading by 0x:

int j = 0x111; // 16^2 * 1 + 16^1 * 1 + 1 = 273
System.out.println("j:>>" + j);

Output:

j:>>273 

int with leading 0's behave strangely

Sure - it's treating it as an octal literal, as per the Java Language Specification, section 3.10.1:

An octal numeral consists of an ASCII digit 0 followed by one or more of the ASCII digits 0 through 7 and can represent a positive, zero, or negative integer.

OctalNumeral:
0 OctalDigits

OctalDigits:
OctalDigit
OctalDigit OctalDigits

OctalDigit: one of
0 1 2 3 4 5 6 7

Note that octal numerals always consist of two or more digits; 0 is always considered to be a decimal numeral-not that it matters much in practice, for the numerals 0, 00, and 0x0 all represent exactly the same integer value.

Why is this happening with int?

045 is an octal (base 8):

8^2 * 0 + 8^1 * 4 + 5 = 37

45 is a decimal (base 10).


Try running this:

int j = 049;
System.out.println("j:>>" + j);

you will get "The literal 049 of type int is out of range", because octal numbers can just have digits from 0 to 7(this is why it is base 8).

Edit:

As @Gleen mentioned in a comment, an hexadecimal is leading by 0x:

int j = 0x111; // 16^2 * 1 + 16^1 * 1 + 1 = 273
System.out.println("j:>>" + j);

Output:

j:>>273 


Related Topics



Leave a reply



Submit