当前位置: 首页 > 知识库问答 >
问题:

JAVA整数溢出阴谋

仲和韵
2023-03-14

由于溢出,下面代码中的第一个for循环找不到正确的最大值。然而,第二个for循环确实如此。我用了门闩。com查看该程序的字节码,该程序显示,要确定哪个数字更大,第一个for循环使用isub,第二个for循环使用if_icmple。有道理。然而,为什么if_icmple能够成功地进行这种比较,因为它在某些时候也必须进行减法运算(我认为这会产生溢出)?

public class Overflow {
   public static void main(String[] args) {
      int[] nums = {3,-2147483648, 5, 7, 27, 9};
       
      int curMax = nums[0];
      for (int num : nums) {
         int diff = curMax - num; 
         if (diff < 0) {
            curMax = num;
         }
      }
      System.out.println("1) max is " + curMax);
       
      curMax = nums[0];
      for (int num : nums) {
         if (num > curMax) {
            curMax = num;
         }
      }  
      System.out.println("2) max is " + curMax);        
   }   
}

输出是

  1. 最大值为-2147483648

共有2个答案

昝卓
2023-03-14

然而,为什么if_icmple能够成功地进行这种比较,因为它在某个时候也必须做减法(我预计会产生溢出)?

它不需要做减法运算。它只需要做一个比较。比较不必涉及减法,当然也不必涉及CPU。

安奇
2023-03-14

假设比较是使用减法实现的。与这里的其他各种观点相反,我认为这很有可能。例如x86上的cmp只是一个不更新目标寄存器的减法,只更新标志。其他各种(但可能不是所有)有标志寄存器的处理器也是这样工作的。在接下来的回答中,我将使用x86作为一个代表性的处理器来举例

但是,代码隐含了一个错误的假设:比较并不等同于先进行减法,然后检查符号,它相当于先进行减法,然后检查零、符号和溢出标志的组合。例如,如果实现if(num

小于或等于(ZF=1或SF)时短跳转≠ 当然)。

表达条件SF≠ 直接在Java中使用并非易事。但是JVM本身没有这样的问题,它可以使用比较(或者,相当于减法),然后使用完全正确的条件跳转。

有一些不太幸运的处理器没有像x86那样的全套条件跳转,但是即使在这种情况下,JVM也比你有更多的选择。

JVM没有的选项是错误地实现比较。

 类似资料:
  • 我在一次采访中被问及这一点。我被要求计算数字x1,x2,x3,…的平均值,。。。xn公司 //所以归结起来是这样的: 面试官说列表的大小是未知的,它可能很大,所以总和可能会溢出。他问我如何解决溢出问题,我的回答是跟踪我们可能超过最大数量的次数等等,他说了一些关于推入堆栈、平均值和长度的事情,我从来没有真正理解他的解决方案,将这两个变量推入某种列表中?有人知道吗?

  • 虚拟机安装:Ubuntu 12.04(x86) 什么是整数溢出? 存储大于最大支持值的值称为整数溢出。整数溢出本身不会导致任意代码执行,但整数溢出可能会导致堆栈溢出或堆溢出,这可能导致任意代码执行。在这篇文章中,我将仅谈论整数溢出导致堆栈溢出,整数溢出导致堆溢出将在后面的单独的帖子中讨论。 数据类型大小及范围: 当我们试图存储一个大于最大支持值的值时,我们的值会被包装 。例如,当我们尝试将存储到带

  • 本文向大家介绍C#整数溢出,包括了C#整数溢出的使用技巧和注意事项,需要的朋友参考一下 示例 整数可以存储的最大容量。而当您超过该限制时,它将循环回到负面。对于int,它是2147483647 对于超出此范围的所有整数,请使用System.Numerics数据类型为BigInteger的名称空间。检查下面的链接以获取更多信息https://msdn.microsoft.com/zh-cn/libr

  • 这是LeetCode中的Pascal三角形编码问题,它要求输出Pascal三角形的第n行。使用,输出如下所示: 显然存在溢出问题。现在为了解决这个问题,我修改了行< code > result . push _ back(result[I-1]*(rowIndex 1-I)/I);到< code > result . push _ back((double)result[I-1]*(double)

  • 我一直在考虑整数(int类型)溢出,我突然想到除法可能溢出。 示例:在我当前的平台上 因此 因此 因此 因此,除法 (INT_MIN / -1 ) 确实溢出。 因此,我有两个问题: > 可以编写哪些(跨平台)C代码来防止除法溢出(对于类型(有符号)int)? 什么保证(在C或C标准中)可能有助于设计代码? 例如,如果标准保证我们有 或者 然后出现以下代码来防止溢出。

  • 问题内容: 有了这段代码,我得到了这个答案。为什么我得到负值? 问题答案: 在您的平台上,np.arange返回dtype’int32’的数组: 数组的每个元素都是32位整数。平方导致结果不适合32位。结果被裁剪为32位,并且仍然解释为32位整数,这就是为什么看到负数的原因。 编辑: 在这种情况下,可以通过在平方之前构造dtype’int64’数组来避免整数溢出: 请注意,使用numpy时,发现的