mirror of
https://github.com/danog/math.git
synced 2024-11-26 20:04:46 +01:00
Add BigNumber::toScale()
This allows to convert any BigNumber to a BigDecimal of the given scale.
This commit is contained in:
parent
0fa9a802c6
commit
c1bdb3b9b5
@ -418,6 +418,8 @@ final class BigDecimal extends BigNumber implements \Serializable
|
||||
/**
|
||||
* Returns a BigDecimal with the current value and the specified scale.
|
||||
*
|
||||
* @deprecated Use `toScale()`.
|
||||
*
|
||||
* @param int $scale
|
||||
* @param int $roundingMode
|
||||
*
|
||||
@ -425,11 +427,7 @@ final class BigDecimal extends BigNumber implements \Serializable
|
||||
*/
|
||||
public function withScale($scale, $roundingMode = RoundingMode::UNNECESSARY)
|
||||
{
|
||||
if ($scale == $this->scale) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
return $this->dividedBy(1, $scale, $roundingMode);
|
||||
return $this->toScale($scale, $roundingMode);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -654,6 +652,20 @@ final class BigDecimal extends BigNumber implements \Serializable
|
||||
return BigRational::create($numerator, $denominator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toScale($scale, $roundingMode = RoundingMode::UNNECESSARY)
|
||||
{
|
||||
$scale = (int) $scale;
|
||||
|
||||
if ($scale === $this->scale) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
return $this->dividedBy(BigDecimal::one(), $scale, $roundingMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -471,6 +471,14 @@ final class BigInteger extends BigNumber implements \Serializable
|
||||
return BigRational::create($this, BigInteger::one(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toScale($scale, $roundingMode = RoundingMode::UNNECESSARY)
|
||||
{
|
||||
return $this->toBigDecimal()->toScale($scale, $roundingMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -354,6 +354,16 @@ abstract class BigNumber
|
||||
*/
|
||||
abstract public function toBigRational();
|
||||
|
||||
/**
|
||||
* Converts this number to a BigDecimal with the given scale, using rounding if necessary.
|
||||
*
|
||||
* @param int $scale The scale of the resulting `BigDecimal`.
|
||||
* @param int $roundingMode A `RoundingMode` constant.
|
||||
*
|
||||
* @return BigDecimal
|
||||
*/
|
||||
abstract public function toScale($scale, $roundingMode = RoundingMode::UNNECESSARY);
|
||||
|
||||
/**
|
||||
* Returns the exact value of this number as a native integer.
|
||||
*
|
||||
|
@ -388,6 +388,14 @@ final class BigRational extends BigNumber implements \Serializable
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toScale($scale, $roundingMode = RoundingMode::UNNECESSARY)
|
||||
{
|
||||
return $this->numerator->toBigDecimal()->dividedBy($this->denominator, $scale, $roundingMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -1678,6 +1678,30 @@ class BigIntegerTest extends AbstractTestCase
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerToScale
|
||||
*
|
||||
* @param string $number
|
||||
* @param int $scale
|
||||
* @param string $expected
|
||||
*/
|
||||
public function testToScale($number, $scale, $expected)
|
||||
{
|
||||
$this->assertBigDecimalEquals($expected, BigInteger::of($number)->toScale($scale));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function providerToScale()
|
||||
{
|
||||
return [
|
||||
['12345678901234567890123456789', 0, '12345678901234567890123456789'],
|
||||
['12345678901234567890123456789', 1, '12345678901234567890123456789.0'],
|
||||
['12345678901234567890123456789', 2, '12345678901234567890123456789.00'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerToInteger
|
||||
*
|
||||
|
@ -4,6 +4,7 @@ namespace Brick\Math\Tests;
|
||||
|
||||
use Brick\Math\BigInteger;
|
||||
use Brick\Math\BigRational;
|
||||
use Brick\Math\RoundingMode;
|
||||
use Brick\Math\Exception\RoundingNecessaryException;
|
||||
|
||||
/**
|
||||
@ -833,6 +834,45 @@ class BigRationalTest extends AbstractTestCase
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerToScale
|
||||
*
|
||||
* @param string $number
|
||||
* @param int $scale
|
||||
* @param int $roundingMode
|
||||
* @param string $expected
|
||||
*/
|
||||
public function testToScale($number, $scale, $roundingMode, $expected)
|
||||
{
|
||||
$number = BigRational::of($number);
|
||||
|
||||
if ($this->isException($expected)) {
|
||||
$this->setExpectedException($expected);
|
||||
}
|
||||
|
||||
$actual = $number->toScale($scale, $roundingMode);
|
||||
|
||||
if (! $this->isException($expected)) {
|
||||
$this->assertBigDecimalEquals($expected, $actual);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function providerToScale()
|
||||
{
|
||||
return [
|
||||
['1/8', 3, RoundingMode::UNNECESSARY, '0.125'],
|
||||
['1/16', 3, RoundingMode::UNNECESSARY, RoundingNecessaryException::class],
|
||||
['1/16', 3, RoundingMode::HALF_DOWN, '0.062'],
|
||||
['1/16', 3, RoundingMode::HALF_UP, '0.063'],
|
||||
['1/9', 30, RoundingMode::DOWN, '0.111111111111111111111111111111'],
|
||||
['1/9', 30, RoundingMode::UP, '0.111111111111111111111111111112'],
|
||||
['1/9', 100, RoundingMode::UNNECESSARY, RoundingNecessaryException::class],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerToInteger
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user