Как найти потенциальные числовые переполнения в коде Java, с помощью Eclipse?

И для комичного значения:

label.text = [NSString stringWithFormat:@"%@", [NSNumber numberWithInt:count]];

(Хотя могло быть полезно, если однажды Вы имеете дело с NSNumber's)

7
задан dirtyvagabond 17 September 2009 в 01:10
поделиться

6 ответов

В 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);
1
ответ дан 7 December 2019 в 14:34
поделиться

Вы хотите это во время компиляции? Не видели настройки для этого.

Если вы действительно этого хотите, лучше всего будет написать новый набор правил для PMD?

0
ответ дан 7 December 2019 в 14:34
поделиться

Каков будет ожидаемый результат для этого?

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

     return aLong;
 }

переполнение происходит только в том случае, если в нем нет переполнения.

Существует потенциальное переполнение для любой операции с целым числом фиксированного представления; определение того, есть ли фактическое переполнение, тривиально можно преобразовать в проблему остановки. Это не означает, что IntelliJ не имеет эвристики, которая предупреждала бы вас в некоторых случаях - вы могли бы, например, отслеживать верхнюю и нижнюю границы любой числовой операции с помощью программы и получать наихудший ответ, но написать точное правило не было бы ни тривиальным, ни разрешимым.

0
ответ дан 7 December 2019 в 14:34
поделиться

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? IntelliJ Idea will show it as a warning but the inspection is off by default.

0
ответ дан 7 December 2019 в 14:34
поделиться

может быть, вы могли бы выполнить свои вычисления с помощью java.math.BigInteger и сравнить результат с

new java.math.BigInteger(String.valueOf(Long.MAX_VALUE))
-1
ответ дан 7 December 2019 в 14:34
поделиться

Если вы не знаете, что такое 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");
 }

Но это только проверяет, может ли полученное значение уместиться в long. Но вы спрашиваете, произошло ли при расчете «переполнение». Это означает, что после каждого расчета вам нужно будет это проверять.

Если вы хотите написать инструмент для 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
4
ответ дан 7 December 2019 в 14:34
поделиться