brick / money

A money and currency library for PHP
MIT License
1.61k stars 96 forks source link

Unexpected `RoundingNecessaryException` on get integer value #87

Closed vjik closed 3 months ago

vjik commented 3 months ago

Example:

$money = Money::of('4556.23', 'USD', roundingMode: RoundingMode::HALF_CEILING);
$money->getAmount()->toInt();
BenMorel commented 3 months ago

Hi,

The rounding mode provided in of() only applies to the amount given as first parameter; it is not stored in the Money object, and every subsequent operation will still use RoundingMode::UNNECESSARY unless specified otherwise.

Here is what happens if you pass a value to of() that does not fit in 2 decimal places (default for USD):

use Brick\Math\RoundingMode;
use Brick\Money\Context\CustomContext;
use Brick\Money\Money;
$money = Money::of('4556.235', 'USD'); // RoundingNecessaryException
$money = Money::of('4556.235', 'USD', roundingMode: RoundingMode::HALF_CEILING); // USD 4556.24

Here is how to convert a Money with 2 decimal places to 0 decimal places, with rounding:

$money = Money::of('4556.23', 'USD'); // USD 4556.23
$money->to(new CustomContext(0), RoundingMode::HALF_CEILING); // USD 4556

Finally, here is how you can convert the Money's amount to 0 decimal places, with rounding:

$money = Money::of('4556.23', 'USD'); // USD 4556.23
$money->getAmount()->toScale(0, RoundingMode::HALF_CEILING)->toInt(); // 4556
BenMorel commented 3 months ago

I updated the README in d88c3c66efa2dcf319592a1fb0a3e68b87edc59a.