Last active
February 13, 2018 21:41
-
-
Save christoferd/f0e52f33d848819351fe0187813f7862 to your computer and use it in GitHub Desktop.
PHP: Round a number down to two decimal places
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Custom function to round down to the nearest lowest number at 2 decimal places. | |
* e.g: 1.006 rounds down to 1.00 | |
* Warning: Do not use PHP_ROUND_HALF_DOWN; | |
* round(0.006, 2, PHP_ROUND_HALF_DOWN) does not round down to 0 | |
* | |
* @param $value | |
* - Must be numeric | |
* - Must be a positive value | |
* @return float | |
* @throws \Exception | |
*/ | |
static function roundDown2DecimalPlaces($value) | |
{ | |
// Error Check | |
// - Must be numeric | |
// - Must be a positive value | |
if(!is_numeric($value) || (is_numeric($value) && $value < 0)) { | |
throw new \Exception('Value must be numeric. Got type: '.gettype($value)); | |
} | |
$strValue = strval($value); | |
// Parts: dollars and cents | |
$parts = explode('.', $strValue); | |
if(count($parts) == 2) { | |
// make sure cents is one or two characters at most | |
$cents = substr($parts[1], 0, 2); | |
// cents as a string now | |
// should be two characters long | |
// if not, pad zeros to the end | |
$cents = str_pad($cents, 2, '0', STR_PAD_RIGHT); | |
} | |
else { | |
$cents = '00'; | |
} | |
$s = $parts[0].'.'.$cents; | |
return $s; | |
} | |
// ----------------------------------------------------------------- | |
/* | |
PHPUnit Test | |
GeneralHelperTest.php functions | |
*/ | |
public function test_roundDown2DecimalPlaces() | |
{ | |
$i = 200; | |
while($i < 201.1) { | |
$this->_roundDown2DecimalPlaces($i); | |
// increment | |
$i += 0.001; | |
} | |
$i = 0; | |
while($i < 11) { | |
$this->_roundDown2DecimalPlaces($i); | |
// increment | |
$i += 0.5; | |
} | |
$i = 135.45; | |
echo "\n\nPass #1 - round $i"; | |
$r = $this->_roundDown2DecimalPlaces($i); | |
self::assertEquals(135.45, $r, 'Failed this->_roundDown2DecimalPlaces !!!!!!!!'); | |
echo "\n\nPass #2"; | |
echo "\n\nRound a rounded value..."; | |
$r = GeneralHelper::roundDown2DecimalPlaces($r); | |
self::assertEquals(135.45, $r, 'Failed GeneralHelper::roundDown2DecimalPlaces'); | |
} | |
/** | |
* Keep this here, once proved working methods, we can copy a method to the Library Function. | |
* | |
* @param $i | |
*/ | |
private function _roundDown2DecimalPlaces($i) | |
{ | |
$rounded = GeneralHelper::roundDown2DecimalPlaces($i); | |
echo "\n$i\t | rounded = $rounded"; | |
// Check | |
$si = strval($i); | |
$siLen = strlen($si); | |
$roundedLen = strlen($rounded); | |
if($siLen < $roundedLen) { | |
// $si shorter, fix... | |
// Contains Cents? | |
if(strpos($si, '.') !== false) { | |
// yes | |
$check = str_pad($si, 2, '0'); | |
} | |
else { | |
// no | |
$check = $si.'.00'; | |
} | |
} | |
elseif($siLen > $roundedLen) { | |
// make them the same size | |
$check = substr($si, 0, $roundedLen); | |
} | |
else { | |
$check = $si; | |
} | |
// Check Equals | |
self::assertEquals($check, $rounded, "Check equals failed: si = $si | check = $check | rounded = $rounded"); | |
// Check Cents is 2 places | |
$ex = explode('.', $rounded); | |
self::assertEquals(2, count($ex), "Rounded value does not have cents! $rounded"); | |
if(count($ex) == 2) { | |
self::assertEquals(2, strlen($ex[1]), "Rounded value does not contain 2 decimal places! $rounded"); | |
} | |
return $rounded; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment