note 41555 deleted from function.round by danbrown
| From: | danbrown@php.net | Date: | Sun, 17 May 2009 16:23:51 +0000 |
| Subject: | note 41555 deleted from function.round by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-154818@lists.php.net to get a copy of this message | ||
Note Submitter: ga dot N-O-S-P-A-M at lacde dot net
----
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)
// mode=-1 gives floor
// mode=0 (default) gives automatic Round to nearest digit : >5 -> +1
// mode=1 gives ceil
// inverseNeg=0 (default)-> PHP floor/ceil behavior, floor(-2.3)=-6, floor towards -INF
// inverseNeg=1 -> inverse floor/ceil behavior means floor(-2.3)=-5, floor towards 0 in case of
need
{
$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;
}
?>