Hello List.
In an earlier post, I received help with a custom function to round
decimals off (the custom function provided by Adam Richardson is below).
However in my MySQL db, when I have values with only 1 decimal point,
I need the value PHP returns to display as 2. For example, 3.8 needs
to display as 3.80.
My line of code that calls the custom function looks like this:
$my_price = round_to_half_cent(number_format($my_price, 3, '.', ','));
When the value of $my_price is 3.81, it returns 3.81. However, when
the value of $my_price is 3.8 that is what it returns.
How can I force the formatting of my_price to always contain either 2
or 3 decimal points (3 if the original number contains 3 or more
decimal points to begin with)
Thanks,
--Rick
On Jan 11, 2010, at 10:39 PM, Adam Richardson wrote:
On Mon, Jan 11, 2010 at 7:45 PM, Mattias Thorslund <mattias@xxxxxxxxxxxx
>wrote:
tedd wrote:
At 2:55 PM -0500 1/11/10, Rick Dwyer wrote:
I have been asked to further modify the value to the nearest half
cent.
So if the 3rd decimal spot ends in 1 or 2, it gets rounded down
to 0
If it ends in 3, 4, 5, 6 it gets rounded to 5. And if it 7, 8 or
9 it
gets rounded up to full cents.
Can this be done fairly easily? Not knowing PHP well, I am not
aware of
the logic to configure this accordingly.
Thanks,
--Rick
--Rick:
The above described rounding algorithm introduces more bias than
simply
using PHP's round() function, which always rounds down. IMO,
modifying
rounding is not worth the effort.
The "best" rounding algorithm is to look at the last digit and do
this:
0 -- no rounding needed.
1-4 round down.
6-9 round up.
In the case of 5, then look to the number that precedes it -- if
it is
even, then round up and if it is odd, then round down -- or vise
versa, it
doesn't make any difference as long as you are consistent.
Here are some examples:
122.4 <-- round down (122)
122.6 <-- round up (123)
122.5 <-- round up (123)
123.4 <-- round down (123)
123.6 <-- round up (124)
123.5 <-- round down (123)
There are people who claim that there's no difference, or are at
odds with
this method, but they simply have not investigated the problem
sufficiently
to see the bias that rounding up/down causes. However, that
difference is
very insignificant and can only be seen after tens of thousands
iterations.
PHP's rounding function is quite sufficient.
Cheers,
tedd
However that's not what Rick is asking for. He needs a function
that rounds
to the half penny with a bias to rounding up (greedy bosses):
Actual Rounded Diff
.011 .010 -.001
.012 .010 -.002
.013 .015 +.002
.014 .015 +.001
.015 .015 .000
.016 .015 -.001
.017 .020 +.003
.018 .020 +.002
.019 .020 +.001
.020 .020 .000
Bias +.005
This could easily be implemented by getting the 3rd decimal and
using it in
a switch() statement.
An unbiased system could look like:
Actual Rounded Diff
.011 .010 -.001
.012 .010 -.002
.013 .015 +.002
.014 .015 +.001
.015 .015 .000
.016 .015 -.001
.017 .020 -.002
.018 .020 +.002
.019 .020 +.001
.020 .020 .000
Bias .000
The only difference is the case where the third decimal is 7.
Cheers,
Mattias
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
Here you go, Rick. Just send the check in the mail ;)
function round_to_half_cent($amount)
{
if (!is_numeric($amount)) throw new Exception('The amount received
by the
"round_to_half_cent" function was not numeric');
$parts = explode('.', str_replace(',', '', (string)$amount));
if (count($parts) >= 3) throw new Exception('The amount received by
the
"round_to_half_cent" function had too many decimals.');
if (count($parts) == 1)
{
return $amount;
}
$digit = substr($parts[1], 2, 1);
if ($digit == 0 || $digit == 1 || $digit == 2)
{
$digit = 0;
}
elseif ($digit == 3 || $digit == 4 || $digit == 5 || $digit == 6)
{
$digit = .005;
}
elseif ($digit == 7 || $digit == 8 || $digit == 9)
{
$digit = .01;
}
else
{
throw new Exception('OK, perhaps we are talking about different
types of
numbers :( Check the input to the "round_to_half_cent" function.');
}
return (double)($parts[0].'.'.substr($parts[1], 0, 2)) + $digit;
}
echo "5.002 = ".round_to_half_cent(5.002);
echo "<br />70,000.126 = ".round_to_half_cent("70000.126");
echo "<br />55.897 = ".round_to_half_cent(55.897);
// should cause exception
echo "<br />One hundred = ".round_to_half_cent("One hundred");
--
Nephtali: PHP web framework that functions beautifully
http://nephtaliproject.com
--Rick
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php