2016-07-11 5 views
1

확인하기 포인트 값. 이것은 어떻게됩니까 :부동 소수점 값을 가질 때 두 객체가 같은지 확인하십시오.</p> <pre><code>JSON.stringify(val) === JSON.stringify(expected) </code></pre> <p>이 내가 부동 한 경우를 제외하고 잘 작동 : 값과 예상 값이 같은 경우 바이너리와 지금 난 그냥 캐릭터 라인 화를 사용하고 다루는 내 자바 스크립트 프로그램에 대한 몇 가지 테스트 케이스를 작성

Given Value: [10,20,30,32.400001525878906,{"test":3,"asdf":23}] 
Expected Value: [10,20,30,32.4,{"test":3,"asdf":23}] 

Test Failed! 

그래서 나는 더 이상 stringify를 사용하여 내 두 객체/배열이 같은지 검사 할 수 없다고 생각합니다. 잠재적으로 깊이 중첩 된 두 객체/배열이 같고 부동 소수점 값을 고려하는지 확인하는 좋은 방법은 무엇입니까? 즉, 두 개의 부동 소수점 값은 99.99 %가 동일하거나 같으면 동일하다고 간주해야합니다.

+0

재귀 동등성 테스터를 작성해야합니다. 그리고 부동 소수점 숫자가되면'=='보다는 관용과 비교해야합니다. – Barmar

+0

JSON.stringify를 사용하여 객체를 비교하는 것은 순서가 보장되지 않으므로 좋은 생각이 아니므로 두 객체는 ​​동일한 속성과 값을 가질 수 있지만 "같지 않음"으로 평가할 수 있습니다. 속성과 값을 반복해야하는데, 이미 * 많은 것에 대한 많은 질문이 있습니다 (http://stackoverflow.com/search?q=%5Bjavascript%5D+compare+objects). – RobG

답변

1

배열의 각 요소를 순서대로 테스트해야하므로 개체에 대해 반복적으로 수행해야합니다. 이것은 전형적으로 깊은 비교 또는 깊은 평등으로 알려져 있습니다. 비교 대상의 유형을 확인하는 재귀 함수를 사용하여이 작업을 수행 할 수 있어야합니다.

부동 소수점 값을 비교할 때 허용 오차를 사용하는 것이 좋습니다. 서로 다른 두 숫자를 뺀 값의 절대 값을 취한 다음이를 선택한 고정 된 공차 값 또는 엡실론이라는 작은 숫자와 비교하여이 작업을 수행합니다.

자바 스크립트에서는, 기계 엡실론 Number.EPSILON로서 사용할 수 있으며, 1보다 큰 그리고 1 Number으로서 표현 될 수있는 가장 작은 수의 차이로 정의된다. 유사한 상수는 대부분의 언어에서 사용할 수 있으며 일반적으로 허용 오차 기반 비교에 사용됩니다.

공차 기반 비교는 단순 항등식에서 부동 소수점 비교로 부동 소수점 비교를 변환하고 비교합니다. , ab의 차이가 tolerance보다 작은 경우

var tolerance = Number.EPSILON; 
if (Math.abs(a - b) < tolerance) { ... } 

: 일반적

if (a === b) { ... } 

을 써서 경우에 당신은 절대 값과 tolerance를 사용하여 부동 소수점 불확실성을 제거하는 것을 써서 당신은 그들을 평등하게 대합니다.

더 미묘한 (경우에 따라 과도한 경우) 방법은 The Floating Point Guide's section on comparison을 참조하십시오. 거기에 제시된 구현은 Java에서 있지만, 많은 노력 없이도 JavaScript로 이식 할 가능성이 높습니다.

+0

Number.EPSILON은 사용하기에는 너무 작다고 생각합니다. 실제 숫자 (또는 그 차이)에 따라 요인에 의해 조정되어야한다고 생각합니다. 따라서 다소 큰 숫자는 1.0의 ulp에 의해 다른 것과 비교되지 않습니다. –

+0

그래, 여기서 그걸 만지려고했지만, 반드시 성공한 것은 아닙니다. :) 대답을 더 잘 표현하는 방법에 대한 제안을 엽니 다. –