- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
以下内容也适用于其他 MIN_VALUE
和 MAX_VALUE
,但我们现在只关注 Integer
。我知道在 Java 中整数是 32 位的,Integer.MAX_VALUE = 2147483647
(231-1) 和 Integer.MIN_VALUE = -2147483648
(-231)。当您超出范围时使用这些值进行计算时,数字会环绕/溢出。因此,当您执行类似 Integer.MAX_VALUE + 1
的操作时,结果与 Integer.MIN_VALUE
相同。
下面是一些使用 MIN_VALUE
和 MAX_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;
}
这对大多数人来说是正确的,但不是全部。 (为了减少问题的大小,here is a TIO link 带有测试代码,而不是在此处复制粘贴。)不正确的:
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
。
最佳答案
这是一个没有按位运算的(我没有计算常量生成,它们可以写出来但会模糊它们的含义)或强制转换,正如你所看到的,它比它应该的更复杂,它会是没有 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);
}
以这种方式实现其他对的最小值/最大值可能是一件奇怪的事情。一种更合理的方法可能是仅使用正数(在 Java 中)对范围的长度取模,并将它们的上限解释为负数。
例如,如果范围是 -2 到 2,您可以通过将它们映射到模数(实际模数,而不是 Java 风格的余数)5 来将它们全部变成 0..4。然后通常的 mod-5 算法将合理地运行.最后,通过将 4 解释为 -1(在 mod-5 算术中,这是一个合理的说法)并将 3 解释为 -2,将它们映射回原始范围。
您可以将上面的代码解释为这样做,但是有一个奇怪的问题(由于涉及的范围)它必须处理有符号数字,就好像它们是无符号的一样,所以 Long.remainderUnsigned
出现了。对于小范围,这不是问题。
关于java - 再现行为 MAX_VALUE 和 MIN_VALUE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46421099/
如何实现能够将 +-Double.MAX_VALUE 作为参数处理的函数 getRandomDouble(min,max)? 在线研究: 这个问题的大多数答案是: public Double getR
我注意到了一件有趣的事情。 Java 的 Integer.MAX_VALUE 是 0x7fffffff (2147483647) Kotlin 的 Int.MAX_VALUE 是 2147483647
我只是想将 1 到 Integer.MAX_VALUE 之间的数字相加,但在输出中我什么也没得到。该计划介于两者之间。下面是我创建的类。 public class Test { public
我查看了 Double.isFinite() 的实现从 java 8 开始就存在(因为我需要 java 7 中的功能): public static boolean isFinite(double d
我想按如下方式比较两个 double 值: Double doubleValue = Double.valueOf(Long.MAX_VALUE); Double doubleValue2 = Dou
在JavaScript , Number.MAX_VALUE表示最大可表示数值(大约为 1.79E+308 ,一个相当大的数字) 但是,如果我评估 (Number.MAX_VALUE - 1) < N
我的表单中有一个 DecimalField,我想限制 min_value=0.1 和 max_value=99.99 purity_percent = forms.DecimalField(max_v
我读过有关 MAX_VALUE 的内容,发现常量可以容纳的最大值为 2^31-1。任何程序哪里需要使用 MAX_VALUE? 我也对这段堆栈代码感到困惑,如果堆栈为空,则返回 Integer.Max_
// The given input String input = "99999999.99"; // We need only 2 decimals (in case of more than 2
在 JavaScript 中,日期中年份的最大值是多少? 如何在代码中找到它? 我尝试了以下方法: new Date().getFullYear().MAX_VALUE; 提前致谢。 最佳答案 根据此
我试着理解下面的代码: int i = Integer.MAX_VALUE; double d = Double.MAX_VALUE; System.out.println(i + ":" + (i+
在我的任务中,我必须为一家燃气公司创建一个燃气表系统,以允许员工创建新的客户帐户并修改名称和单位成本等数据,以及从他们的帐户中提取(存入)资金。 我已经创建了我的构造函数,甚至添加了一个重载方法,尽管
有没有办法将vec填充到具有u64::max_value极限值的范围内? fn main() { let vals: Vec = (2..u64::max_value()).collect()
我想检查 double 是否有 Double.MAX_VALUE。 这是正确的方法吗(版本 1): boolean hasMaxVal(double val){ return val == D
我很惊讶为什么在我的机器上,数组的最大大小是 Integer.MAX_VALUE/7 我知道数组是按整数索引的,因此数组大小不能大于 Integer.MAX_VALUE。我还读了一些stackover
我想检查 double 是否有 Double.MAX_VALUE。 这是正确的方法吗(版本 1): boolean hasMaxVal(double val){ return val == D
我偶然发现了如此奇怪的代码,但我不知道为什么? public class CrazyTest { public static void main(String[] args) {
有人可以解释为什么这段代码在 Java 7,8 上是无限循环吗?当 i = Integer.MAX_VALUE + 1 时循环应该停止,但它似乎拒绝了限制。为什么会这样? public static
我有以下代码: if (maxLength>=0 && (++totalLength > maxLength)) throw new IllegalStateException("Form t
这个问题的答案可能非常明显,但我无法在 Mozilla 文档中或通过粗略搜索在 Google 上找到它。 如果你有这样的代码 Number.MAX_VALUE + 1; // Infinity, ri
我是一名优秀的程序员,十分优秀!