note 76702 deleted from function.round by danbrown

From: Date: Sun, 17 May 2009 16:17:41 +0000
Subject: note 76702 deleted from function.round by danbrown
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-154788@lists.php.net to get a copy of this message
Note Submitter: smithaapc at NOSPAM dot yahoo dot com ---- round() is broken, plain and simple. The solution must take into account all of the digits of a given number during rounding. Truncating the number before the rounding eliminates valuable information. Consider: myRound(12.4444444443, 2) = 12.45 ... not quite. Try this out instead: function trueRound($value, $figs=1) { if(is_numeric($value) && is_int($figs) && $figs > 0) { // must adjust $figs down 1 for computing significant figures $figs--; // $prec ensures all of the original digits are included in the sprintf format $prec = strpos($value, '.') === false ? strlen($value)-1 : strlen($value)-2; $sci = sprintf('%.'.$prec.'e', $value); list($sig, $mant) = explode('e', $sci); // $base includes all of the significant digits, $test contains all the remaining digits list($base, $test) = explode('.', $sig * pow(10, $figs)); // All 4's on the left side of $test will not be significant in the rounding $test = preg_replace('/^4+/', '', $test); // The first digit in $test that is not a 4 will determine the direction of the rounding $test = preg_replace('/^(\d)\d+/', '$1', $test); if($test > 4) { // If the digit is > 4, then simply round up by adding 1 ... $base += 1; } // ... then simply adjust the decimal point $value = $base * pow(10, $mant-$figs); } return($value); } Note this function rounds up to a number of significant figures (all digits) rather than significant digits (digits after the decimal point). Rounding down could be easily accomplished by passing a switch along with the other parameters. Mike

« previous php.notes (#154788) next »