|
|
 |
rand | sin |  | | Last updated: Thu, 19 May 2005 |
round (PHP 3, PHP 4, PHP 5) round -- Rounds a float Descriptionfloat round ( float val [, int precision] )
Returns the rounded value of val to
specified precision
(number of digits after the decimal point).
precision can also be negative or zero (default).
Example 1. round() examples |
<?php
echo round(3.4); echo round(3.5); echo round(3.6); echo round(3.6, 0); echo round(1.95583, 2); echo round(1241757, -3); echo round(5.045, 2); echo round(5.055, 2); ?>
|
|
Note:
The precision parameter was introduced
in PHP 4.
See also:
ceil(),
floor(), and
number_format().
User Contributed Notes
round
twain47 at gmail dot com
10-May-2005 09:25
roger dot anzoategui at gmail dot com
06-Apr-2005 11:14
Ron, very good observation, in some occasions the behavior of an accounting system in which I participated, the following problem occurred: reduces it of two exact values did not give zero due to that millionths of difference in the decimals they existed (not yet itself if due to the own algorithms of the microprocessor or of the language, did not I have the opportunity to do a bench, and the surest thing is that this Reason that may not have been able to notice me previously).
Your observation I have it present in my code.
ron at korving dot demon dot nl
11-Feb-2005 04:46
Unfortunately, ranzoategui's (and my revision) round version did not work well (try to round 8.075 to 2 decimals for example).
I found out the best way to achieve a good round is to add a tiny number to the value before rounding. This seems to work fine in all cases (and luckily it's faster than previous methods):
<?
function stdround($num, $d=0)
{
return round($num + 0.0001 / pow(10, $d), $d);
}
?>
10-Feb-2005 08:23
If you want more speed, and you dont need any decimals returned, use this:
<?php
$number = 254.51263;
$round = (int)($number+0.5); ?>
This way is 32% faster than calling the round() function in this situation (tested!).
ron at korving dot demon dot nl
07-Feb-2005 08:12
This is a slighty shorter and faster version of ranzoategui's round function:
<?
function stdround($num, $d=0)
{
$d = pow(10, $d);
return round(floor($num * $d * 10) / 10) / $d;
}
?>
This function behaves exactly like round(), except for the fact that it doesn't apply a so called bankers' rounding algorithm, but a more classic approach (where a 5 is always rounded up).
For more info on Banker's rounding: http://en.wikipedia.org/wiki/Significance_arithmetic
ranzoategui at bolivia dot com
06-Jan-2005 02:16
<?php
function approx( $value, $dec = 2 ) {
$value += 0.0;
$unit = floor( $value * pow( 10, $dec + 1 ) ) / 10;
$round = round( $unit );
return $round / pow( 10, $dec );
}
?>
martin at chinese-monkey dot com
13-Nov-2004 11:16
If you didn't want to use 'ceil()' or 'floor()' as it only rounds to a whole number u could do this:
<?php
$actual_value = 3.352;
$number = 0.01; $temp1 = $actual_value * 2;
$temp2 = $temp1 + $number; $temp3 = $temp2 / 2;
$new_value = round($temp3, 2);
echo $new_value; ?>
red at aztec dot sk
19-Jul-2004 07:21
Better is:
<?php
$actual_value = 3.45; $half_round = round(($actual_value*2), 0)/2; ?>
or
<?php
$actual_value = 3.45; $temp1 = $actual_value * 2; $temp2 = round($temp1, 0); $half_round = $temp2 / 2 ?>
NOT
<?php
$actual_value = 3.45; $temp1 = $actual_value * 2; $temp2 = round($actual_value, 0); $half_round = $temp2 / 2 ?>
Dan
06-Jul-2004 04:08
a simpler solution to the 'round to a half' method suggested by monte at ispi dot net, below. This version returna the actual number.
<?php
$actual_value = 3.45; $temp1 = $actual_value * 2; $temp2 = round($actual_value, 0); $half_round = $temp2 / 2 ?>
monte at ispi dot net
28-Jun-2004 08:31
Just a quick note on rounding to the nearest "half" instead of nearest "whole". I my case, I'm showing a user rating with stars and need to show a star for each whole, and half a star for remainder values closer to half than whole.
// replace 3.45 with any rating
$_actual_rating = 3.45;
$_rating_round_half = round($_actual_rating / 0.5) * 0.5;
$_remainder = fmod($_rating_round_half, 1);
$_rating = (int) $_rating_round_half - $_remainder;
$_half_star = $_remainder == 0.5;
In the above example, $_rating will contain a whole number for the number of stars to display, and $_half_star will be a boolean to determine whether or not to display half a star as well.
ga dot N-O-S-P-A-M at lacde dot net
14-Apr-2004 12:49
If you want a complete and simple solution to round for n digits you should use this function at the bottom.
(you may want this to be even clearer with nice defines like below but it is not obliged if you use -1/0/1)
<?php
define(FLOOR,-1);
define(NEARER,0);
define(CEIL,1);
?>
$myNiceValue=MyApprox($value,3); <- nearest value for 3 digits
$myNiceValue=MyApprox($value,3,FLOOR); <- floor value
ex:
MyApprox(2.36745,3); // 2.37
MyApprox(1462.36745,3); // 146 (because nearer)
MyApprox(1465.36745,3); // 147 (because nearer)
MyApprox(1462.36745,3,FLOOR); // 146
MyApprox(1462.36745,3,CEIL); // 147
MyApprox(-1462.36745,3); // -146 (because nearer)
MyApprox(-1465.36745,3); // -147 (because nearer)
MyApprox(-1462.36745,3,FLOOR); // -147 <-- like PHP but for n digit
MyApprox(-1462.36745,3,CEIL); // 146 <-- like PHP but for n digit
The last argument ($inverseNeg) is provided only if you want to switch floor and ceil for negative value to overide the common behaviour of php. (little chances it would be useful for you)
This must work for php > 4.0.5
if you want to make it work for < versions you may only have to change the str_replace to do not use arrays but 2 str_replace instead.
It may be really interesting to have this kind of functions directly in php !
Plz note that this one is probably not the quicker code possible I coded it quickly. (if you need speed it's better to use directly the method you want anyway)
Note that it's simple to use a "common" behavior in your script(s) :
define(APPROX_METHOD,-1)
MyApprox($value,$n,APPROX_METHOD);
...
So you can change once for all the method or even by choice of your user.
<?php
function MyApprox($fValue,$sigdigits=0,$mode=0,$inverseNeg=0)
{
$sValue=''.(float)($fValue);
$lenght=strlen($sValue);
$isNeg=$fValue<0;
if(($sigdigits<=0)||($sigdigits==False))
{
if(($inverseNeg)&&($isNeg)) $mode=-$mode;
if($mode==-1) return floor($fValue);
if($mode==1) return ceil($fValue);
return round($fValue);
}
$posDot=strpos($sValue,'.');
$sResult=str_replace(array('.','-'),'', $sValue);
$fResult=0.0;
if(($mode==0)&&(intval($sResult{$sigdigits})>=5)) $fResult=1.0;
$sResult=substr($sResult,0,$sigdigits);
$fResult+=(float)$sResult;
if($isNeg)
{
if($inverseNeg)
{
if($mode==1) $fResult+=1;
}
else if($mode==-1) $fResult+=1;
}
else if($mode==1) $fResult+=1;
if($posDot==False) $posDot=$lenght;
$numb=$sigdigits-($posDot-$isNeg);
if($numb>0) for($i=0;$i<$numb;$i++) $fResult/=10.0;
else if($numb<0) for($i=0;$i<$numb;$i++) $fResult*=10.0;
if($isNeg) return -$fResult;
else return $fResult;
}
?>
terry at scribendi dot com
12-Jan-2004 01:45
To round any number to a given number of significant digits, use log10 to find out its magnitude:
round($n, ceil(0 - log10($n)) + $sigdigits);
Or when you have to display a per-unit price which may work out to be less than a few cents/pence/yen you can use:
// $exp = currency decimal places - 0 for Yen/Won, 2 for most others
$dp = ceil(0 - log10($n)) + $sigdigits;
$display = number_format($amount, ($exp>$dp)?$exp:$dp);
This always displays at least the number of decimal places required by the currency, but more if displaying the unit price with precision requires it - eg: 'English proofreading from $0.0068 per word', 'English beer from $6.80 per pint'.
ssttoo at hotmail dot com
05-Dec-2003 06:12
Having done the following test:
<?php
$test_numbers = array (1.255,3.255,10.255);
foreach ($test_numbers AS $number){
echo "<br />Number:<b> " . $number . "</b>";
echo "<br />Printf():<b> ";
printf("%.2f",$number);
echo "</b><br />Printf() and round(): <b> ";
printf("%.2f",round($number,2));
echo "</b><br />Printf() and round() *100/100:<b> ";
printf("%.2f",round($number*100)/100);
echo "</b><br />----------------";
}
?>
it looks that small numbers are not always rounded the way one expects, regardless of the rounding method used. The results are:
Number: 1.255
Printf(): 1.25
Printf() and round(): 1.25
Printf() and round() *100/100: 1.25
----------------
Number: 3.255
Printf(): 3.25
Printf() and round(): 3.25
Printf() and round() *100/100: 3.26
----------------
Number: 10.255
Printf(): 10.26
Printf() and round(): 10.26
Printf() and round() *100/100: 10.26
So to get around this I came out with a small 'fuzz'-ing:
<?php
function myFormattedRoundedNumber($number, $fuzz = 0.00000000001){
return sprintf("%.2f", (($number>=0) ? ($number+$fuzz) : ($number-$fuzz)));
}
?>
As you can see, it also takes into account the negative numbers.
PiotrL
12-Nov-2003 07:44
There are many ways to round floating-point numbers.
And many valid (!) algorithms. This is because the algorithm depends on the domain of value and sometimes on... country.
For example as far as I know in my country money is rounded in the same way as in math calculations:
1.4 => 1
1.5 => 2
1.6 => 2
and
2.5 => 3
A lot of rounding algorithms (and very easy to implement in every language) can be found here:
http://www.merlyn.demon.co.uk/pas-chop.htm
25-Aug-2003 06:12
Many have thus far mentioned problems encountered when trying to add a small fuzz factor to a number such as 1.499999999. This is the way I get around that problem using , allbeit probably less efficient than assuming a small possiblitiy for error:
$numberToRound = 1.5;
//Convert to string.
$numberToRound = "$numberToRound";
//iff number ends in a "5", add fuzz
if (eregi("$5", $pages)) $pages += .000001;
$round = round($pages, 0);
ianring (at) golden.net
07-Aug-2003 02:30
The round() function may indeed work properly with half-values (eg. 1.5), but this little method will give you peace of mind. Add some "fuzz" to your function with a miniscule delta value.
$delta = 0.00001;
$x = round($x+$delta);
This is fine, unless $x has a value of 1.49999 ... if you worried about that, use this method instead:
if(($x-floor($x))==0.5){
$x+=$delta;
}
$x = round($x);
you can change your "optimistic" delta into a "pessimistic" delta by subtracting instead of adding.
Cheers,
Ian Ring
ralf dot schreijer at smc dot uni-muenster dot de
18-Jun-2003 07:39
The function below regards a higher number of digits for rounding as the number of digits you want to round! At least it rounds a Value to the number of digits you want to:
function MyRound($iValue, $iDigits, $iPrecision){
$iDigits = intval($iDigits);
$iPrecision = intval($iPrecision);
if($iDigits > $iPrecision){ $iPrecision = $iDigits; }
for($i = $iPrecision; $i >= $iDigits; $i--){
$iValue = round($iValue, $i);
} // for($i = $iPrecision; $i >= $iDigits; $i--) -- END
return $iValue;
}
Oromian
12-May-2003 07:08
<?
$percent = "48";
$num = round($percent/5)*5;
echo $num;
$percentt = "47";
$numm = round($percentt/5)*5;
echo $numm;
?>
eb at st-us dot com
17-Jan-2003 01:16
/*next line will output 1.4999 as 1.49, no round. Use it if you want to collect fractional money less than 0.01 after for example % calculations.*/
$a=1.4999;
$a = sprintf("%01.2lf", floor($a*100)/100); //$a=1.49
tichoux at charlevoix dot net
23-Oct-2002 04:06
for a poll, if you want to have 100% and not 99 or 99.99 % you can do that :
round( number_format( (($individual_result*100)/$total_result), 2), 1)
kt at netspirit dot ch
20-Aug-2002 11:10
because of some site-effects between round() and modulo, therfore the result is not exactly at every time ...
another way ( and without site-effects) of getting 0.05 increments for currencies, f.e. swiss francs:
$res = (round(20*$chf))/20;
echo $res;
with kind regards
php at silisoftware dot com
14-Aug-2002 04:15
Here's a function to round to an arbitary number of significant digits. Don't confuse it with rounding to a negative precision - that counts back from the decimal point, this function counts forward from the Most Significant Digit.
ex:
round(1241757, -3); // 1242000
RoundSigDigs(1241757, 3); // 1240000
Works on negative numbers too. $sigdigs should be >= 0
function RoundSigDigs($number, $sigdigs) {
$multiplier = 1;
while ($number < 0.1) {
$number *= 10;
$multiplier /= 10;
}
while ($number >= 1) {
$number /= 10;
$multiplier *= 10;
}
return round($number, $sigdigs) * $multiplier;
}
dalef at bendnet dot com
25-Mar-2002 01:27
for php 3.x, if you need to use the precision arg:
function round3x($val,$precision){
$exp = pow(10,$precision);
$val = $val * $exp;
$val = round($val);
$val = $val / $exp;
return $val;
}
js5 at sanger dot ac dot uk
17-Jan-2002 01:17
This isn't a bug. Rounding of "halves" is usally done to the even number. This means that on average half of the "halves" are rounded up and half of the "halves" are rounded down. So that
any "average" calculated should not be affected by the rounding.
felix at innovative-web dot NOSP dot AM dot de
31-Dec-2001 08:07
Hi!
Yet another update to the bcround function. Vittorio Moccia pointed out that it didn't work with "infinite" precision. However, the function below allows you to gain the precision you need. $precision specifies the number of decimals behind $decimals that shall be used for rounding (10 or 20 is a good value). Hope this was the last bug in the function. If you find any more, don't hesitate to contact me.
function bcround ($number, $decimals, $precision)
{
$precision_add = str_repeat("5",$precision);
if (bccomp($number,0) > 0)
{
return (bcadd (bcadd ($number, "0.".str_repeat("0",$decimals).$precision_add, $decimals+$precision), 0, $decimals));
}
else
{
return (bcadd (bcsub ($number, "0.".str_repeat("0",$decimals).$precision_add, $decimals+$precision), 0, $decimals));
}
}
- Felix Schwarz, Innovative
twan at ecreation dot nl
15-May-2000 08:51
If you'd only want to round for displaying variables (not for calculating on the rounded result) then you should use printf with the float:
printf ("%6.2f",3.39532);
This returns: 3.40 .
rand | sin |  | | | Last updated: Thu, 19 May 2005 |
| |