Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

deal with integer limits #115

Merged
merged 4 commits into from
Jan 4, 2016
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,16 @@
},
"require-dev": {
"kriswallsmith/buzz": "~0.15",
"phpunit/phpunit": "^4.5"
"phpunit/phpunit": "^4.5",
"ext-bcmath": "*",
"ext-gmp": "*"
},
"suggest": {
"TheBigBrainsCompany/TbbcMoneyBundle": "Very complete Symfony2 bundle with support for Twig, Doctrine, Forms, ...",
"pink-tie/money-bundle": "Pink-Tie's Symfony2 integration with Money library",
"Sylius/SyliusMoneyBundle": "Sylius' Symfony2 integration with Money library"
"Sylius/SyliusMoneyBundle": "Sylius' Symfony2 integration with Money library",
"ext-bcmath": "Calculate without integer limits",
"ext-gmp": "Calculate without integer limits"
},
"autoload": {
"psr-4": {
Expand Down
95 changes: 95 additions & 0 deletions src/Calculator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?php
namespace Money;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing newline

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get why this is necessary, but OK, I will add it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consistency.


/**
* Interface Calculator
* @package Money
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please remove package phpdoc and add yourself as an author (If you are OK with that)?

*/
interface Calculator
{

/**
* @return bool
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it's kind of obvious, but can you please add some documentation here as well?

*/
public static function supported();

/**
* Compare a to b
*
* @param int|string $a
* @param int|string $b
* @return int
*/
public function compare($a, $b);

/**
* Add added to amount
*
* @param int|string $amount
* @param int|string $addend
* @return int|string
*/
public function add($amount, $addend);

/**
* Subtract subtrahend from amount
* @param int|string $amount
* @param int|string $subtrahend
* @return int|string
*/
public function subtract($amount, $subtrahend);

/**
* Multiply amount with multiplier
*
* @param int|string $amount
* @param int|float $multiplier
* @return int|string
*/
public function multiply($amount, $multiplier);

/**
* Divide amount with divisor
*
* @param int|string $amount
* @param int|float $divisor
* @return int|string
*/
public function divide($amount, $divisor);

/**
* Round number to following integer
*
* @param int|string|float $number
* @return int|string
*/
public function ceil($number);

/**
* Round number to preceding integer
*
* @param int|string|float $number
* @return int|string
*/
public function floor($number);

/**
* Round number, use rounding mode for tie-breaker
*
* @param int|string|float $number
* @param int|string $roundingMode
* @return int|string
*/
public function round($number, $roundingMode);

/**
* Share amount among ratio / total portions
*
* @param int|string $amount
* @param int|float $ratio
* @param int|float $total
* @return int|string
*/
public function share($amount, $ratio, $total);

}
195 changes: 195 additions & 0 deletions src/Calculator/BcMathCalculator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
<?php
namespace Money\Calculator;

use Money\Calculator;
use Money\Money;
use Money\Number;

/**
* Class BcMathCalculator
* @package Money\Calculator
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add yourself as an author (if you are OK with that) and remove the rest from here.

*/
final class BcMathCalculator implements Calculator
{
/**
* @var string
*/
private $scale;

/**
* @param int $scale
*/
public function __construct($scale = 14)
{
$this->scale = $scale;
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-extra line

/**
* {@inheritdoc}
*
* @return bool
*/
public static function supported()
{
return extension_loaded('bcmath');
}

/**
* {@inheritdoc}
*
* @param $a
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Return and param docs are not necessary with inheritdoc.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not agree with this. The phpDocumentor documentation says "The inline tag {@inheritdoc} is used in a description to import the description of a parent element, even if the child element already has a description." So {@inheritdoc} is only relevant to the description. The current Money class also contains inherited docblock with return docs.

* @param $b
* @return int
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a new line before return statements

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case of interface implementations, use {@inheritdoc} please.

*/
public function compare($a, $b)
{
return bccomp($a, $b);
}

/**
* {@inheritdoc}
*
* @param $amount
* @param $addend
* @return string
*/
public function add($amount, $addend)
{
return bcadd($amount, $addend);
}

/**
* {@inheritdoc}
*
* @param $amount
* @param $subtrahend
* @return string
*/
public function subtract($amount, $subtrahend)
{
return bcsub($amount, $subtrahend);
}

/**
* {@inheritdoc}
*
* @param $amount
* @param $multiplier
* @return string
*/
public function multiply($amount, $multiplier)
{
return bcmul($amount, $multiplier, $this->scale);
}

/**
* {@inheritdoc}
*
* @param $amount
* @param $divisor
* @return string
*/
public function divide($amount, $divisor)
{
return bcdiv($amount, $divisor, $this->scale);
}

/**
* {@inheritdoc}
*
* @param $number
* @return string
*/
public function ceil($number)
{
$decimalSeparatorPosition = strpos($number, '.');
if ($decimalSeparatorPosition === false) {
return $number;
}

return bcadd($number, '1', 0);
}

/**
* {@inheritdoc}
*
* @param $number
* @return string
*/
public function floor($number)
{
return bcadd($number, '0', 0);
}

/**
* {@inheritdoc}
*
* @param $number
* @param $roundingMode
* @return string
*/
public function round($number, $roundingMode)
{
$number = new Number($number);
if ($number->isDecimal() === false) {
return (string) $number;
}

if ($number->isHalf() === false) {
return $this->roundDigit($number);
}

if ($roundingMode === Money::ROUND_HALF_DOWN) {
return $this->floor((string) $number);
}

if ($roundingMode === Money::ROUND_HALF_UP) {
return $this->ceil((string) $number);
}

if ($roundingMode === Money::ROUND_HALF_EVEN) {
if ($number->isCurrentEven() === true) {
return $this->floor((string) $number);
} else {
return $this->ceil((string) $number);
}
}

if ($roundingMode === Money::ROUND_HALF_ODD) {
if ($number->isCurrentEven() === true) {
return $this->ceil((string) $number);
} else {
return $this->floor((string) $number);
}
}

throw new \InvalidArgumentException('Unknown rounding mode');
}

/**
* @param $number
* @return string
*/
private function roundDigit(Number $number)
{
if ($number->isCloserToNext()) {
return $this->ceil((string) $number);
}

return $this->floor((string) $number);
}

/**
* {@inheritdoc}
*
* @param $amount
* @param $ratio
* @param $total
* @return string
*/
public function share($amount, $ratio, $total)
{
return $this->floor(bcdiv(bcmul($amount, $ratio, $this->scale), $total, $this->scale));
}

}
Loading