2016-10-21 4 views
0

저는이 아주 이상한 문제로 머리를 긁적 거리고 있습니다. PHP에서 계산을하고 최종 결과는 숫자입니다. 이것은 정수이지만 계산이 끝났기 때문에 PHP는 이것을 float로 간주합니다. 그러나 정수로 타입 변환하면 마술처럼 빼기가됩니다. 마찬가지로 1 전체 정수. 나는 정말로 상실감에 처해있다. 직접 시험해보십시오.PHP float 및 int가 다른 숫자를 반환합니다.

<?php 
$number_of_rows = 10; 
$number_of_columns = 19; 
$active = array(); 

$tile = 160; 
$column = $tile/$number_of_columns; // 8.42105263158 
$rounded_down = floor($column); // 8 
$column = $column-$rounded_down; // 0.42105263158 
$column = $column*$number_of_columns; // 8 

var_dump($column); // 8 -> that is great 
var_dump((int)$column); // 7 -> WTF?!!! 

?> 

PHP 7.0.12 (Linux 64 비트)

+1

'echo serialize ($ column);''int'로 형 변환 할 때 반올림하지 않습니다. – AbraCadaver

+1

http://stackoverflow.com/questions/588004/is-floating-point-math-broken?rq=1 – AbraCadaver

+0

'$ column'의 실제 값은'7.999999999999234'와 같을 것입니다.이 값은'8' 인쇄의 기본 정밀도 때문입니다. 그러나'int '로 변환하면 분수가 제거됩니다. – Barmar

답변

2

설명은 Warning in PHP manual을 참조하십시오.

부동 소수점 숫자는 정밀도를 제한 : 정밀하고 floor() 예에 대해 이야기

발췌. 시스템에 따라 다르지만 일반적으로 PHP는 IEEE 754 배정도 형식을 사용합니다.이 형식은 1.11e-16 정도의 반올림으로 인해 최대 상대 오차가 발생합니다. 기본이 아닌 산술 연산은 더 큰 오류를 줄 수 있으며 물론 여러 작업이 혼합 될 때 오류 전파를 고려해야합니다.

또한, 기수 10에서 부동 소수점 숫자로 정확하게 표현할 수있는 유리수 (예 : 0.1 또는 0.7)는 기수 2의 부동 소수점 숫자로 정확하게 표현되지 않으며 내부 2 가수. 따라서 정밀도를 약간 떨어 뜨리지 않고 내부 바이너리로 변환 할 수 없습니다. 이 혼동 결과를 가져올 수있다 : 내부 표현되기 때문에, 예를 들면, 층 ((0.1 + 0.7) * 10)는 일반적으로 7 대신 예상 8 반환 무언가 7.9999999999999991118 등 ....

+0

외부 링크가 아닌 관련 콘텐츠를 여기에 게시하십시오. – Barmar

+0

@Barmar, PHP는 정밀도 오류를 덤프하지 않지만 AbraCadaver의 serialize 주석을 보면 정밀도 오류입니다. '$ column'의 실제 값은'7.9999999999999911'입니다. – Devon

+0

그래, 내가 주석을 단다는 것을 깨달았다. – Barmar

관련 문제