2012-10-25 5 views
1

두 개의 질문이 있습니다.java Float : == equals compareTo

1) 나는이 Float 또는 Double 데이터를 비교할 때, compareTo 대신 equals 사용하는 것이 들었다. 나는 그 이유를 모른다. equals을 사용하여 어디에 문제가 발생하는지 보여주는 예가 있습니까?

float f2=(float)1.123450; 
    Float f3=new Float(1.123450); 

    System.out.println(f3==f2); // result is true 

내가 ==가 동일한 메모리 주소로 두 개의 데이터 포인트를 의미하여 생각 :

2)이 코드를 참조하십시오. 하지만 f3f2은 같은 주소입니까? new Float(...) 새 공간을 만들지 않습니까?

+0

다소 관련 : http://stackoverflow.com/questions/1551235/java-strings-compareto-vs-equals?rq=1 –

+0

f1.equals이 (F2) 무엇을 주셨 는가? [워드 프로세서] (http://docs.oracle.com/javase/6/docs/api/java/lang/Float.html#compareTo (자바에서 – smk

+0

.lang.Float)) : "이 메소드 ['compareTo']에 의해 부과 된 Float 객체의 자연 순서는'equals'와 일치합니다." –

답변

7

두 인수가 모두 참조 유형 인 경우 ==은 메모리 위치를 테스트합니다. 그러나 == (또는 !=)에 대한 인수 중 하나가 숫자이고 다른 하나가 숫자로 변환 가능한 경우 (unboxing 사용), 비교는 언 박싱 후 숫자 값을 비교하여 수행됩니다. 따라서이 경우 비교는 부동 소수점 값 (이 경우 동일 함)에 따라 수행됩니다. 자세한 내용은 Java Language Specification §15.21.1을 참조하십시오.

그러나 Float.NaN == Float.NaNfalse입니다.

+6

일반적으로 말하자면, 두 개의 수레/복식이 정확히 일치하는지 아닌지를 확인하여 비교하는 것입니다. 이는 실수를 플로트 (예 : 0.1)로 정확하게 표현할 수없는 경우 부동 소수점이 누적 될 수있는 반올림 오류 때문입니다. – yshavit

+0

@yshavit - 네, 이것은 하나의 값에 대해'equals','compareTo'와'=='사이의 차이점을 놓치지 않는 아주 좋은 지적입니다. (그러나 Peter가 정확한 지점에 초점을 맞추기 위해 응답을 변경했음을 알 수 있습니다.) –

5

일반적으로 말하면 ==은 반올림이나 산술 오류를 처리해야 compareTo()가 도움이되지 않는 한 괜찮습니다. 오류 내에서 두 개의 복식을 비교하려면

당신이 사용할 수있는

if (Math.abs(a - b) < ERR) // within error. 

또는 상대 오차

또는 계수가 종종 열 10000와 같은 수단의 전력인지 반올림 내

if (Math.abs(a - b) < ERR * (Math.abs(a) + Math.abs(b))/2) // within error. 
소수점 네 자리까지. 자바에서

if (Math.round(a * factor) == Math.round(b * factor)) // within a multiple 
+2

[Float.equals()의 문서] (http://docs.oracle.com/javase/6/docs/api/) java/lang/Float.html # equals (java.lang.Object)) : _ "'f1'과'f2'가 모두'Float.NaN'을 표현하면, equals 메소드는'Float '을 반환하더라도'true'를 반환합니다. NaN == Float.NaN'의 값은'false'입니다. "_ –

0

, 당신은이 (주) 유형,

  1. 프리미티브
  2. 참조

    그들이 유형 double 인 경우에만 경우

    원시 유형의 기본 요소를 고려, float이 , int, long 등입니다.

    참조 유형은 데이터를 저장하기 위해 "개체"를 사용하는 모든 유형입니다. 수업 시간에 제작할 때 실제로는 "변장"방식으로 참조 유형을 만듭니다. 참조 유형의 예로는 String, Double, Integer 등이 있습니다.

    따라서 형식이 달라질 때까지 float xFloat y과 비교하면 실제로 두 가지 유형을 비교하고 있습니다.

    자바에서는 ==의 연산자가 대부분 동등한 유형의 객체 만 비교합니다.그러나 때로는 언어 (상기 정의 된) x 원시적이며 y가 참조 형식 인 경우에, 예컨대 x == y를 다른 형태의 비교를 허용한다.

    xy의 비교를 수행하면 boxing and unboxing이라고하는 작업이 수행됩니다. 그러나 권투를 이해하기 위해서는 메모리 의미론에 따라 기본 유형과 참조 유형의 차이점을 이해해야합니다. (당신을 놀라게하는시키지 말라!)

    원시적 인 형태의 신속하고 세분화 접근의 관점에서 보면 매우 유연하지 스택이라는 메모리 위치에 저장됩니다. 꽤 쉽습니다.

    참조 형식 비록 다른 : 참조 형은 new 연산자 사용을 인스턴스화 될 때 - Float 또는 다른 참조 타입 인 경우 (Float x = <something>;을 할 때 내재적이라고 Float x = <something>;Float x = new Float(<something>);로 설정되어, 즉) 정도 객체가 생성되어 힙에 저장되지만 해당 객체 (힙에 있음)에 대한 포인터는 스택에 저장됩니다.

    즉, x에 저장된 값을 검색하려면 컴퓨터가 스택에 저장된 주소를 사용하고 힙의 해당 메모리 주소로 이동해야합니다. 스택 메모리 할당과 주변의 다른 개체에 대한 걱정없이 해제되는 곳이다 "동적 메모리 할당,"라고 뭔가 아주 좋은하지 않기 때문에

    우리는 참조 유형을 저장하는 힙을 사용합니다. 복싱 언 박싱 지금

    : 두 개체가이다되도록

    권투 (또한 포장)는 원시 타입 오브젝트를 취하고 참조 형식으로 저장하는 과정이다 (따라서 float xFloat x된다) 동일 유형. (그것은 종이에 크리스마스 선물을 포장하는 것과 같은 종류입니다.) 그래서 뒷 배경에, Integer k = 6은 일종의 복싱입니다. (autoboxing)

    언 박싱은 언 박싱과는 반대되는 것으로 언 랩핑이라고 할 수 있습니다. 언 박싱는 "박스"오브젝트를 다시 원시적 형에 대한 참조 유형에서 소요, 그래서 문은 너무 많은 번거 로움 :이 정말 의미

    Integer k = 6; //Boxing

    int m = k; //Unboxing

    없이 작업 할 수 있습니다 귀하의 질문 측면에서 : 귀하가 게시 한 코드에서 autoboxing 및 unboxing이 발생하여 명세서가 유효하게되었습니다. JVM은 당신이 의미하는 바를 수행 할만큼 영리했습니다. 그렇다고해서 복싱과 언 박싱이 코드 성능에 심각한 영향을 미칠 수 있기 때문에 정기적 인 습관을 만들어야한다는 것을 의미하지는 않습니다!

    또한 xy이 모두 Float 유형 인 경우 참조를 비교해야합니다.

    행운을 빌어 요!

관련 문제