Re: Rounding errors

From: Richard (riplin_at_Azonic.co.nz)
Date: 09/01/04


Date: 1 Sep 2004 02:56:21 -0700

Robert Wagner <robert@wagner.net.yourmammaharvests> wrote

> >It does. It maintains the average of the infinite precision original
> >real numbers. With enough digits the average is close enough to
> >0.500. Rounding maintains this with an average of 0.500.
 
> What if the numbers were not truncated, computed or rounded? I posted
> a demo of that case to which you had no reasonable answer.

Rounding, as used in Cobol, and in many other languages and in
mathematics works on numbers that are assumed to have an infinite
number of random digits following the point of rounding, as is usually
the case when doing calculations.

If you use this mechanism on numbers that are other than this, for
example if the digits (or implicit digits) are all zeroes or all 9s,
then the answer will not be a good representation of the original, and
simple rounding is not the correct tool. Programmers should be
skilled enough to know what their tools can and cannot do and how to
choose appropriate tools.

> to which you had no reasonable answer.

I am not here to solve your programming problems. However, I did
offer two mechanisms: round and forward, and pre-adjusting by
subtracting .499..5 to the rounding point.

If you don't find these 'reasonable' then I suggest that you look for
other alternatives, or perhaps attend a tutorial where they may teach
you how to solve such problems.

What you seem to require is a mechanism that simultaneously:

 * rounds a set of dollar amounts to thousands based on 5/4 rounding
 * maintains the exact total and average of the original
 * adds up to the rounded exact total

You seem to not want to use bankers rounding or round and forward or
pre-subtract 0.49999..5 because the number must be the exact
thousands based on 5/4 rounding.

In other words you want something that the number system cannot
deliver.

Just who is being unreasonable ?

> You're incorrect. It doesn't work that way in C# nor in JavaScript (I
> don't know about compiled Java).

A quick ferret on Google dragged up on JavaScript:

""" ---------------------------------
""Rounding a Number to a Number
""For a positive number X, Math.round(X) rounds to the nearest
integer,

That seems to be how Cobol does it.

""In my MSIE 4, for X positive or negative :-
""* Math.round(X) for half-integer X rounds towards plus infinity;
...
""Banker's rounding, for 0.5 to the nearest even number, is not used.

There you go, this doesn't use bankers.

""Most real numbers, in particular those with finite base-10
representations, ""cannot be held exactly in a Double. This is why,
for instance, ""Math.round(1.035*100) gives 1.03, but
Math.round(2.035*100) gives 2.04 and ""Math.round(1.045*100) gives
1.05; moreover, RoundToNdp(1.0035, 3) gives 1.004, ""but
RoundToNdp(1.035, 2) gives 1.03.

JavaScript only doesn't give the same result as Cobol because, for
example, 1.035 is represented in floating point by 1.034999... and not
because it works differently.

Certainly, many languages provide floor() and ceiling() as well. Some
also use othertypes of rounding.

> This looks like a Brooklyn Bridge defense. Everyone else is doing
> wrong.

If rounding (as is used in Cobol) is consistenly defined by 'everyone'
to do the same job and the implementations meet that definition, then
where is the 'error' ?

I would suggest that it is with the programmer who used it without
knowing what it was defined to do.

> >This means that you _can_ truncate beyond the third digit without
> >affecting the result of rounding, which is entirely predictable.
>
> You've said that over and over. What's the point of truncating to
> three digits followed by rounding to two? Why not just round in the
> first place?

The point is that _YOU_ introduced the v999 truncation. _YOU_ brought
up the issue by first of all claiming that all v999, v99, v999999 add
up to average 0.500..

I had to go into detail to explain why these did not addup to the same
and why this was irrelevant to the result of the rounding.

Now you are confused about why it was being discussed.

The fact is that you can truncate illustrates that rounding neither
knows nor cares what is beyond the single digit that is used for
rounding.

> Yes, and an infinite number of random errors average to zero. The
> problem is Cobol rounding is not random. It pushes the average upward
> always, unless the numbers happen to end with zero.

No. Once again you fail to understand. Once again you completely
ignore, willfully, what has been said to you over and over.

LISTEN TO ME:

Rounding is defined to operate on numbers with an infinite number of
random digits following the digit that it rounds on.

When used on a set of these numbers it DOES NOT change the average.
This is provable.

> >Now here's the thing: read this 3 times, then come back tomorrow and
> >read it again:
> >
> > The difference between the set of infinite precision reals and
> > the truncated set,
> > and
> > the difference between the rounded set and the truncated set
> >
> > are _identical_ (in ideal conditions)
>
> It didn't take that long.

Read it again. And continue to read it because you obviously don't
understand it yet. You just m,ade a statement above that shows you
completely fail to understand it.

> That's true only in the case where rounding removes one digit.

No that is not true. That is wrong. Read it again. This time
readwhat it says not what you thought it was going to say before
youread it.

> If we take the more common case of dollars.cents
> rounded to dollars, there is an upward bias of half a cent.

Dollar.cent values do not have an infinite number of random digits
after the rounding point. Rounding neither knows nor cares about
this, it works as if they are there.

This is why it is called 'double rounding' and is a beginners error, a
programmers error. Your error.

I have already explained in detail exactly what happens when you do
this and how a _competent_ programmer copes with this. For example by
using round and forward or pre-subtracting 0.0049999..5

What I am astounded by is that after 30 years of programming you are
still unaware of how numbers work and how to cope with this. I would
expect this shortfall in skill and knowledge in a newbie with no
formal training.

> >If the set of infinite precision reals adds up to the same as the set
> >of rounded numbers (which it does under ideal conditions). Then any
> >set that is less than that set (such as a truncated set) will have the
> >_same_ difference to the two sets that have the same total.
> >
> >How hard is that ?
>
> It's based on a false premise -- that the truncation error is offset
> by the rounding error. They are two separate issues that don't
> necessarily cancel out.

THEY DON'T 'CANCEL OUT' AT ALL. You still need to go back and read
what I told you to read 3 times.

1. The rounded set (R) has an identical average to the infinite
precision set
   (P). (provable for ideal conditions)

2. Truncation discards digits and thus has a lesser value for set (T)
   (provable)

3. ( R - T ) == ( P - T ) (bacause R == P )

4. Rounding only needs n + 1 digits to give the rounded set (R)
    (definition)

5. (P) -> (T n+1) -> (R n) gives (R) == (P)

How hard _is_ this ?
 
> >> When I present cases where there was no truncation to correct, you
> >> brush them aside by saying the rules are different for integers.
> >
> >Rounding works on real numbers of infinite precision and random digits
> >beyond the rounding point to create numbers with fixed precision.
> >
> >If you use it on numbers that do not have those characteristics then
> >either you put up with the errors (of usage) or you modify the
> >technique to cater for the differences that you _should_ expect.
>
> What does that mean .. in English?

If you cannot follow that then either you are trolling or I would
serious doubt your ability to follow such things are the Cobol
standard or a program spec.

> There is no reason rounding should
> work differently on dollars rounded to thousands than it does on cents
> rounded to dollars. As i pointed out in another thread, they're both
> scaled integers at machine level.

There is no difference in these two. Neither have an infinite number
of random digits following the rounding point. They have 3 and 2
non-zero digits respectively, then they have an infinite number of
implicit zeroes.

> >> Your argument is an appeal to ignorance.
> >
> >I really don't know what to say without it seeming like an ad hominem
> >attack ;-)
>
> Just say I'm an idiot. You've done it before. :)

It may yet come to that.

> I have found a better definition. So have others who are serious about
> the subject. It's called Nearest-unbiased.

Good. As you should notice it is a _different_ definition and is used
for different requirements. Do not use it when wanting a rounded
result of a multiply or divide - it will give the wrong answer.

'Nearest-unbiassed' requires more digits than rounding. It can be
implemented by subtracting 0.004999..5 from the dollar cent amounts
prior to using (standardCobol) rounding.

Perhaps you may recognise my 'reasonable' suggestion.



Relevant Pages

  • Re: XQ and ->Qpi bug on large X
    ... you shouldn't be rounding to only two digits ... I am trying to make a similar point here about rounding; ... and round it, ... prior to using the input values in calculations. ...
    (comp.sys.hp48)
  • RE: prePEP: Decimal data type
    ... > the rounding procedure to be used in computations involving Euros ... implementing a fixed number of decimal digits "after the decimal point" ... To convert from the euro to the national currency, ... currency should then be rounded to two decimals. ...
    (comp.lang.python)
  • Re: Rounding a floating point number
    ... double roundto(double x, int digits) ... if (digits> DBL_DIG) ... rounding the value 1.2345 to 2 decimal ... What is the purpose of rounding a floating-point value to N decimal ...
    (comp.lang.c)
  • Re: Rounding errors
    ... >>number of random digits following the point of rounding, ... > an infinite number of digits right of decimal. ... multiplication nor what the number of digits in the calculations was. ...
    (comp.lang.cobol)
  • Re: Rounding errors
    ... >number of random digits following the point of rounding, ... an infinite number of digits right of decimal. ... If we round to cents with Cobol, ...
    (comp.lang.cobol)