Java Integer 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;
624   5  

5 ответов:

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

вычитание "трюк" для сравнения двух числовых значений нарушается!!!

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

здесь a < b, еще a - b положительный.

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

кроме того, даже если он работает, это не обеспечьте любое значительное улучшение в представлении, и смогите на самом деле стоить удобочитаемость.

см. также

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

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

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

возможно, это для того, чтобы избежать переполнения / underflow.

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

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

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

public int compareTo(Integer anotherInteger) {
    return sign(this.value - anotherInteger.valuel);
}

Comments

    Ничего не найдено.