簡體   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