有没有一种方法可以在Java中声明一个无符号的int?
或也可以这样构成问题:Java的unsigned等同于什么?
只是为了告诉您上下文,我正在查看Java的实现String.hashcode()
。我想测试整数是否为32 unsigned int时发生冲突的可能性。
>>>
operator而不是进行右移而无需扩展符号>>
。
有没有一种方法可以在Java中声明一个无符号的int?
或也可以这样构成问题:Java的unsigned等同于什么?
只是为了告诉您上下文,我正在查看Java的实现String.hashcode()
。我想测试整数是否为32 unsigned int时发生冲突的可能性。
>>>
operator而不是进行右移而无需扩展符号>>
。
Answers:
Java没有无符号整数的数据类型。
如果需要存储较大的值,可以定义一个,long
而不是一个int
。
您也可以使用带符号的整数,就好像它是无符号的一样。二进制补码表示法的好处是,对于有符号和无符号整数,大多数操作(例如加法,减法,乘法和左移)在二进制级别上都是相同的。但是,一些操作(除法,右移,比较和转换)是不同的。从Java SE 8开始,Integer
该类中的新方法允许您完全使用int
数据类型来执行无符号算术:
在Java SE 8和更高版本中,可以使用int数据类型表示无符号的32位整数,其最小值为0,最大值为2 ^ 32-1。使用Integer类可将int数据类型用作无符号整数。像静态方法
compareUnsigned
,divideUnsigned
等已被添加到Integer类支持算术运算的无符号整数。
请注意,int
变量在声明时仍然是带符号的,但是现在可以通过使用Integer
类中的这些方法来进行无符号算术运算。
int
数据类型表示无符号的32位整数,其最小值为0
,最大值为2^32-1
。-请参阅docs.oracle.com/javase/tutorial/java/nutsandbolts/…和docs.oracle.com/javase/8/docs/api/java/lang/Integer.html
int
就像通过各种方法将其无符号一样。
Integer
Java 8 中的类允许一个人使用unsigned int,则它只是空间和速度之间的差异(因为在C / C ++中它们是原始的,而在Java中则是整个对象包装器)
int
即使已签名也要翻转。这是C / C ++,未签名会翻转,但是签名会在溢出时导致“未定义行为”。如果“转存”是您唯一关心的问题,则不需要未签名。我想这就是CRC例程等在Java中无需额外努力即可工作的原因。这就是为什么新的API仅添加解析,格式化,比较,除法和余数的原因。无论如何,所有其他操作(即所有位操作)以及加,减,乘等操作都在做正确的事情。
int中的值是带符号的还是无符号的,取决于位的解释方式-Java将位解释为带符号的值(它没有无符号的原语)。
如果您有一个要解释为无符号值的int(例如,从知道包含无符号值的DataInputStream中读取一个int),则可以执行以下操作。
int fourBytesIJustRead = someObject.getInt();
long unsignedValue = fourBytesIJustRead & 0xffffffffl;
请注意,十六进制文字是长文字而不是int文字很重要-因此结尾处是“ l”。
0xFFFFFF
并保留int吗?
我们需要的无符号数来模拟MySQL的签名TINYINT
,SMALLINT
,INT
,BIGINT
在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);
所有这些类型java.lang.Number
都可以扩展,并且可以转换为高阶基本类型和BigInteger
。希望这可以帮助。
(免责声明:我为这些库背后的公司工作)
使用char
16位无符号整数。
也许这就是你的意思?
long getUnsigned(int signed) {
return signed >= 0 ? signed : 2 * (long) Integer.MAX_VALUE + 2 + signed;
}
getUnsigned(0)
→0getUnsigned(1)
→1getUnsigned(Integer.MAX_VALUE)
→2147483647getUnsigned(Integer.MIN_VALUE)
→2147483648getUnsigned(Integer.MIN_VALUE + 1)
→21474836492 * (long) Integer.MAX_VALUE + 2
比这更容易理解0x1_0000_0000L
吗?在这方面,为什么不简单return signed & 0xFFFF_FFFFL;
?
这里有很好的答案,但是我看不到按位运算的任何演示。就像Visser(当前接受的答案)所说的那样,Java默认对整数进行符号处理(Java 8具有无符号整数,但我从未使用过它们)。事不宜迟,让我们开始吧...
如果您需要向IO写入无符号整数会怎样?实际示例是您要根据RFC 868输出时间时。这需要一个32位,大端无符号整数,该整数对自1900年1月1日12:00 AM以来的秒数进行编码。如何编码?
声明一个4字节(32位)的字节数组
Byte my32BitUnsignedInteger[] = new Byte[4] // represents the time (s)
这将初始化数组,请参见Java中字节数组是否初始化为零?。现在,您必须按照大端顺序(或小端顺序,如果要破坏)来用信息填充数组中的每个字节。假设您有一个包含时间的长整数(Java中长整数为64位长)secondsSince1900
(其中仅利用了前32位,并且您已经处理了Date引用1970年1月1日12:00 AM的事实),然后您可以使用逻辑与从中提取位,然后将这些位移到以大端顺序将其强制转换为字节时不会忽略的位置(数字)。
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位big-endian整数。是的,long数据类型是带符号的,但是我们忽略了这一事实,因为我们假设secondsSince1900仅使用低32位。由于将long强制转换为一个字节,所有高于2 ^ 7(十六进制的前两位)的位都将被忽略。
参考源:Java网络编程,第4版。
刚编写了这段代码,就将“ this.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);
}
您可以使用Math.abs(number)函数。它返回一个正数。
MIN_VALUE
0