Skip to content

Instantly share code, notes, and snippets.

@abznak
Created June 28, 2011 06:55
Show Gist options
  • Save abznak/1050638 to your computer and use it in GitHub Desktop.
Save abznak/1050638 to your computer and use it in GitHub Desktop.
lesson - do not use floats for money
<?php
#don't use floats for money!
$a = 110; # $110
$b = 1.10 * 100; # 100 items at $1.10 each
#$b = 110 -1E-13;
print "a: "; var_dump($a);
print "b: "; var_dump($b);
print "\n";
print "a: $a\n";
print "b: $b\n";
print "\n";
if ($a < $b) {
print "a is less than b\n";
}
if ($b < $a) {
print "b is less than a\n";
}
print "difference: " . ($a - $b)."\n";
@abznak
Copy link
Author

abznak commented Jun 28, 2011

Output:

a: int(110)
b: float(110)

a: 110
b: 110

a is less than b
difference: -1.4210854715202E-14

@md2perpe
Copy link

That's a very small difference. It will hardly make any trouble as long as you know that you shouldn't do direct comparisions like value1 == value2 but instead use abs(value1 - value2) < 0.0001.

@abznak
Copy link
Author

abznak commented Jun 28, 2011

True, I could have written "do not use floats for money unless the code is designed to handle it".

Personally, for storing monetary values, I still prefer using fixed point types or faking them with ints. I think the occasional $value/100 when outputting is a small price to pay to be able to use direct comparisons.

@md2perpe
Copy link

I agree that decimals are better to use. In MySQL there's a DECIMAL type (although at work we use integers with the two least significant digits being öre/cents/...), but in PHP you either have to create your own class via integers or use a library like BC or GMP.

@abznak
Copy link
Author

abznak commented Aug 29, 2011

serialize will show the detail that var_dump, var_export and print all hide:
$ php -r "print serialize(1.1 * 100);"
d:110.0000000000000142108547152020037174224853515625;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment