简体   繁体   English

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

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

Is there a way to find potential numeric overflows in Java code, using the Eclipse IDE? 有没有办法使用Eclipse IDE在Java代码中找到潜在的数字溢出? For example... 例如...

long aLong = X * Y * Z;

... where X, Y, and Z are ints and the result may overflow Integer.MAX_VALUE. ...其中X,Y和Z是整数,结果可能会溢出Integer.MAX_VALUE。 (Note that, perhaps counter-intuitively, if the result in this example overflows Integer.MAX_VALUE, aLong will be assigned the erroneous overflowed value). (注意,也许与直觉相反,如果此示例中的结果溢出Integer.MAX_VALUE,则将为aLong分配错误的溢出值)。

I've looked in Eclipse's Warnings settings, PMD rules, and FindBugs rules and I can't find any setting to help with this. 我查看了Eclipse的警告设置,PMD规则和FindBugs规则,我找不到任何设置来帮助解决这个问题。 A co-worker notes that IntelliJ will warn about this... and I'd hate to have to admit that I can't do the same with Eclipse. 一位同事指出,IntelliJ会对此发出警告......而且我不得不承认我不能对Eclipse做同样的事情。 ;-) ;-)


Clarification 1: I'm not looking for something that gives 0 false positives... just warnings that "you may have an overflow problem here"., 澄清1:我不是在找一些给出误报的东西......只是警告说“你这里可能有溢出问题”。

Clarification 2: This is desired at "development time"... meaning, at the same stage that Eclipse is looking for unused imports, PMD is checking its rules, etc. 澄清2:这是“开发时间”所希望的......这意味着,在Eclipse寻找未使用的进口的同一阶段,PMD正在检查其规则等。

If you do not know what X could be, it could be the worst case. 如果你不知道X可能是什么,那可能是最糟糕的情况。 So, what is the worst case: 那么,最坏的情况是什么:

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

Conclusion: You don't want Eclipse to warn you about everything. 结论:您不希望Eclipse警告您所有事情。

If you want to fix integer overflow of 如果要修复整数溢出

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

Conclusion: This would not fix long overflow problems. 结论:这不能解决长溢出问题。 If you want to fix them you should write code like: 如果你想修复它们,你应该编写如下代码:

 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");
 }

But this will only check if resulting value could fit in long. 但这只会检查结果值是否适合长期。 But you are asking, if during calculation "Overflow" happened. 但是你问,如果在计算过程中发生了“溢出”。 This would mean after every calculation you would need to check for this. 这意味着每次计算后都需要检查一下。

If you want to write a tool for eclipse that parses whole source file to find this, then i am not stopping you. 如果你想为eclipse编写一个解析整个源文件来找到它的工具,那么我不会阻止你。 But it would be just whole lot easier to remember following values: 但是记住以下值会更加容易:

 /*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

In FindBugs the FindPuzzlers detector's description contains 在FindBugs中,FindPuzzlers检测器的描述包含

ICAST_INTEGER_MULTIPLY_CAST_TO_LONG (ICAST, STYLE): Result of integer multiplication cast to long ICAST_INTEGER_MULTIPLY_CAST_TO_LONG(ICAST,STYLE):整数乘法的结果转换为long

but somehow I can't make this detect the problem in the following code: 但不知怎的,我不能在下面的代码中检测到这个问题:

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

You want this at compile time? 你想在编译时这个吗? Haven't seen a setting to do this. 没有看到设置这样做。

If you really want it, the best bet is most likely to write a new ruleset for PMD? 如果你真的想要它,最好的选择是最有可能为PMD写一个新的规则集?

What would be the expected result for this? 这会是什么预期的结果?

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

     return aLong;
 }

it has an overflow only if there is no overflow in it. 只有在没有溢出的情况下它才会溢出。

There's a potential overflow for any fixed representation integer operation; 任何固定表示整数运算都有潜在的溢出; determining whether there's an actual overflow is trivially convertible to the halting problem. 确定是否存在实际溢出可以简单地转换为停止问题。 Which doesn't mean that IntelliJ doesn't have some heuristic to warn you in some cases - you could, for example, track the upper and lower bounds of any numeric operation through a program and get a worst-case answer, but writing an accurate rule would be neither trivial nor decidable. 这并不意味着IntelliJ在某些情况下没有一些启发式方法来警告您 - 例如,您可以通过程序跟踪任何数字操作的上限和下限,并获得最坏情况的答案,但是准确的规则既不是微不足道的,也不是可判定的。

This would either require a deep analisys of an algorithm or just give you a warning for every arithmetic operation that involves variables. 这要么需要深入分析算法,要么只为每个涉及变量的算术运算提供警告。

EDIT: Oh, do you mean that if X, Y and Z are integers, then the multiplication would be on integers and only then assigned to aLong? 编辑:哦,你的意思是如果X,Y和Z是整数,那么乘法将是整数,然后才分配给aLong? IntelliJ Idea will show it as a warning but the inspection is off by default. 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