컴퓨터는 모든 숫자를 2진수로 표현하기 때문에
부동 소수점에 약간의 오차범위가 생기게 됩니다.
<?php
echo floor( 2.0 * 100 )."<br>";
echo floor( 2.1 * 100 )."<br>";
echo floor( 2.2 * 100 )."<br>";
echo floor( 2.3 * 100 )."<br>"; // 부동소수점 오류
echo floor( 2.4 * 100 )."<br>";
echo "<br>";
echo ((2.0 * 100) % 10 )."<br>";
echo ((2.1 * 100) % 10 )."<br>";
echo ((2.2 * 100) % 10 )."<br>";
echo ((2.3 * 100) % 10 )."<br>"; // 부동소수점 오류
echo ((2.4 * 100) % 10 )."<br>";
?>200
210
220
229
240
0
0
0
9
0값이 이렇게 뛰는 현상이 생기게 됩니다. 이 때 해결하는 방법은 bcmath 나 gmp 를 활용하는 방법이 있습니다.
0.15는 순환소수, 0.16은 유한소수입니다. 컴퓨터는 2진수로만 표현하기 때문에 순환소수의 경우에는 깔끔하게 값이 떨어지지 않게 됩니다. 이러한 문제를 해결하기 위해서는 int 로 활용할 수 있도록 값을 정수로 바꾸어 계산하는 등의 작업을 거쳐야 합니다.
float 으로 되어있다면 decimal(소수) 로 변환하여 사용하는 방법소수점으로 저장이 되었
계산의 정확도를 따지면 DB에서 쿼리로 계산하는 것이 유리할 수도 있습니다.
유지보수에 유리한 방향으로 설계하는 것이 중요하니 도입하기 전 여러가지로 고려를 한 뒤 적용하는 것이 좋습니다.
select cast(amount * 100 as int) as "Cents"
from shopkeeper where createddate between date_trunc('day', now()) - interval '1 day' and date_trunc('day', now())SQL 구문에서 계산을 하게 되면 연산에 에러가 덜 뜨게 만들 수 있으니 한번 고려하는 것도 방법이라 생각합니다.
strval() 함수를 사용하여 문자형으로 변경하여 해결하는 방법입니다.
성능에 제약을 줄 수 있기 때문에 이런 방법도 있다. 라고 봐주시면 좋을 것 같아요
strval($data)-strval($data)