重现行为MAX_VALUE和MIN_VALUE

以下内容也适用于其他MIN_VALUEMAX_VALUE ,但现在只关注Integer 。 我知道在Java中,整数是32位, Integer.MAX_VALUE = 2147483647 (2 31 -1), Integer.MIN_VALUE = -2147483648 (-2 31 )。 当你超出它们的界限时使用这些值计算时,数字会回绕/溢出。 因此,当您执行类似Integer.MAX_VALUE + 1 ,结果与Integer.MIN_VALUE相同。

以下是MIN_VALUEMAX_VALUE一些基本算术计算:

 Integer.MAX_VALUE: 2147483647 Integer.MAX_VALUE + 1: -2147483648 Integer.MAX_VALUE - 1: 2147483646 Integer.MAX_VALUE * 2: -2 Integer.MAX_VALUE * 3: 2147483645 Integer.MAX_VALUE * 4: -4 Integer.MAX_VALUE * 5: 2147483643 Integer.MAX_VALUE / Integer.MAX_VALUE: 1 Integer.MAX_VALUE * Integer.MAX_VALUE: 1 Integer.MAX_VALUE / Integer.MIN_VALUE: 0 Integer.MAX_VALUE * Integer.MIN_VALUE: -2147483648 Integer.MAX_VALUE - Integer.MIN_VALUE: -1 Integer.MAX_VALUE + Integer.MIN_VALUE: -1 -Integer.MAX_VALUE: -2147483647 -Integer.MAX_VALUE - 1: -2147483648 -Integer.MAX_VALUE + 1: -2147483646 Integer.MIN_VALUE: -2147483648 Integer.MIN_VALUE + 1: -2147483647 Integer.MIN_VALUE - 1: 2147483647 Integer.MIN_VALUE * 2: 0 Integer.MIN_VALUE * 3: -2147483648 Integer.MIN_VALUE * 4: 0 Integer.MIN_VALUE * 5: -2147483648 Integer.MIN_VALUE / Integer.MAX_VALUE: -1 Integer.MIN_VALUE / Integer.MIN_VALUE: 1 Integer.MIN_VALUE * Integer.MIN_VALUE: 0 Integer.MIN_VALUE - Integer.MAX_VALUE: 1 -Integer.MIN_VALUE: -2147483648 -Integer.MIN_VALUE - 1: 2147483647 -Integer.MIN_VALUE + 1: -2147483647 

或者更多(iff MIN == -MAX-1 ):

 MAX: MAX MAX + 1: MIN MAX - 1: MAX - 1 MAX * 2: -2 MAX * 3: MAX - 2 MAX * 4: -4 MAX * 5: MAX - 4 MAX / MAX: 1 MAX * MAX: 1 MAX / MIN: 0 MAX * MIN: MIN MAX - MIN: -1 MAX + MIN: -1 -MAX: MIN + 1 -MAX - 1: MIN -MAX + 1 MIN + 2 MIN: MIN MIN + 1: MIN + 1 MIN - 1: MAX MIN * 2: 0 MIN * 3: MIN MIN * 4: 0 MIN * 5: MIN MIN / MAX: -1 MIN / MIN: 1 MIN * MIN: 0 MIN - MAX: 1 -MIN: MIN -MIN - 1: MAX -MIN + 1: MIN + 1 

我的问题是:如何手动重现所有基本算术运算( +-*/ )?

首先想到的是模运算符。 所以我尝试了一个这样的简单方法:

 long reproduceMinMaxFromLongToInt(long n){ if(n > 2147483647L){ return n % 2147483648L; } if(n < -2147483648L){ return n % -2147483648L; } return n; } 

这对大多数人来说都是正确的,但不是全部。 (为了减少问题的大小, 这里是一个带有测试代码的TIO链接 ,而不是这里的复制粘贴。)那些不正确:

 Calculation: Should be But is instead MAX_VALUE + 1: -2147483648 0 MAX_VALUE * 2: -2 2147483646 MAX_VALUE * 4: -4 2147483644 MAX_VALUE * MIN_VALUE: -2147483648 0 MAX_VALUE - MIN_VALUE: -1 2147483647 MIN_VALUE - 1: 2147483647 -1 MIN_VALUE * 3: -2147483648 0 MIN_VALUE * 5: -2147483648 0 -MIN_VALUE - 1: 2147483647 2147483647 

其他都是正确的。

如何修改reproduceMinMaxFromLongToInt方法,以便为所有基本算术计算提供正确的结果(忽略Power,Modulo,Root等计算)?
我知道我应该在大多数情况下考虑逐位操作数,但是如果没有逐位操作数,只能使用基本算术操作数(包括模数)来重现这种行为吗?

编辑:注意: Integer仅用作示例。 当然,我可以在这种情况下转换为int 。 但我试图找出更通用的算法,它也应用于其他min / max ,如min=-100; max=99 例如, min=-100; max=99

这里有一个没有按位运算(我不计算常量生成,它们可以被写出来,但它会模糊它们的含义)或强制转换,因为你可以看到它比它应该更复杂,如果没有Java它会更糟糕8:

 long reproduceMinMaxFromLongToInt(long n){ // reduce range n = Long.remainderUnsigned(n, 1L << 32); // sign-extend if (n < (1L << 31)) return n; else return n - (1L << 32); } 

以这种方式实现其他对min / max可能是一件奇怪的事情。 一种更合理的方法可能是仅使用模数范围的正数(以Java为单位),并将它们的上限范围解释为负数。

例如,如果范围是-2到2,你可以通过以模数(实际模数,而不是Java风格的余数)映射它们将它们全部带入0..4。然后通常的mod-5算法将合理地起作用。 最后只需将它们映射回原始范围,将4解释为-1(即,在mod-5算术中,一个合理的说法),将3解释为-2。

您可以将上面的代码解释为这样做,但是有一个奇怪的问题(由于涉及的范围)它必须使用带符号的数字,好像它们是无符号的,所以Long.remainderUnsigned出现了。 对于不会出问题的小范围。

一个解决方案,虽然可能不是您想要的解决方案,但是将数字转换为int ,然后对整数进行算术运算。 你最终会转换回long以保持你的方法的合同。