Skip to content

Instantly share code, notes, and snippets.

@christoferd
Last active February 13, 2018 21:41
Show Gist options
  • Save christoferd/f0e52f33d848819351fe0187813f7862 to your computer and use it in GitHub Desktop.
Save christoferd/f0e52f33d848819351fe0187813f7862 to your computer and use it in GitHub Desktop.
PHP: Round a number down to two decimal places
/**
* 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