At 8:40 PM +0100 2/13/07, Satyam wrote:
----- Original Message ----- From: "Jon Anderson" <jon@xxxxxxxxxxxxxxxxxx>
The reason is simple:
0: No rounding. It's already there. (8.0 doesn't need to be rounded
to 8 - it already *is* 8.)
1-4: You round down -> 4 of 9 times you round down.
5-9: You round up -> 5 of 9 times you round up.
That is not quite correct, there is no such 4 ninths agains 5
ninths. You round down in the interval from 0 to0.499999999 and you
round up from 0.5 to 0.9999999. If you substract the .5 from
0.99999, you get 0.4999999 so it is about the same interval for both.
If there is any difference, and actually there is, is because any
number is, in reality, truncated, and not rounded, at some point.
Depending on the number of bits of the mantissa, it might be a long
way off, but eventually, it will happen, and that one is truncation,
nor rounding, and if you repeat any calculation involving fractional
numbers, it will eventually add up to something noticeable.
Actually, there is the further problem that computers actually use
binary, not decimal, so they cannot represent decimal numbers
exactly. To offer an example of what I'm talking about, 1/3, which
results in a never ending 0.333333 is exactly 0.1 in base 3
arithmetic! Conversely, many 'round' numbers in our decimal
notation are not 'round' in binary and viceversa. So it is all the
piling of lots of rounding errors in real-life number
representations that produce the error, not the mathematics of
rounding, which actually work in an abstract world of infinitely
precise number representations (in other words, infinite bits to
represent any numbers).
Satyam
Satyam and Jon:
Actually, both of you are correct.
The bias in rounding comes from the concept of rounding down for
numbers 0-4 and rounding up for number 5-9. Please, let's take a
critical look at that premise.
For zero, as Jon claims, there is no rounding at all -- you don't do
anything. You can't include zero as one of the conditions that claims
to do something when it doesn't do anything. It doesn't do anything
to the data at all! So, to include zero in a rounding scheme is
fundamentally flawed. Satyam, put your objections on hold for a
moment and consider.
For values one to four, you round down. So, you have four conditions
where you actually do something to the data, you round down.
For values five to nine, you round up. So, you have five conditions
where you actually do something to the data, you round up.
If you do anything four times one way and five times the other,
you're going to introduce a bias.
So, how do you get around this?
One way is to use Statistical (Stochastic) rounding. It singles out
five as being the culprit for this bias. It uses the even/odd rule of
the preceding digit to determine which direction to round 5. If the
value is even, then it rounds up -- whereas if the value is odd, then
it rounds down. (or reverse the rounding, it doesn't matter as long
as you are consistent).
For all other values (1-4 and 6-9, note four each direction) the
typical rounding is observed.
Examples of it at work:
0.5 -> 1 (zero is treated as even -- see below *)
1.5 - >1
2.5 -> 3
3.5 -> 3
4.5 -> 5
5.5 ->5
6.5 -> 7
7.5 -> 7
8.5 -> 9
9.5 - 9
From this distribution (actually all you'll ever need to prove this),
you can see we have just as many cases that round up as we do that
round down -- thus, the aforementioned rounding bias has been
reduced. The negative range is just a mirror image.
Now, one can try to pump this algorithm through a PHP loop to see the
difference (as I've tried) but you'll find that there are rounding
errors (due to what Satyam said about computers representing decimal
numbers exactly) that will prohibit making the algorithm work as
described.
For example, the "built-in" functions, such as intval(), do not work
the way you might expect them to work. Try using this statement:
$t =intval(($number - intval($number)) * 10);
It works fine if the number is 89441560.5 -- it returns 5.
However, if the number is 139690837.6 -- returns 5 instead of 6.
And the list goes on of examples where the result isn't quite what's expected.
If you look deeper into this, you'll find the rounding problem
doesn't really have a solution, but rather it's a compromise. I'm
sure that Rasmus Lendorf could shed some light on this -- remember
the "When is z != z?" argument I started many moons ago? I think this
is along the same lines.
Perhaps the round() function takes all this into account, but I don't
know and therein lies my suspicion.
Cheers,
tedd
*By definition, any number that can be divided by two and leaves no
remainder is even. Some say that the value is undefined, but for sake
of this argument, it's considered even. Besides, symmetry in nature
is more desirable.
--
-------
http://sperling.com http://ancientstones.com http://earthstones.com
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php