Java 中的 UnsignedInt 运算

UnsignedInt operations in Java

我觉得很清楚了,但我肯定还是决定问了。

如果我有这样的东西。

int secs=2power32-1 //Unsigned int read from file as Java sign. int.
if(Integer.compareUnsigned(secs,3600)>=0){ //Get hours from secs.
start[0]=Integer.divideUnsigned(secs,3600);
secs=secs-start[0]*3600;
}

if(Integer.compareUnsigned(secs,60)>=0){ // Get min. from secs.
 ...
}

我不是 100% 确定第二次比较计算的数字(秒)正确。

请问有人知道证明吗?

非常感谢。

测试计算的一种方法是将原始 unsigned int 转换为等效的 long,然后使用常规运算符执行计算:

String bin = Integer.toBinaryString (-1); // -1 is the int number having the highest
                                          // value as unsigned int - (2^32-1)
long secsl = Long.parseLong (bin, 2); // will result in 4294967295
if(secsl >=3600){ //Get hours from secs.
  long temp = secsl / 3600;
  secsl=secsl-temp*3600;
}

if(secsl >= 60){ // Get min. from secs.
  ...
}

secsl 应与代码段中 secs 的无符号值具有相同的值(您可以通过调用 Integer.toUnsignedString(secs).

查看

P.S.

在两个片段(你的和我的)中,第二个条件为真,因为 secslsecs 都是 1695。因此你的计算是正确的。

我相信肯定可以用这个:

secs=Integer.remainderUnsigned(secs,3600);

但是正如 Eran 所说,结果总是 secs=1695 无论是使用正常差分来计算无符号数的余数表示为有符号数还是由无符号数计算余数

如果有人知道按位证明我会很高兴看到它。

是的,secs = secs-start[0]*3600 符合您的预期。

Integer 没有无符号方法的加法、减法和乘法方法的原因是它们与有符号运算完全相同(逐位)。例如,如果您执行 65535*65537,您将得到 -1。解释为 unsigned int,这些位如您所料得到 2^31-1。

这在早期的计算机中非常重要属性,因为这意味着计算机不需要为有符号和无符号操作提供单独的指令和逻辑。

为了证明,您真的只需要了解那些对整数的运算 (* + -) 都适用于 mod 2^32。当您将负 int 解释为无符号值时,您分配给它的无符号值等于有符号值 + 2^32。值mod2^32完全一样