Why are integer literals with leading zeroes interpreted strangely?
JavaJava Problem Overview
This prints 83
System.out.println(0123)
However this prints 123
System.out.println(123)
Why does it work that way?
Java Solutions
Solution 1 - Java
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).
Solution 2 - Java
Because integer literals starting with 0
are treated as octal numbers.
See section 3.10.1 of the JLS
Solution 3 - Java
Try this:
public static String leftPad(int n, int padding) {
return String.format("%0" + padding + "d", n);
}
leftPad(5, 3); // return "005"
leftPad(15, 5); // return "00015"
leftPad(224, 3); // return "224"
leftPad(0, 4); // return "0000"
Solution 4 - Java
first one printed as 83 because java takes 0123 as octal number and it prints decimal equivalent of that number.
Solution 5 - Java
The octal (leading 0) and hexadecimal (leading 0x) were inherited from C. For comparison, try
System.out.println(0x123);
Solution 6 - Java
In Java integer literals with a leading zero are octal integers (base 8).
(1 * 8^2) + (2 * 8^1) + (3 * 8^0) = 83
So do not use any number leading with 0 if you don't want to treat it as an octal number.
Solution 7 - Java
0123 -> 83
1010L -> 1010
0101L -> 65
The numbers 1010L
and 0101L
are not in binary representation (just to avoid the confusion).
These numbers are in decimal representation.
Even as per the Regex patterns in Oracle docs,
> \0n is the character with octal value 0n (0 <= n <= 7)
> \xhh is the character with hexadecimal value 0xhh
Thus, your number 0101
be it in Integer
or Long
format is treated as an Octal representation of a number.
123 => 1 * 8^2 + 2 * 8^1 + 1 * 8^0 = 83
0101 => 1 * 8^2 + 0 * 8^1 + 1 * 8^0 = 64 + 0 + 1 = 65
Solution 8 - Java
printf
will do it: http://java.sun.com/developer/technicalArticles/Programming/sprintf/
public class X
{
public static void main(final String[] argv)
{
System.out.printf("%04d", 123);
System.out.println();
}
}
You could also make it "%0" + size + "%d"
if you wanted to vary the length... though if the lengths were common I'd probably make constants like "%04d"
, "%012d"
, etc...