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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25556017/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 00:38:51  来源:igfitidea点击:

How to use the unsigned Integer in Java 8 and Java 9?

javajava-8unsigned

提问by Pabce

In the Oracle "Primitive data types" page, it mentions that Java 8 adds support for unsigned ints and longs:

在 Oracle "Primitive data types" page 中,它提到 Java 8 添加了对无符号整数和长整数的支持:

int: By default, the intdata type is a 32-bit signed two's complement integer, which has a minimum value of ?231and a maximum value of 231?1. In Java SE 8 and later, you can use the intdata type to represent an unsigned 32-bit integer, which has a minimum value of 0 and a maximum value of 232?1.Use the Integerclass to use intdata type as an unsigned integer. See the section The Number Classes for more information. Static methods like compareUnsigned, divideUnsignedetc have been added to the Integerclass to support the arithmetic operations for unsigned integers.

long: The longdata type is a 64-bit two's complement integer. The signed longhas a minimum value of ?263and a maximum value of 263?1. In Java SE 8 and later, you can use the longdata type to represent an unsigned 64-bit long, which has a minimum value of 0 and a maximum value of 264?1.Use this data type when you need a range of values wider than those provided by int. The Longclass also contains methods like compareUnsigned, divideUnsignedetc to support arithmetic operations for unsigned long.

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

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

However, I find no way to declare an unsigned long or integer. The following code, for example, gives a compiler error message of "the literal is out of range" (I'm using Java 8, of course), when it should be in range (the value assigned is precisely 264?1):

但是,我找不到声明无符号长整数或整数的方法。例如,以下代码给出了“文字超出范围”的编译器错误消息(当然,我使用的是 Java 8),当它应该在范围内时(分配的值正好是 2 64?1) :

public class Foo {
    static long values = 18446744073709551615L;

    public static void main(String[] args){
        System.out.println(values);
    }  
}

So, is there any way to declare an unsigned int or long?

那么,有没有办法声明一个 unsigned int 或 long?

采纳答案by Sbodd

Per the documentation you posted, and this blog post- there's no difference when declaring the primitive between an unsigned int/long and a signed one. The "new support" is the addition of the static methods in the Integer and Long classes, e.g. Integer.divideUnsigned. If you're not using those methods, your "unsigned" long above 2^63-1 is just a plain old long with a negative value.

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

From a quick skim, it doesn't look like there's a way to declare integer constants in the range outside of +/- 2^31-1, or +/- 2^63-1 for longs. You would have to manually compute the negative value corresponding to your out-of-range positive value.

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

回答by kajacx

Well, even in Java 8, longand intare still signed, only some methods treat them as if they were unsigned. If you want to write unsigned longliteral like that, you can do

好吧,即使在 Java 8 中,long并且int仍然是有符号的,只有一些方法将它们视为 unsigned。如果你想写这样的无符号long文字,你可以这样做

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

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

回答by 1ac0

There is no way how to declarean unsigned long or intin Java 8 or Java 9. But some methods treat them as if they were unsigned, for example:

有没有办法如何来声明一个无符号长或者int在Java中8或Java 9.但有些方法对待他们,好像他们是无符号,例如:

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

but this is not declarationof the variable.

但这不是变量的声明

回答by blueberry0xff

    // Java 8
    int vInt = Integer.parseUnsignedInt("4294967295");
    System.out.println(vInt); // -1
    String sInt = Integer.toUnsignedString(vInt);
    System.out.println(sInt); // 4294967295

    long vLong = Long.parseUnsignedLong("18446744073709551615");
    System.out.println(vLong); // -1
    String sLong = Long.toUnsignedString(vLong);
    System.out.println(sLong); // 18446744073709551615

    // Guava 18.0
    int vIntGu = UnsignedInts.parseUnsignedInt(UnsignedInteger.MAX_VALUE.toString());
    System.out.println(vIntGu); // -1
    String sIntGu = UnsignedInts.toString(vIntGu);
    System.out.println(sIntGu); // 4294967295

    long vLongGu = UnsignedLongs.parseUnsignedLong("18446744073709551615");
    System.out.println(vLongGu); // -1
    String sLongGu = UnsignedLongs.toString(vLongGu);
    System.out.println(sLongGu); // 18446744073709551615

    /**
     Integer - Max range
     Signed: From ?2,147,483,648 to 2,147,483,647, from ?(2^31) to 2^31 – 1
     Unsigned: From 0 to 4,294,967,295 which equals 2^32 ? 1

     Long - Max range
     Signed: From ?9,223,372,036,854,775,808 to 9,223,372,036,854,775,807, from ?(2^63) to 2^63 ? 1
     Unsigned: From 0 to 18,446,744,073,709,551,615 which equals 2^64 – 1
     */

回答by Lukas Eder

If using a third party library is an option, there is jOOU(a spin off library from jOOQ), which offers wrapper types for unsigned integer numbers in Java. That's not exactly the same thing as having primitive type (and thus byte code) support for unsigned types, but perhaps it's still good enough for your use-case.

如果使用第三方库是一种选择,则有jOOU(来自jOOQ的衍生库),它为 Java 中的无符号整数提供包装器类型。这与为无符号类型提供原始类型(以及字节码)支持并不完全相同,但对于您的用例来说,它可能仍然足够好。

import static org.joou.Unsigned.*;

// and then...
UByte    b = ubyte(1);
UShort   s = ushort(1);
UInteger i = uint(1);
ULong    l = ulong(1);

All of these types extend java.lang.Numberand can be converted into higher-order primitive types and BigInteger.

所有这些类型都扩展java.lang.Number并可以转换为高阶原始类型和BigInteger.

(Disclaimer: I work for the company behind these libraries)

(免责声明:我为这些库背后的公司工作)