부동 소수점 숫자(Floating point numbers)

부동 소수점 숫자("float", "doubles" 또는 "real number"라고도 함)는 다음 구문 중 하나를 사용하여 지정할 수 있습니다.

                  
<?php
$a = 1.234;
$b = 1.2e3;
$c = 7E-10;
$d = 1_234.567; // as of PHP 7.4.0
?>
                  
                

공식적으로 PHP 7.4.0부터(이전에는 밑줄이 허용되지 않았습니다):

LNUM          [0-9]+(_[0-9]+)*
DNUM          ([0-9]*(_[0-9]+)*[\.]{LNUM}) | ({LNUM}[\.][0-9]*(_[0-9]+)*)
EXPONENT_DNUM (({LNUM} | {DNUM}) [eE][+-]? {LNUM})
                

float의 크기는 플랫폼에 따라 다르지만 대략 14자리의 정밀도를 가진 최대 대략 1.8e308이 일반적인 값(64비트 IEEE 형식)입니다.

경고
부동 소수점 정밀도

부동 소수점 숫자는 정밀도가 제한됩니다. 시스템에 따라 다르지만 PHP는 일반적으로 IEEE 754 배정밀도 형식을 사용하므로 1.11e-16 정도의 반올림으로 인해 최대 상대 오류가 발생합니다. 기본이 아닌 산술 연산은 더 큰 오류를 줄 수 있으며, 물론 여러 연산이 복합될 때 오류 전파를 고려해야 합니다.

또한 0.1 또는 0.7과 같이 10진법에서 부동 소수점 숫자로 정확히 표현할 수 있는 유리수는 가수의 크기에 관계없이 내부적으로 사용되는 2진법의 부동 소수점 숫자로 정확히 표현되지 않습니다. 따라서 약간의 정밀도 손실 없이는 내부 바이너리 대응물로 변환될 수 없습니다. 이로 인해 혼란스러운 결과가 발생할 수 있습니다. 예를 들어 floor((0.1+0.7)*10)은 일반적으로 예상되는 8 대신 7을 반환합니다. 내부 표현은 7.999999999999991118...과 같기 때문입니다.

따라서 부동 숫자 결과를 마지막 자릿수까지 신뢰하지 말고 부동 소수점 숫자를 직접 비교하지 마십시오. 더 높은 정밀도가 필요한 경우 임의 정밀도 수학 함수gmp 함수를 사용할 수 있습니다.

'간단한' 설명은 'Why don’t my numbers add up?'라는 제목의 » 부동 소수점 가이드를 참조하세요.


부동 소수점으로 변환

From strings

문자열이 숫자이거나 선행 숫자이면 해당 부동 소수점 값으로 해석되고, 그렇지 않으면 영(0)으로 변환됩니다.

From other types

다른 유형의 값의 경우 먼저 값을 int로 변환한 다음 float로 변환하여 변환이 수행됩니다. 자세한 내용은 정수로 변환을 참조하십시오.

메모: 특정 유형은 int로 변환할 때 정의되지 않은 동작이 있으므로 float로 변환할 때도 마찬가지입니다.

부동 소수점 비교

위의 경고에서 언급했듯이 부동 소수점 값이 같은지 테스트하는 것은 내부적으로 표현되는 방식 때문에 문제가 됩니다. 그러나 이러한 제한 사항을 해결하는 부동 소수점 값을 비교하는 방법이 있습니다.

부동 소수점 값이 같은지 테스트하기 위해 반올림으로 인한 상대 오차의 상한이 사용됩니다. 이 값은 기계 엡실론 또는 단위 반올림으로 알려져 있으며 계산에서 허용되는 가장 작은 차이입니다.

$a$b는 5자리 정밀도와 같습니다.

                  
<?php
$a = 1.23456789;
$b = 1.23456780;
$epsilon = 0.00001;

if(abs($a-$b) < $epsilon) {
    echo "true";
}
?>
                  
                
NaN

일부 숫자 연산은 상수 NAN으로 표시되는 값을 생성할 수 있습니다. 이 결과는 부동 소수점 계산에서 정의되지 않았거나 표현할 수 없는 값을 나타냅니다. 이 값을 자신을 포함하지만 true를 제외한 다른 값에 대해 느슨하거나 엄격하게 비교하면 결과가 false가 됩니다.

NAN은 여러 다른 값을 나타내므로 NAN 자체를 포함하여 다른 값과 비교해서는 안 되며 대신 is_nan()을 사용하여 검사해야 합니다.