Skip to content

Commit

Permalink
added half-even rounding (#34)
Browse files Browse the repository at this point in the history
* added half-even rounding
  • Loading branch information
aywan authored and krowinski committed Sep 1, 2019
1 parent 4379ac7 commit bba0aba
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 0 deletions.
29 changes: 29 additions & 0 deletions src/BCMathExtended/BC.php
Original file line number Diff line number Diff line change
Expand Up @@ -630,4 +630,33 @@ public static function bitXor(string $leftOperand, string $rightOperand): string
{
return self::bitOperatorHelper($leftOperand, $rightOperand, self::BIT_OPERATOR_XOR);
}

public static function roundHalfEven(string $number, int $precision = 0): string
{
$number = self::convertScientificNotationToString($number);
if (! self::checkIsFloat($number)) {
return self::checkNumber($number);
}

$precessionPos = strpos($number, '.') + $precision + 1;
if (strlen($number) <= $precessionPos) {
return self::round($number, $precision);
}

if ($number[$precessionPos] !== '5') {
return self::round($number, $precision);
}

$isPrevEven = $number[$precessionPos - 1] === '.'
? (int)$number[$precessionPos - 2] % 2 === 0
: (int)$number[$precessionPos - 1] % 2 === 0
;
$isNegative = self::isNegative($number);

if ($isPrevEven === $isNegative) {
return self::roundUp($number, $precision);
}

return self::roundDown($number, $precision);
}
}
41 changes: 41 additions & 0 deletions tests/Unit/BCTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,47 @@ public function shouldRound($expected, $number, $precision = 0): void
self::assertSame($expected, BC::round((string)$number, $precision));
}

public function roundHalfEvenProvider(): array
{
return [
['2', '1.8'],
['2', '1.5'],
['1', '1.2'],
['1', '0.8'],
['0', '0.5'],
['0', '0.2'],
['-0', '-0.2'],
['0', '-0.5'],
['-1', '-0.8'],
['-1', '-1.2'],
['-2', '-1.5'],
['-2', '-1.8'],
['-2.35', '-2.35', 2],
['-2.4', '-2.35', 1],
['2.4', '2.35', 1],
['0', '0.005', 2],
['0.02', '0.015', 2],
['0.02', '0.025', 2],
['0.04', '0.035', 2],
['0.04', '0.045', 2],
['0.06', '0.055', 2],
['0.06', '0.065', 2],
['0.08', '0.075', 2],
['0.08', '0.085', 2],
];
}

/**
* @test
* @dataProvider roundHalfEvenProvider
* @param string $expected
* @param string $number
* @param int $precision
*/
public function shouldRoundHalfEven(string $expected, string $number, int $precision = 0): void
{
self::assertSame($expected, BC::roundHalfEven($number, $precision));
}

public function randProvider(): array
{
Expand Down

0 comments on commit bba0aba

Please sign in to comment.