Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP casting float to int returns different value

Tags:

php

casting

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?

like image 305
DerLola Avatar asked Sep 15 '15 15:09

DerLola


People also ask

When casting a float to an int what happens to the value?

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.

Why is float not precise?

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.

What is Floatval PHP?

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.


1 Answers

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....

like image 123
Steve E. Avatar answered Oct 14 '22 19:10

Steve E.