Java Enum数据长值设置为零

时间:2016-01-15 17:46:24

标签: java enums primitive-types

鉴于下面的枚举,

enum SizeUnits {

    Bytes(1),
    Kilobytes(1024),
    Megabytes(1024 * 1024),
    Gigabytes(1024 * 1024 * 1024),
    Terabytes(1024 * 1024 * 1024 * 1024),
    Petabytes(1024 * 1024 * 1024 * 1024 * 1024);
    private final long multiplier;

    private SizeUnits(long mult) {
        this.multiplier = mult;
        System.out.println("mult="+mult);
    }
}

我得到以下输出:

mult=1
mult=1024
mult=1048576
mult=1073741824
mult=0
mult=0

显然,最后两个是内部剪裁,我不明白为什么。考虑到我使用longclaimed max value for long with Java 8是:enter image description here,它看起来应该不应该是这样的: 2^64-1

如果它是以整数的大小剪裁,我本来期望它也剪辑1073741824。此外,它不仅仅是环绕,而是实际将值剪切为零。

为什么它将最后两个条目剪辑为零?


更新

阿。文字的类型。当然。

注意(如下面的答案所述)如果我将L作为该行的最后一个条目,它仍然会溢出更大的情况,因为显然它没有将操作提升为{{ 1}}在溢出之前。

现在,当尝试通过

进行投射时,为什么它不起作用是有道理的
long

但这有效:

(long)(1024 * 1024 * 1024 * 1024 * 1024)

它是什么时候溢出的问题。谢谢大家!

3 个答案:

答案 0 :(得分:7)

最后两次溢出。它们等于2^402^50
哪个不适合int。这些是整数,而不是长 将L添加到1024值中的第一个:

Terrabytes(1024L * 1024 * 1024 * 1024)

当你添加L时,你明确表示它很长。
然后其他操作数也被提升为长,
结果不会溢出。

另请尝试:

1)long x = 1024 * 1024 * 1024 * 1024 * 1024;
2)long y = 1024L * 1024 * 1024 * 1024 * 1024;

查看您在xy中获得的值。

答案 1 :(得分:2)

你所谓的“剪辑”是数字溢出。你反复乘以(int)2的幂,直到它们溢出。因为只保留低32位,所以得到0因为唯一要设置的位超出了低位32位。

如果您有千兆字节值(1024 * 1024 * 1024),则int已经是2 ^ 30:

01000000 00000000 00000000 00000000

当乘以另一个1024时,如果精度允许,你会得到这个:

1 00000000 00000000 00000000 00000000 00000000

但只保留低位32位,即0

您可以将第一个1024投射到long或使用long字面值。 (它必须是第一个文字,以确保long算术整个过程并避免中间溢出。)

(long) 1024 * 1024 * 1024 * 1024

1024L * 1024 * 1024 * 1024

long有64位,足以满足您的需要(2 50 )。但是,如果你继续前进,你需要大于Long.MAX_VALUE,2 63 -1的值,那么切换到使用BigInteger s。

答案 2 :(得分:1)

您只是将计算结果转换为long。 2 ^ 32的任何倍数都将溢出为0.

另一种写作方式是

enum SizeUnits {

    Bytes(1L << 0),
    Kilobytes(1L << 10),
    Megabytes(1L << 20),
    Gigabytes(1L << 30),
    Terrabytes(1L << 40),
    Petabytes(1L << 50),
    Exabytes(1L << 60);
    private final long multiplier;

    private SizeUnits(long mult) {
        this.multiplier = mult;
        System.out.println(name() + ": mult=" + mult);
    }
}