다음 코드는 총 2줄의 출력을 내고 종료된다.
<?php
$subtotal = "8311.609";
$tax = (float) $subtotal * 0.1;
echo 'PHP $tax: ' . $tax . PHP_EOL;
echo 'JSON $tax: ' . json_encode($tax) . PHP_EOL;
exit(0);
그 첫번째 출력은 다음과 같다.
PHP $tax: 831.1609
그런데 그 두번째 출력은 다음과 같다.
JSON $tax: 831.1609000000001
그렇다 실무 프로그래밍을 하다 보면 한 번씩은 얻어맞는 부동소수점 문제다. 사실 이건 모든 프로그래밍 언어가 저마다 씨름하고 있는 문제이므로, 그 해결법/회피법이 어떠한가를 보면 그 언어의 개성을 엿볼 수 있지 않은가 생각한다.
그리고 PHP에는 이 문제를 처리하는 아주 "멋진" walkaround가 알려져 있다.
위 코드를 딱 한 줄만 고쳐 보자.
$tax = (float) ($subtotal * 0.1 . '');
그러면 거짓말처럼 두 출력이 같아진다.
PHP $tax: 831.1609
JSON $tax: 831.1609
굳이 설명을 하자면, 이는 PHP가 float
을 string
으로 변환하는 과정에서 epsilon을 제거하기 때문에 가능한 일이다. 잘 생각해 보면, 처음 코드에서도 PHP $tax
는 잘 출력되었는데 그게 왜 가능한 거였더냐 하면 "출력"을 위해서 $tax
라는 float
자료를 string
으로 형변환했기 때문에 가능한 거였거든.
PHP는 형 관련해서 잘 모르겠으면 무조건 문자열로 변환/취급/처리하는 게 제일인 거 같다.