When I'm executing the following code in PHP (v5.5.9) something unexpected happens:
$valueAsCents = 54780 / 100 * 100;
var_dump($valueAsCents);
var_dump((int) $valueAsCents);
This returns
float 54780
int 54779
So apparently the float value with no decimals, is not equal to the int value. Any ideas of what's going on here?
When you convert a floating-point value to integer type, the fractional part is simply discarded (i.e. not the nearest value is taken, but the number is rounded towards zero). If the result does not fit into the target integer type, the behavior is undefined.
Floating-point decimal values generally do not have an exact binary representation. This is a side effect of how the CPU represents floating point data. For this reason, you may experience some loss of precision, and some floating-point operations may produce unexpected results.
The floatval() function is an inbuilt function in PHP which returns the float value of a variable. Syntax: float floatval ( $var ) Parameters: This function accepts one parameter which is mandatory and described below: $var: The variable whose corresponding float value will be returned.
When you divide $valueAsCents = 54780 / 100 then it becomes a float which is not always accurate in digital form because of the way they are stored. In my tests I got
547.7999999999999545252649113535881042480468750000
When multiplied by 100 this is would be
54779.9999999999927240423858165740966796870000
When PHP casts to int, it always rounds down.
When converting from float to integer, the number will be rounded towards zero.
This is why the int value is 54779
Additionally, the PHP manual for float type also includes a hint that floating point numbers may not do what you expect.
Additionally, rational numbers that are exactly representable as floating point numbers in base 10, like 0.1 or 0.7, do not have an exact representation as floating point numbers in base 2, which is used internally, no matter the size of the mantissa. Hence, they cannot be converted into their internal binary counterparts without a small loss of precision. This can lead to confusing results: for example, floor((0.1+0.7)*10) will usually return 7 instead of the expected 8, since the internal representation will be something like 7.9999999999999991118....
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With