note 106395 deleted from function.round by danbrown

From: Date: Tue, 15 Nov 2011 16:53:41 +0000
Subject: note 106395 deleted from function.round by danbrown
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-184514@lists.php.net to get a copy of this message
Note Submitter: cygnus2k at gmail dot com ---- Re-definition of round for early versions of php: <?php function roundhelper( $value, $mode) { $tmp_value=0.0; if ($value >= 0.0) { $tmp_value = floor($value + 0.5); if (($mode == "PHP_ROUND_HALF_DOWN" && $value == (-0.5 + $tmp_value))) { $tmp_value = $tmp_value - 1.0; } } else { $tmp_value = ceil($value - 0.5); if (($mode == "PHP_ROUND_HALF_DOWN" && $value == (0.5 + $tmp_value))) { $tmp_value = $tmp_value + 1.0; } } return $tmp_value; } function mathround( $value, $places, $mode) { $f1=0.0; $f2=0.0; $tmp_value=0.0; $precision_places=0; /*if (!php_math_is_finite($value)) { return $value; }*/ $precision_places = 14 - floor(log10(abs($value))); $f1 = pow(10, abs($places)); /* If the decimal precision guaranteed by FP arithmetic is higher than the requested $places BUT is small enough to make sure a non-zero $value is returned, pre-round the result to the precision */ if ($precision_places > $places && $precision_places - $places < 15) { $f2 = pow(10, abs($precision_places)); if ($precision_places >= 0) { $tmp_value = $value * $f2; } else { $tmp_value = $value / $f2; } /* preround the result (tmp_$value will always be something * 1e14, thus never larger than 1e15 here) */ $tmp_value = roundhelper($tmp_value, $mode); /* now correctly move the decimal point */ $f2 = pow(10, abs($places - $precision_places)); /* because $places < $precision_places */ $tmp_value = $tmp_value / $f2; } else { /* adjust the value */ if ($places >= 0) { $tmp_value = $value * $f1; } else { $tmp_value = $value / $f1; } /* This $value is beyond our precision, so rounding it is pointless */ if (abs($tmp_value) >= 1e15) { return $value; } } /* round the temp value */ $tmp_value = roundhelper($tmp_value, $mode); /* see if it makes sense to use simple division to round the value */ if (abs($places) < 23) { if ($places > 0) { $tmp_value = $tmp_value / $f1; } else { $tmp_value = $tmp_value * $f1; } } else { /* Simple division can't be used since that will cause wrong results. Instead, the number is converted to a string and back again using strtod(). strtod() will return the nearest possible FP value for that string. */ /* 40 Bytes should be more than enough for this format string. The float won't be larger than 1e15 anyway. But just in case, use snprintf() and make sure the buffer is zero-terminated */ //char buf[40]; snprintf($buf, 39, "%15fe%d", $tmp_value, -$places); $buf[39] = '\0'; //tmp_value = zend_strtod(buf, NULL); /* couldn't convert to string and back */ /*if (!zend_finite(tmp_value) || zend_isnan(tmp_value)) { tmp_value = value; }*/ } return $tmp_value; } $numero=number_format("1254.50",2,'.',''); echo "Valor: " . mathround($numero , 0, "PHP_ROUND_HALF_DOWN") ."\n"; //SHOW 1254 $numero=number_format("1254.51",2,'.',''); echo "Valor: " . mathround($numero , 0, "PHP_ROUND_HALF_DOWN") ."\n"; //SHOW 1255 ?>

« previous php.notes (#184514) next »