여전히 부동 소수점 빼기가 오류 또는 이상한 값을 초래하는 비슷한 문제가있는 사용자가있는 경우 이 문제에 대해 좀 더 자세히 설명하고 싶습니다. 범인은 부동 소수점 숫자입니다. 다른 운영 체제와 다른 프로그래밍 언어가 다르게 작동 할 수 있습니다.
문제를 설명하기 위해 아래에 간단한 예를 들어 설명합니다.
이것은 PHP와 직접 관련이 없으며 버그가 아닙니다. 그러나 모든 프로그래머는이 문제를 알고 있어야합니다.
이 문제는 20 년 전부터 많은 사람들의 목숨을 앗아갔습니다.
1991 년 2 월 25 일, MIM-104 패트리어트 미사일 배터리의 부동 소수점 계산에서의이 문제는 사우디 아라비아 다란 (Dhahran)에서 들어오는 스커드 미사일을 차단하여 미 육군 제 14 사단 분리 팀의 28 명의 병사가 사망하게했다.
하지만 어떻게됩니까?
이유는 부동 소수점 값이 제한된 정밀도를 나타 내기 때문입니다. 따라서 처리 후에도 의 문자열 표현이 같지 않을 수 있습니다. 또한 은 스크립트에 부동 소수점 값을 쓰고 직접 수학 연산없이 을 인쇄합니다.
그냥 간단한 예 :
$a = '36';
$b = '-35.99';
echo ($a + $b);
당신이 바로 0.01를 인쇄하는 기대? 그러나 매우 이상한 답변을 인쇄합니다 0.009999999999998
다른 숫자와 마찬가지로 부동 소수점 숫자 double 또는 float는 0과 1의 문자열로 메모리에 저장됩니다.부동 소수점이 정수와 다른 점은 우리가 0과 1을 어떻게 보는지를 해석 할 때입니다. 그들이 저장되는 방법에 대한 많은 표준이 있습니다. 바로 ....
이
진수 숫자가 아니라 바이너리로 표현되지 않은 왼쪽에서
부동 소수점 숫자는 일반적으로, 부호 비트, 지수 필드 및 유효 숫자 나 가수 등의 컴퓨터 자료로 포장된다 충분한 공간이 부족하기 때문입니다. 그래서 1/3 정확히 0.3333333 ...이라고 표현할 수 없습니다. 그렇죠? 우리가 0.01을 이진수 부동 소수점 숫자로 표현할 수없는 이유는 동일한 이유 때문입니다. 1/100은 0.00000010100011110101110000 ..... 반복 10100011110101110000입니다.
0.01이 2 진수로 01000111101011100001010으로 단순화되고 시스템 잘림 형식으로 유지되면 십진수로 다시 변환 될 때 0.0099999와 같이 표시됩니다. ... 시스템에 따라 다릅니다 (64 비트 컴퓨터는 32 비트보다 훨씬 더 정밀함을 제공합니다). 운영 체제는이 경우 인쇄 된대로 인쇄할지 또는 사람이 읽을 수있는 방식으로 인쇄 할지를 결정합니다. 그래서, 그것은 기계에 의존하여 어떻게 표현하고 싶어하는가입니다. 그러나 다른 방법으로 언어 수준에서 보호 될 수 있습니다.
결과를 포맷하면 echo number_format (0.009999999999998, 2); 0.01을 인쇄합니다.
이 경우 읽어야하는 방법과 필요한 정밀도를 지정하기 때문입니다.
php.ini에서 '정밀도'를 조사하여 PHP 전반의 변경 사항을 광범위하게 검사합니다. 그러나 중요한 숫자 *를 다루고 있음을 알려드립니다. –