분석
JavaScript에는 숫자 유형 번호가 하나 뿐이며 JavaScript의 모든 숫자는 IEEE-754 표준 형식으로 표시됩니다. 부동 소수점 숫자의 정밀 문제는 JavaScript에 고유하지 않습니다. 일부 소수는 이진에서 무한 숫자를 나타 내기 때문입니다.
소수점 바이너리
0.1 0.0001 1001 1001 1001 ...
0.2 0.0011 0011 0011 0011 ...
0.3 0.0100 1100 1100 1100 ...
0.4 0.0110 0110 0110 0110 ...
0.5 0.1
0.6 0.1001 1001 1001 1001 ...
예를 들어, 1.1은 실제로 '1.1'을 나타낼 수는 없지만 어느 정도의 정확도 만 달성 할 수 있습니다.
1.0999999999999999999
JavaScript의 문제는 더 복잡합니다. 여기 Chrome의 일부 테스트 데이터 만 있습니다.
입력 및 출력
1.0-0.9 == 0.1 거짓
1.0-0.8 == 0.2 거짓
1.0-0.7 == 0.3 거짓
1.0-0.6 == 0.4 True
1.0-0.5 == 0.5 True
1.0-0.4 == 0.6 True
1.0-0.3 == 0.7 True
1.0-0.2 == 0.8 True
1.0-0.1 == 0.9 True
해결하다
그렇다면 1.0-0.9! = 0.1에서 이러한 유형의 비 버그 문제를 피하는 방법은 무엇입니까? 다음은 현재 더 자주 사용되는 솔루션이 플로팅 포인트 계산 결과를 판단하기 전에 정확도가 줄어 듭니다.
코드 사본은 다음과 같습니다.
(1.0-0.9) .tofixed (숫자) // tofixed () 정확도 매개 변수는 0에서 20 사이 여야합니다.
parsefloat ((1.0-0.9) .tofixed (10)) === 0.1 // 결과는 참입니다
parsefloat ((1.0-0.8) .tofixed (10)) === 0.2 // 결과는 참입니다
parsefloat ((1.0-0.7) .tofixed (10)) === 0.3 // 결과는 참입니다
parsefloat ((11.0-11.8) .tofixed (10)) === -0.8 // 결과는 사실입니다
방법 정제
코드 사본은 다음과 같습니다.
// Isequal 도구 방법을 사용하여 값이 동일인지 아닌지를 결정합니다.
함수 isequal (Number1, Number2, Digits) {
Digits == 정의되지 않았습니까? // 기본 정확도는 10입니다
return number1.tofixed (숫자) === 번호 2.tofixed (숫자);
}
Isequal (1.0-0.7, 0.3);
// 기본 확장 방법, 객체 지향 스타일을 선호합니다
숫자 .prototype.isequal = 함수 (번호, 자리) {
Digits == 정의되지 않았습니까? // 기본 정확도는 10입니다
replay this.tofixed (숫자) === 번호 .tofixed (숫자);
}
(1.0-0.7) .Sequal (0.3);