2012-12-18 3 views
0

오른쪽으로 패딩 0으로 float (18,16)을 얻으려고하지만 항상 0 대신 1로 끝나기 때문에 작동하지 않습니다. . 내 생각에 그것은 잘못 지정했기 때문에 그것이 올바른 방법은 확실치 않다.Sprintf 오른쪽 패딩 0으로 18,16 플로트 부동

샘플 : 12.1223412.122340000000000 될해야 1.011.01000000000000를가되어야합니다.

이것을 달성하려면 sprintf('%18.016f', $fMyFloat);을 사용하고 있지만 항상 0 대신 1로 끝납니다. 분명히 무언가를 감독하고 있는데, 나는 무엇을 모르고 있습니다. 어떤 도움이라도 대단히 감사합니다.

+1

분할과 공격을 ['str_pad'] (HTTP ://php.net/str_pad)? – Charles

+0

나는 그것을 시도하고 작동하지만 sprintf에서도 가능해야한다고 생각했습니다. 그러나 나는 방법을 이해할 수 없었다. 그것은 당신이 다른 대우를 받아야하는 기간의 뒤에 9 개의 손가락 이상에 뜨고있을 때 보인다. – Ben

답변

3

이 테스트 코드 :

$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 PrecisionBC 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; 
} 
+0

명확한 설명에 감사드립니다. 와우. 너는이 물건을 안다! 이것은 나의 knowlegde 너머에 간다. 그리고 나는 이것을 이해하지 않고 있었을 것이다. 감사합니다. +1하고 받아들입니다. 좋은 하루 되세요. (그리고 네 말이 맞아, 전에 네가 가진 str_pad 솔루션에 갈거야.). – Ben

관련 문제