如何在 Java 8 和 Java 9 中使用无符号整数?

2022-08-31 11:20:46

在Oracle的“基元数据类型”页面中,它提到Java 8增加了对无符号整数和长整型的支持:

int:默认情况下,数据类型为 32 位有符号二进制补码整数,其最小值为 −231,最大值为 231−1。在 Java SE 8 及更高版本中,可以使用 int 数据类型来表示无符号的 32 位整数,其最小值为 0,最大值为 232−1。使用该类可将数据类型用作无符号整数。有关详细信息,请参阅数字类部分。像 等静态方法已被添加到类中以支持无符号整数的算术运算。intIntegerintcompareUnsigneddivideUnsignedInteger

long:数据类型为 64 位二进制补码整数。有符号的最小值为 −263,最大值为 263−1。在 Java SE 8 及更高版本中,可以使用 long 数据类型来表示无符号的 64 位 long,其最小值为 0,最大值为 264−1。当您需要比 int 提供的值范围更宽的值范围时,请使用此数据类型。该类还包含诸如 等方法,以支持无符号的算术运算。longlongLongcompareUnsigneddivideUnsignedlong

但是,我发现没有办法声明无符号长整型或整数。例如,下面的代码给出了编译器错误消息“文本超出范围”(当然,我使用的是Java 8),当它应该在范围内时(分配的值恰好是264−1):

public class Foo {
    static long values = 18446744073709551615L;
    
    public static void main(String[] args){
        System.out.println(values);
    }  
}

那么,有没有办法声明一个无符号的int或long呢?


答案 1

好吧,即使在Java 8中,并且仍然带有签名,只有一些方法将它们视为未签名。如果你想像那样写无符号的文字,你可以做longintlong

static long values = Long.parseUnsignedLong("18446744073709551615");

public static void main(String[] args) {
    System.out.println(values); // -1
    System.out.println(Long.toUnsignedString(values)); // 18446744073709551615
}

答案 2

根据您发布的文档和这篇博客文章 - 在声明无符号 int/long 和有符号 int/long 之间的基元时没有区别。“新支持”是在 Integer 和 Long 类中添加静态方法,例如 Integer.divideUnsigned。如果您没有使用这些方法,那么您高于 2^63-1 的“无符号”多头只是一个具有负值的普通旧多头。

从快速浏览来看,似乎没有一种方法可以在 +/- 2^31-1 或多头 +/- 2^63-1 的范围内声明整数常量。您必须手动计算与超出范围的正值相对应的负值。


推荐