HihoBookStudy / EffectiveJava

이펙티브 자바 북스터디입니다.
1 stars 0 forks source link

[Item10] Float.compare와 Float.equals 동작 방식의 차이가 궁금합니다. #19

Closed Limgayoung closed 2 months ago

Limgayoung commented 3 months ago

63페이지에 float과 double은 equals를 사용하지 않고 compare로 비교하는 것을 권장하고 있습니다. Float과 Double의 cmopare와 equals의 동작 방식의 차이를 설명해 주실 수 있나요?

또, Float과 Double의 equals는 오토박싱을 수반할 수 있으니 성능상 좋지 않다고 나와 있는데, 다른 기본타입들은 equals를 사용해도 오토박싱을 수반하지 않는지 궁금합니다.

ForteEscape commented 3 months ago

Q1.

63페이지에 float과 double은 equals를 사용하지 않고 compare로 비교하는 것을 권장하고 있습니다. Float과 Double의 cmopare와 equals의 동작 방식의 차이를 설명해 주실 수 있나요?


A1.

// Float.equals
public boolean equals(Object obj) {
    return (obj instanceof Float)
           && (floatToIntBits(((Float)obj).value) == floatToIntBits(value));
}

// Float.compare
public static int compare(float f1, float f2) {
    if (f1 < f2)
        return -1;           // Neither val is NaN, thisVal is smaller
    if (f1 > f2)
        return 1;            // Neither val is NaN, thisVal is larger

    // Cannot use floatToRawIntBits because of possibility of NaNs.
    int thisBits    = Float.floatToIntBits(f1);
    int anotherBits = Float.floatToIntBits(f2);

    return (thisBits == anotherBits ?  0 : // Values are equal
            (thisBits < anotherBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
             1));                          // (0.0, -0.0) or (NaN, !NaN)
}

Q2.

또, Float과 Double의 equals는 오토박싱을 수반할 수 있으니 성능상 좋지 않다고 나와 있는데, 다른 기본타입들은 equals를 사용해도 오토박싱을 수반하지 않는지 궁금합니다.


A2. 결론부터 말씀드리자면 오토박싱이 수반됩니다. 아래는 Integer 타입의 equals 코드와 compare 코드입니다.

    public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }

    public static int compare(int x, int y) {
        return (x < y) ? -1 : ((x == y) ? 0 : 1);
    }
Limgayoung commented 3 months ago

2번에서 그렇다면 Integer 타입의 equals도 강제 형변환을 시키기 때문에 오토박싱이 일어나는 것은 같을 것 같습니다. 다른 기본형들도 compare를 사용하는 것이 성능상 좋을 것 같은데 왜 Float과 Double만 특별히 compare를 사용하는 것을 권장하는 것인지 알 수 있을까요?

ForteEscape commented 3 months ago

다른 기본형들은 == 이라는 좋은 연산자를 제공합니다. float, double의 경우 실수 타입으로 인한 정밀도 차이로 인해 ==의 사용이 권장되지 않아 특별하게 compare를 사용하는 것으로 생각됩니다.

Limgayoung commented 3 months ago

아하!! 제가 책이 없을 때 추가 질문을 해서 책에서 기본형은 equals를 권하는 것으로 착각했네요! 감사합니다 ~ ㅎㅎ