Подтвердить что ты не робот

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. Интересно, какой подход правильный. Учитывая приведенный выше код, который следует использовать? Исходный код наверху. Я собираюсь изменить его на второй подход.

4b9b3361

Ответ 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> является одним из шести операторов сравнения.