2009-09-16 21 views
7

有没有一种方法可以使用Eclipse IDE在Java代码中查找潜在的数值溢出?例如...如何使用Eclipse在Java代码中查找潜在的数值溢出?

long aLong = X * Y * Z; 

...其中X,Y和Z是整数并且结果可能溢出Integer.MAX_VALUE。 (请注意,如果本例中的结果溢出Integer.MAX_VALUE,aLong将被分配错误的溢出值)。

我看过Eclipse的警告设置,PMD规则和FindBugs规则,我找不到任何设置来帮助解决这个问题。一位同事指出,IntelliJ会警告这个......我不想承认我不能在Eclipse上做同样的事情。 ;-)


澄清1:我不是在寻找的东西,让0误报...只是警告说:“你可以在这里有一个溢出的问题”,

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

+0

因此,您想要警告任何算术操作吗?如果a,x和y是相同的积分类型,则a = x + y会溢出 – Mark 2009-09-17 21:42:47

+0

我希望也有这样的检查,但仅用于乘法。我正在进行比赛编程,通常值高达10^9,所以加法不是问题,但乘法是,我想要警告,否则我忘了'1L * x * y'技巧... – Betlista 2014-12-02 10:38:20

回答

-1

可能是你可以用java.math.BigInteger做你的计算,并将结果与

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

是一种没有错误地进行计算的方法,但不能检测计算是否受到特定类型的错误的影响,这就是问题所在。 – Carl 2009-09-16 21:43:51

0

你想在编译时?还没有看到一个设置来做到这一点。

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

0

对此的预期结果是什么?

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

    return aLong; 
} 

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

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

+0

问题是*潜在*溢出,这是最差的答案,正如你指出的那样,是可判定的。 该功能不是关于决定溢出,它更像是关注程序员可能没有认识到的潜在溢出点,尽管噪声可能相当高(例如,简单的可变整数的加法应该将其设置为关闭,例如)。 – Carl 2009-09-16 23:18:47

+0

有人一直在阅读GEB – Jherico 2009-09-17 05:00:36

0

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

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

+0

是的,你的编辑是正确的。我只是在寻找类似于IntelliJ Idea的警告。 – dirtyvagabond 2009-09-17 01:11:13

+0

您可以编写FindBugs规则的PMD,但我认为它不值得。 – 2009-09-17 02:34:47

1

在的FindBugs的FindPuzzlers探测器的描述包含

ICAST_INTEGER_MULTIPLY_CAST_TO_LONG(ICAST,STYLE):整数乘法投长

的结果,但不知何故,我不能让这个检测在下面的代码的问题:

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

Eclipse插件中有两个设置 - “最小报告级别”和“最小信心报告”。它的排名是17,当置信度设置为低或中时显示... – Betlista 2014-12-02 11:11:13

4

如果你不知道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 
相关问题