Java, сравнивая значения BigInteger
BigInteger bigInteger = ...;
if(bigInteger.longValue() > 0) { //original code
//bigger than 0
}
//should I change to this?
if(bigInteger.compareTo(BigInteger.valueOf(0)) == 1) {
//bigger than 0
}
Мне нужно сравнить некоторые суровые значения BigInteger. Интересно, какой подход правильный. Учитывая приведенный выше код, который следует использовать? Исходный код наверху. Я собираюсь изменить его на второй подход.
Ответы
Ответ 1
Первый подход неверен, если вы хотите проверить, имеет ли значение BigInteger значение postive: longValue
просто возвращает бит 64 младшего порядка, который может вернуть знак... Таким образом, тест может потерпеть неудачу для положительного BigInteger.
Второй подход лучше (см. Bozhos answer для оптимизации).
Другая альтернатива: BigInteger#signum
возвращает 1
, если значение положительное:
if (bigInteger.signum() == 1) {
// bigger than 0
}
Ответ 2
Если вы используете BigInteger
, это предполагает, что вам нужны большие числа, чем может обрабатывать long
. Поэтому не используйте longValue()
. Используйте compareTo
. В вашем примере лучше:
if (bigInteger.compareTo(BigInteger.ZERO) > 0) {
}
Ответ 3
Это не прямой ответ, но важная заметка об использовании compareTo().
При проверке значения compareTo() всегда проверяйте x < 0
, x > 0
и x == 0
.
Не тестируйте x == 1
Из Comparable.compareTo() javadocs:
Сравнивает этот объект с указанным объектом для заказа. Возвращает отрицательное целое число, ноль или положительное целое число, так как этот объект меньше, равен или больше указанного объекта.
Примечание:
-
A negative integer
, а не -1
.
-
A positive integer
, а не 1
.
Правда, проверка ==1
и ==-1
будет работать для BigInteger
. Это код BigInteger.compareTo()
:
public int compareTo(BigInteger val) {
if (signum == val.signum) {
switch (signum) {
case 1:
return compareMagnitude(val);
case -1:
return val.compareMagnitude(this);
default:
return 0;
}
}
return signum > val.signum ? 1 : -1;
}
Но это все еще плохая практика и явно рекомендуется в JavaDocs:
Сравнивает этот BigInteger с указанным BigInteger. Этот метод предоставляется в предпочтении индивидуальным методам для каждого из шести операторов булевого сравнения (<, ==, > , > =,! =, < =). Предлагаемая идиома для выполнения этих сравнений: (x.compareTo(y) <op> 0
), где <op>
является одним из шести операторов сравнения.