이 테스트 코드 :
$data = array(
12.12234,
1.01
);
foreach($data as $fMyFloat){
echo sprintf('%18.016f', $fMyFloat) . PHP_EOL;
}
... 인쇄 내 64 비트 컴퓨터에서이 :
12.1223399999999994
1.0100000000000000
당신은 부동 소수점 정밀도의 잘 알려진 문제에 직면하고있다. 베이스 10에서베이스 2 로의 정수를 변환하는 것은 매우 간단하고 정확합니다. 그러나 기본 10의 부동 소수점 수는 항상 기본 2에서 정확히 표현 될 수 없습니다.이 문제는 PHP에만 해당되는 것이 아니지만 입니다 (
).
부동 소수점 숫자의 정밀도는 제한되어 있습니다. 그것은 시스템 에 달려 있지만, PHP는 일반적으로 1.11e-16의 반올림으로 최대 상대 오차를 줄 수있는 IEEE 754 배정 밀도 형식 인 을 사용합니다. 0이 아닌 산술 연산은 오류가 더 커질 수 있으며, 물론 여러 작업이 혼합 된 경우 오류 전파를 고려해야합니다.
는 또한, 0.1 또는 0.7 같은 기본 10 정확히 표현할 수 로 부동 소수점 수는 유리수가, 가 내부적으로 사용되는 어떠한 문제입니다 기본 2, 부동 소수점 숫자로 정확한 표현이없는 가수의 크기. 따라서, 그들은 정밀
같은 정밀도를 달성하기 위해 귀하의 유일한 기회의 작은 손실없이 내부 이진 파일로 변환 할 수는 문자열로 숫자를 조작하는 것입니다. PHP는 GNU Multiple Precision 및 BC Math과 같이 문자열 일치가 필요한 경우 도움이되는 임의의 두 정밀도 라이브러리를 묶습니다. 여기 bc 수학에 조금 해킹있다 :
$data = array(
'12.12234',
'1.01'
);
bcscale(16);
foreach($data as $fMyFloat){
echo bcdiv($fMyFloat, 1) . PHP_EOL;
}
그것은이 경우, 그러나, 당신은 아마 단순한 문자열 기능을 사용할 수 있습니다 기간에
$data = array(
'12.12234',
'1.01'
);
foreach($data as $fMyFloat){
list($a, $b) = explode('.', $fMyFloat);
echo $a . '.' . str_pad($b, 16, 0) . PHP_EOL;
}
분할과 공격을 ['str_pad'] (HTTP ://php.net/str_pad)? – Charles
나는 그것을 시도하고 작동하지만 sprintf에서도 가능해야한다고 생각했습니다. 그러나 나는 방법을 이해할 수 없었다. 그것은 당신이 다른 대우를 받아야하는 기간의 뒤에 9 개의 손가락 이상에 뜨고있을 때 보인다. – Ben