在Java中是否有一种方法来声明无符号整型?
或者这个问题也可以是这样的: Java中与unsigned等价的是什么?
只是为了告诉你上下文,我正在查看Java的String.hashcode()的实现。我想测试如果整数是32 unsigned int,碰撞的可能性。
在Java中是否有一种方法来声明无符号整型?
或者这个问题也可以是这样的: Java中与unsigned等价的是什么?
只是为了告诉你上下文,我正在查看Java的String.hashcode()的实现。我想测试如果整数是32 unsigned int,碰撞的可能性。
当前回答
对于无符号数字,您可以使用这些类从Guava库:
UnsignedInteger UnsignedLong
它们支持各种操作:
+ - 次 国防部 除以
目前似乎缺少的是字节移位操作符。如果需要,可以从Java中使用BigInteger。
其他回答
可以使用Math.abs(number)函数。它返回一个正数。
也许这就是你的意思?
long getUnsigned(int signed) {
return signed >= 0 ? signed : 2 * (long) Integer.MAX_VALUE + 2 + signed;
}
getUnsigned(0) → 0 getUnsigned(1) → 1 getUnsigned(Integer.MAX_VALUE) → 2147483647 getUnsigned(Integer.MIN_VALUE) → 2147483648 获取未签名(Integer.MIN_VALUE+1) → 2147483649
Java没有无符号整数的数据类型。
如果需要存储较大的值,可以定义long类型而不是int类型。
也可以像使用无符号整数一样使用有符号整数。two的补体表示的好处是,对于有符号整数和无符号整数,大多数操作(如加法、减法、乘法和左移)在二进制级别上是相同的。但是,有一些操作(除法、右移、比较和强制转换)是不同的。从Java SE 8开始,Integer类中的新方法允许您完全使用int数据类型来执行无符号算术:
在Java SE 8及更高版本中,可以使用int数据类型表示无符号32位整数,其最小值为0,最大值为2^32-1。使用Integer类将int数据类型用作无符号整数。像compareUnsigned, divideUnsigned等静态方法已经添加到Integer类中,以支持无符号整数的算术操作。
注意,int变量在声明时仍然是有符号的,但现在可以使用Integer类中的这些方法进行无符号算术。
这里有很好的答案,但我没有看到任何逐位操作的演示。正如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)
This initializes the array, see Are byte arrays initialised to zero in Java?. Now you have to fill each byte in the array with information in the big-endian order (or little-endian if you want to wreck havoc). Assuming you have a long containing the time (long integers are 64 bits long in Java) called secondsSince1900 (Which only utilizes the first 32 bits worth, and you‘ve handled the fact that Date references 12:00 A.M. January 1, 1970), then you can use the logical AND to extract bits from it and shift those bits into positions (digits) that will not be ignored when coersed into a Byte, and in big-endian order.
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现在等价于一个符合RCF 868标准的32位无符号大端整数。是的,长数据类型是有符号的,但是我们忽略了这个事实,因为我们假设secondsSince1900只使用了低32位)。由于将long强制转换为字节,所有高于2^7(十六进制中的前两位)的位将被忽略。
参考资料:Java网络编程,第4版。
对于无符号数字,您可以使用这些类从Guava库:
UnsignedInteger UnsignedLong
它们支持各种操作:
+ - 次 国防部 除以
目前似乎缺少的是字节移位操作符。如果需要,可以从Java中使用BigInteger。