在Java中声明一个无符号整型

在Java中是否有一种方法来声明无符号整型?

或者这个问题也可以被框定为: Java中与unsigned等价的是什么?< / p >

只是告诉你上下文,我正在查看Java的String.hashcode()的实现。我想测试如果整数是32 unsigned int,碰撞的可能性。

625643 次浏览

Java没有无符号整数的数据类型。

如果需要存储较大的值,可以定义long而不是int

也可以像使用无符号整数一样使用有符号整数。二补体表示法的好处是,对于有符号整数和无符号整数,大多数操作(如加法、减法、乘法和左移)在二进制级别上是相同的。但是,有一些操作(除法、右移、比较和强制转换)是不同的。从Java SE 8开始,Integer类中的新方法允许你完全使用int数据类型执行无符号算术:

在Java SE 8及更高版本中,可以使用int数据类型表示无符号32位整数,其最小值为0,最大值为2^32-1。使用Integer类将int数据类型用作无符号整数。静态方法如compareUnsigneddivideUnsigned等已添加到Integer类中,以支持无符号整数的算术操作。

注意,int变量在声明时仍然是有符号的,但现在可以通过使用Integer类中的这些方法进行无符号算术。

可以使用Math.abs(number)函数。它返回一个正数。

int中的值是有符号还是无符号取决于位是如何解释的——Java将位解释为有符号值(它没有无符号原语)。

如果你有一个int,你想解释为一个无符号值(例如,你从DataInputStream读取一个int,你知道应该解释为一个无符号值),那么你可以做下面的技巧。

int fourBytesIJustRead = someObject.getInt();
long unsignedValue = fourBytesIJustRead & 0xffffffffL;

注意,重要的是十六进制字面值是一个长字面值,而不是int字面值-因此'L'在末尾。

对于无符号数字,可以使用番石榴库中的这些类:

它们支持各种操作:

  • +
  • -
  • 国防部
  • 除以

目前似乎缺少的是字节移位操作符。如果需要,可以从Java中使用BigInteger。

我们需要无符号数字来建模MySQL的无符号TINYINTSMALLINTINTBIGINT中的jOOQ,这就是为什么我们创建了jOOU,这是一个在Java中为无符号整数提供包装器类型的极简库。例子:

import static org.joou.Unsigned.*;


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

所有这些类型都扩展了java.lang.Number,并且可以转换为更高阶的基元类型和BigInteger。希望这能有所帮助。

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

也许这就是你的意思?

long getUnsigned(int signed) {
return signed >= 0 ? signed : 2 * (long) Integer.MAX_VALUE + 2 + signed;
}
  • __abc0→0
  • __abc0→1
  • __abc0→2147483647
  • __abc0→2147483648
  • __abc0→2147483649

对16位无符号整数使用char

只是做了这段代码,它转换了“这个”。Altura "从负数到正数。希望这能帮助到需要帮助的人

       if(this.altura < 0){


String aux = Integer.toString(this.altura);
char aux2[] = aux.toCharArray();
aux = "";
for(int con = 1; con < aux2.length; con++){
aux += aux2[con];
}
this.altura = Integer.parseInt(aux);
System.out.println("New Value: " + this.altura);
}

似乎你可以通过在使用值之前对它们进行“逻辑与”来处理签名问题:

示例(byte[] header[0]的值为0x86):

System.out.println("Integer "+(int)header[0]+" = "+((int)header[0]&0xff));

结果:< br >

Integer -122 = 134

这里有很好的答案,但我没有看到任何逐位操作的演示。正如Visser(目前接受的答案)所说,Java默认为整数加符号(Java 8有无符号整数,但我从未使用过它们)。废话不多说,我们开始吧……

RFC 868使用实例

如果需要向IO写入无符号整数会发生什么?实际的例子是当你想根据RFC 868输出时间。这需要一个32位的大端序无符号整数,用于编码从12:00 A.M.开始的秒数1900年1月1日。怎么编码呢?

创建自己的32位无符号整数,如下所示:

声明一个4字节(32位)的字节数组

Byte my32BitUnsignedInteger[] = new Byte[4] // represents the time (s)

这将初始化数组,参见在Java中字节数组初始化为零吗?。现在,您必须以大端序(如果您想破坏破坏,则可以用小端序)的信息填充数组中的每个字节。假设你有一个名为secondsSince1900的long包含时间(长整数在Java中是64位长)(它只利用前32位的值,并且你已经处理了Date引用12:00 A.M.的事实1970年1月1日),然后您可以使用逻辑与从其中提取位,并将这些位转换为在强制转换为字节时不会被忽略的位置(数字),并以大端序排列。

my32BitUnsignedInteger[0] = (byte) ((secondsSince1900 & 0x00000000FF000000L) >> 24); // first byte of array contains highest significant bits, then shift these extracted FF bits to first two positions in preparation for coersion to Byte (which only adopts the first 8 bits)
my32BitUnsignedInteger[1] = (byte) ((secondsSince1900 & 0x0000000000FF0000L) >> 16);
my32BitUnsignedInteger[2] = (byte) ((secondsSince1900 & 0x000000000000FF00L) >> 8);
my32BitUnsignedInteger[3] = (byte) ((secondsSince1900 & 0x00000000000000FFL); // no shift needed

我们的my32BitUnsignedInteger现在等价于一个32位无符号大端整数,符合RCF 868标准。是的,长数据类型是有符号的,但是我们忽略了这个事实,因为我们假设secondsSince1900只使用了低32位)。由于将long强制转换为字节,所有高于2^7(十六进制中的前两位)的位将被忽略。

参考资料:Java网络编程,第4版。