Basic Idea

Decimals in PHP are essentially float by default. This can come with a few caveats.
See the following example:

$decimalOne = 0.10;
$decimalTwo = 0.20;
$decimalAdded = $decimalOne + $decimalTwo;

Actual value: 0.30000000000000004

Now lets compare that with 0.3 somewhere:

$balance = 0.30 - $decimalAdded;
$positiveBalance = $balance >= 0;  // We count 0 as OK

Positive balance: NO

Value objects

So in order to have a better handling of those values, using strings is recommended. But even strings are not easy to work with often. Using a value object can overcome also those issues and provide a clear API.

use PhpCollective\DecimalObject\Decimal;

$decimalOne = Decimal::create('0.10');
$decimalTwo = Decimal::create('0.20');
$decimalAdded = $decimalOne->add($decimalTwo);

Actual value: 0.30

Internal object result

PhpCollective\DecimalObject\Decimal Object
(
    [value] => 0.30
    [scale] => 2
)

It also keeps track of the scale and therefore on output will also give the correct (expected) precision/scale for each value if needed.

Now let's try the founds check again:

$balance = Decimal::create('0.30')->subtract($decimalAdded);
$positiveBalance = !$balance->isNegative(); // We count 0 as OK

Positive balance: YES

See this for basic examples and API details.


Send your feedback or bugreport!