ceadreak
ceadreak

Reputation: 1684

PHP / difference between 2 float returns a very big result

I have a strange behavior when try to compute a result ...

In my app, I have an Invoice object with a property totalIncludingTax and another unpaidAmount.

When a payment is settled, The unpaidAmount property is recomputed.

Consider an invoice with a total including tax of 14.35

This returns returns double(14.35)

$invoice->getTotalIncludingTax()

This assertion returns true

$this->assertEquals($invoice->getUnpaidAmount(), ($invoice->getTotalIncludingTax() - 14.35));

BUT this dump returns double(1.7763568394003E-15)

var_dump(($invoice->getTotalIncludingTax() - 14.35)); 

Any idea ?

Edit

This assertion returns true too

$this->assertEquals(0, ($invoice->getTotalIncludingTax() - 14.35));

Upvotes: 0

Views: 309

Answers (2)

Jimit Shah
Jimit Shah

Reputation: 92

I would always prefer to do calculations/comparision in bcmath with the scale of 4 and then round it with the scale of 2 or 0.

check http://php.net/manual/en/book.bc.php

Upvotes: 0

Joseph Young
Joseph Young

Reputation: 2795

1.7763568394003E-15 isn't a big number, it's actually very very small. It's being shown in scientific notation; it's 0.0000000000000017763568394003 in normal form. This is the error due to floating point representations.

The PHP manual states you should compare floats as such:

To test floating point values for equality, an upper bound on the relative error due to rounding is used. This value is known as the machine epsilon, or unit roundoff, and is the smallest acceptable difference in calculations.

$a and $b are equal to 5 digits of precision.

<?php
$a = 1.23456789;
$b = 1.23456780;
$epsilon = 0.00001;

if(abs($a-$b) < $epsilon) {
    echo "true";
}
?>

Perhaps the assertEquals does something similar

Upvotes: 2

Related Questions