## ikr/money-math

gmp-based arbitrary precision operations on currency amounts "XXX.YY"; because floats are BAD for representing money

2 563

21

7

7

v0.1.3 2018-02-20 10:22 UTC

# What does it do?

Arithmetic operations on currency amounts. Amounts on input and output are arbitrary large and precise:

99999999999999999999999999999999999999999999999999999999999999999999999999999999.99
+
0.01
=
100000000000000000000000000000000000000000000000000000000000000000000000000000000.00

However, in cases when the division is involved — like for percentage calculation — the result is rounded to the whole cent: 33% of \$0.50 is \$0.17 instead of \$0.165

As a bonus feature, there's a simple formatting function for amounts in CHF, EUR, USD, GBP, and JPY.

# Why does it exist?

Because storing currency amounts in floats is a really bad idea

# How to use it?

## Installation

Install via Composer package manager:

Just create a composer.json file for your project:

{
"require": {
"ikr/money-math": "0.1.*"
}
}

And run these two commands to install the Composer dependencies:

\$ curl -s http://getcomposer.org/installer | php
\$ php composer.phar install

<?php

## API

use MoneyMath\Decimal2;
use MoneyMath\Currency;

\$a = new Decimal2("3.50");
\$b = new Decimal2("4.50");

\$a->integerValue()                          // 3
\$a->fractionValue()                         // 50
\$a->centsValue()                            // 350

strval(Decimal2::plus(\$a, \$b))              // "8.00"
strval(Decimal2::sum([\$a, \$a, \$b]))         // "11.50"
strval(Decimal2::avg([\$a, \$b]))             // "4.00"
strval(Decimal2::minus(\$a, \$b))             // "-1.00"
strval(Decimal2::multiply(\$a, 2))           // "7.00"
strval(Decimal2::mul(\$a, \$b))               // "15.75"

strval(Decimal2::div(\$a, \$b))               // "0.78"
strval(Decimal2::getPercentsOf(\$a, \$b))     // "0.16" b% of a
strval(Decimal2::cmp(\$a, \$b))               // -1

And last, but not least :)

\$c = new Decimal2("42.02");
strval(Decimal2::roundUpTo5Cents(\$c))       // "42.05"

Which we use for bills in CHF that are required by law to be 0 (mod 5).

For formatting please use the Currency class

(new Currency('EUR'))->format(new Decimal2('-100000000000.00')) // -100.000.000.000,00