Целое число Java compareTo () - почему сравнение использования по сравнению с вычитанием?

Я нашел это java.lang.Integer реализация compareTo метод смотрит следующим образом:

public int compareTo(Integer anotherInteger) {
    int thisVal = this.value;
    int anotherVal = anotherInteger.value;
    return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1));
}

Вопрос состоит в том почему сравнение использования вместо вычитания:

return thisVal - anotherVal;
78
задан jahroy 17 May 2013 в 04:04
поделиться

5 ответов

Это связано с целочисленным переполнением. Когда thisVal очень велико, а anotherVal отрицательно, то вычитание последнего из первого дает результат больше, чем thisVal , который может выходить за пределы диапазона отрицательных значений.

92
ответ дан 24 November 2019 в 10:32
поделиться

Проще говоря, тип int недостаточно велик для хранения разницы между двумя произвольными значениями int . Например, разница между 1,5 миллиардами и -1,5 миллиардами составляет 3,0 миллиарда, но int не может содержать значения больше 2,1 миллиарда.

9
ответ дан 24 November 2019 в 10:32
поделиться

Уловка с вычитанием для сравнения двух числовых значений не работает !!!

        int a = -2000000000;
        int b =  2000000000;
        System.out.println(a - b);
        // prints "294967296"

Здесь a , но a - b положительно.

НЕ используйте эту идиому. Не работает.

Более того, , даже если он работает , он НЕ обеспечивает какое-либо существенное улучшение производительности и может фактически стоить читабельности.

См. Также

  • Головоломки Java Головоломка 65: Странная сага подозрительного типа

    У этой головоломки есть несколько уроков. Наиболее конкретный из них: Не используйте компаратор на основе вычитания, если вы не уверены, что разница между значениями никогда не будет больше, чем Integer.MAX_VALUE . В общем, остерегайтесь переполнения int . Еще один урок состоит в том, что вам следует избегать «умного» кода. Стремитесь писать ясный, правильный код и не оптимизируйте его, если это не окажется необходимым.

63
ответ дан 24 November 2019 в 10:32
поделиться

Возможно, чтобы избежать переполнения / потери значимости.

3
ответ дан 24 November 2019 в 10:32
поделиться

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

  • Первая версия compareTo возвращает одно из трех возможных значений: -1, 0 или 1.
  • Если вы замените последнюю строку вычитанием, результатом может быть любое целочисленное значение.

Если вы знаете, что переполнения не будет, вы можете использовать что-то вроде этого:

public int compareTo(Integer anotherInteger) {
    return sign(this.value - anotherInteger.valuel);
}
1
ответ дан 24 November 2019 в 10:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: