BCMath 임의 정밀도 수학
BCMath 임의 정밀도 수학
부동소수점은 정확한 소수 계산에 한계가 있어요. 돈이나 정밀한 계산이 필요한 값이라면, PHP에서는 BCMath를 통해 어느 크기든 정밀도까지 지정 가능한 수학을 쓸 수 있어요.
본문
임의 정밀도 수학(arbitrary precision mathematics)을 위해 PHP는 BCMath를 제공해요. 이 라이브러리는 메모리가 충분하다면 문자열로 표현되는, 소수점 이하 최대 2147483647(즉 0x7FFFFFFF) 자리까지 어떤 크기와 정밀도의 숫자도 지원해요.
유효한(잘 형성된) BCMath 숫자는 정규식 /^[+-]?[0-9]*(\.[0-9]*)?$/ 와 일치하는 문자열이에요.
다만 여기서 한 가지 조심할 점이 있어요. BCMath 함수가 연산자로 string을 기대하는 자리에 float를 넘기면, PHP가 float를 string으로 변환하는 방식 때문에 의도치 않은 결과가 나올 수 있어요. 문자열이 지수 표기법(BCMath가 지원하지 않는 형태)이 될 수 있고, PHP 8.0.0 이전에는 소수 구분자가 로케일에 따라 달라질 수 있기 때문이에요(BCMath는 항상 소수점을 기대해요). 예제로 확인해 볼게요.
$num1 = 0; // (string) 0 => '0'
$num2 = -0.000005; // (string) -0.000005 => '-5.05E-6'
echo bcadd($num1, $num2, 6); // => '0.000000'
setlocale(LC_NUMERIC, 'de_DE'); // 소수점 대신 쉼표를 사용
$num2 = 1.2; // (string) 1.2 => '1,2'
echo bcsub($num1, $num2, 1); // => '0.0'
BC Math 함수들
bcadd— 두 임의 정밀도 숫자를 더함bcceil— 임의 정밀도 숫자를 올림bccomp— 두 임의 정밀도 숫자를 비교bcdiv— 두 임의 정밀도 숫자를 나눔bcdivmod— 임의 정밀도 숫자의 몫과 나머지를 구함bcfloor— 임의 정밀도 숫자를 내림bcmod— 임의 정밀도 숫자의 나머지를 구함bcmul— 두 임의 정밀도 숫자를 곱함bcpow— 임의 정밀도 숫자를 거듭제곱bcpowmod— 임의 정밀도 숫자를 거듭제곱하되 지정된 나머지로 축소bcround— 임의 정밀도 숫자를 반올림bcscale— 모든 bc 수학 함수의 기본 소수점 자리수를 설정하거나 가져옴bcsqrt— 임의 정밀도 숫자의 제곱근 구하기bcsub— 한 임의 정밀도 숫자를 다른 숫자에서 뺌
BcMath\Number 클래스
BcMath\Number— 임의 정밀도 숫자 관련 클래스BcMath\Number::add— 임의 정밀도 숫자를 더함BcMath\Number::ceil— 임의 정밀도 숫자를 올림BcMath\Number::compare— 두 임의 정밀도 숫자를 비교BcMath\Number::__construct— BcMath\Number 객체 생성BcMath\Number::div— 임의 정밀도 숫자로 나눔BcMath\Number::divmod— 임의 정밀도 숫자의 몫과 나머지를 구함BcMath\Number::floor— 임의 정밀도 숫자를 내림BcMath\Number::mod— 임의 정밀도 숫자의 나머지를 구함BcMath\Number::mul— 임의 정밀도 숫자를 곱함BcMath\Number::pow— 임의 정밀도 숫자를 거듭제곱BcMath\Number::powmod— 임의 정밀도 숫자를 거듭제곱하되 나머지로 축소BcMath\Number::round— 임의 정밀도 숫자를 반올림BcMath\Number::__serialize— BcMath\Number 객체를 직렬화BcMath\Number::sqrt— 임의 정밀도 숫자의 제곱근 구하기BcMath\Number::sub— 임의 정밀도 숫자를 뺌BcMath\Number::__toString— BcMath\Number를 문자열로 변환BcMath\Number::__unserialize— data 매개변수를 BcMath\Number 객체로 역직렬화
더 알아보기
- BCMath는 숫자를 문자열로 다뤄서 정수·소수 모두 큰 자리수에서 정확해요. 대규모 정수만 필요하다면 GMP 확장이 더 빠른 경우가 많으니 용도에 따라 골라 쓰면 돼요.