繁体   English   中英

如何使用Eclipse在Java代码中找到潜在的数字溢出?

[英]How to find potential numeric overflows in Java code, using Eclipse?

有没有办法使用Eclipse IDE在Java代码中找到潜在的数字溢出? 例如...

long aLong = X * Y * Z;

...其中X,Y和Z是整数,结果可能会溢出Integer.MAX_VALUE。 (注意,也许与直觉相反,如果此示例中的结果溢出Integer.MAX_VALUE,则将为aLong分配错误的溢出值)。

我查看了Eclipse的警告设置,PMD规则和FindBugs规则,我找不到任何设置来帮助解决这个问题。 一位同事指出,IntelliJ会对此发出警告......而且我不得不承认我不能对Eclipse做同样的事情。 ;-)


澄清1:我不是在找一些给出误报的东西......只是警告说“你这里可能有溢出问题”。

澄清2:这是“开发时间”所希望的......这意味着,在Eclipse寻找未使用的进口的同一阶段,PMD正在检查其规则等。

如果你不知道X可能是什么,那可能是最糟糕的情况。 那么,最坏的情况是什么:

 int X = Integer.MAX_VALUE;
 long aLong = X + 1;

结论:您不希望Eclipse警告您所有事情。

如果要修复整数溢出

 long aLong = X * Y * Z; //you could write
 long aLong = (long)X * Y * Z;

结论:这不能解决长溢出问题。 如果你想修复它们,你应该编写如下代码:

 BigInteger tmp = BigInteger.valueOf(X).multiply(BigInteger.valueOf(Y)).multiply(BigInteger.valueOf(Z));
 if(BigInteger.valueOf(Long.MAX_VALUE).compareTo(tmp)>=0){
  long aLong = tmp.longValue();
 }else{
  System.out.println("Overflow");
 }

但这只会检查结果值是否适合长期。 但是你问,如果在计算过程中发生了“溢出”。 这意味着每次计算后都需要检查一下。

如果你想为eclipse编写一个解析整个源文件来找到它的工具,那么我不会阻止你。 但是记住以下值会更加容易:

 /*11111111111111111111111111111111*/int Y = -1; //-1
 /*11111111111111111111111111111111*/int QRY = (Y >> 1); //-1
 /*11111111111111111111111111111110*/int QLY = (Y << 1); //-2
 /*11111111111111111111111111111110*/int QLX = (X << 1); //-2
 /*11000000000000000000000000000000*/int QRZ = (Z >> 1); //-1073741824
 /*10000000000000000000000000000000*/int Z = Integer.MIN_VALUE; //-2147483648
 /*01111111111111111111111111111111*/int X = Integer.MAX_VALUE; // 2147483647
 /*00111111111111111111111111111111*/int QRX = (X >> 1); // 1073741823
 /*00000000000000000000000000000000*/int QLZ = (Z << 1); // 0

在FindBugs中,FindPuzzlers检测器的描述包含

ICAST_INTEGER_MULTIPLY_CAST_TO_LONG(ICAST,STYLE):整数乘法的结果转换为long

但不知怎的,我不能在下面的代码中检测到这个问题:

    final int x = 10000;
    final int y = 10000;
    final int z = 10000;
    final long aLong = x * y * z;
    System.out.println(aLong);

你想在编译时这个吗? 没有看到设置这样做。

如果你真的想要它,最好的选择是最有可能为PMD写一个新的规则集?

这会是什么预期的结果?

 long testMethod () {
     long aLong =  Integer.MAX_VALUE + doesMethodContainAnOverflow ( "testMethod" ) ? 0 : 1;

     return aLong;
 }

只有在没有溢出的情况下它才会溢出。

任何固定表示整数运算都有潜在的溢出; 确定是否存在实际溢出可以简单地转换为停止问题。 这并不意味着IntelliJ在某些情况下没有一些启发式方法来警告您 - 例如,您可以通过程序跟踪任何数字操作的上限和下限,并获得最坏情况的答案,但是准确的规则既不是微不足道的,也不是可判定的。

这要么需要深入分析算法,要么只为每个涉及变量的算术运算提供警告。

编辑:哦,你的意思是如果X,Y和Z是整数,那么乘法将是整数,然后才分配给aLong? IntelliJ Idea会将其显示为警告,但默认情况下检查已关闭。

也许你可以用java.math.BigInteger进行计算并将结果与​​之比较

new java.math.BigInteger(String.valueOf(Long.MAX_VALUE))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM