为什么带前导零的整数字面值会被奇怪地解释?

69

这将打印出83

System.out.println(0123)

然而,这会打印出123。

System.out.println(123)

为什么它会这样运行?

8个回答

109

前导零表示使用八进制(一种八进制数字)表示文本。

0123可以通过进行(1 * 8 * 8) + (2 * 8) + (3)来转换,这在十进制中等于83。由于某种原因,八进制浮点数不可用。

如果您不打算使用八进制文字,请勿使用前导零。

还有一个0x前缀,表示该文字以十六进制(基数16)表示。


16

由于以0开头的整数字面量会被视为八进制数。

请参见JLS第3.10.1节


9

试试这个:

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"

4

八进制(前导0)和十六进制(前导0x)是从C语言继承而来的。 为了进行比较,请尝试

System.out.println(0x123);

4

第一个输出为83,因为Java将0123视为八进制数,并打印该数字的十进制等效值。


2
在Java中,以0开头的整数字面值是八进制整数(基数为8)。
(1 * 8^2) + (2 * 8^1) + (3 * 8^0) = 83

如果您不想将数字视为八进制数,请勿使用以0开头的任何数字。


1
0123 -> 83
1010L -> 1010  
0101L -> 65

这些数字1010L0101L不是二进制表示(仅为避免混淆)
这些数字是十进制表示。
即使根据Oracle docs中的正则表达式模式,

\0n是具有八进制值0n(0 <= n <= 7)的字符
\xhh是具有十六进制值0xhh的字符

因此,您的数字0101IntegerLong格式表示时被视为数字的八进制表示。
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

0

printf可以做到: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();
    }
}

如果您想要改变长度,也可以将其设置为"%0" + size + "%d"... 不过如果长度是固定的,我可能会创建像"%04d""%012d"等常量。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接