Tomm Carr [mailto:[EMAIL PROTECTED]] wrote:
> Sent: Friday, September 20, 2002 7:16 PM
> To: JDJList
> Subject: [jdjlist] Re: Double multiplication
>
>
> Roger Glover wrote:
>
> >You are confusing accuracy with precision. You cannot get
> >penny-level accuracy if your number scheme only supports 14
> >decimal digits of precision (like IEEE double) and the number to
> >be represented is one hundred trillion(US: 10-to-the-14th)
> >dollars(US).
> >
> Depends on which calculations you are performing. If tracking the
> expenditures within any particular agency, you are working at the penny
> level but the total amount is significantly lower than 100 trillion
> dollars. If working with total budgets values as, for instance, the
> breakdown of the entire Federal budget, the values are in increments of
> $1000. So a $100 trillion budget would be 1.0e11 instead of 1.0e14.
My point was only that there is a limit to how large a number will
support penny-level accuracy when you are using IEEE double precision.
Obviously you don't run into currency-based problems on the order of
a decade's worth of the GNP every day, especially ones that care
about pennies.
But here is an example that comes to mind:
"Calculate the total annual monetary flux through the New York
Stock Exchange in a year."
The average daily share volume tends to hover between 1.0E9 and
1.5E9 lately. There are over 200 trading days in a year. Stock prices
tend to sit between hundreds and tens of thousands of "pennies", with
thousands of "pennies" far and away the most common. So it seems to me
that we now have a problem where penny-level precision is important, but
where the final result very likely will be too large for IEEE double
precision to give penny-level accuracy.
> Besides, the entire Federal budget is, what, something around $5 or $6
> trillion. It will probably be another year or two before it hits $100
> trillion.
Be that as it may, the really big numbers are in capitalism, not in
government. The NYSE example is but a small one. Nasdaq generally has
higher trading volumes than NYSE, and commodities exchanges and options
exchanges (CBOE, PHLX) leave stock exchanges in the dust.
> >However, when dealing with normal (significantly smaller) amounts you
> >should be able to get the desired accuracy, unless the number of
> >calculations begins to cause rounding error to creep into the pennies
> >digit...
> >
> Rounding error starts creeping in at the very first calculation,
Of course, but rounding error starts at the *LEAST SIGNIFICANT BIT*. It
should not reach the *PENNIES DIGIT* for quite some time, unless we are
dealing with Terabucks (see above). That is why, in normal usage, it
suffices to round a double result to some small number of significant
figures, using, for example, NumberFormat in Java. The high-level
explicit rounding operation sweeps away the low-level digits corrupted
by machine rounding error.
> unless you happen to hit those specific values that are absolutely
> represented by the bits
Those specific values can be characterized as multiples of powers of
one-half. More specifically i*(1/2-raised-to-the-k), where i and k are
integers and |i| < 2-raised-to-the-24th.
But that is all beside the point. If you add 10.22 + 8.43 and display
the result rounded to the nearest hundredth, you should still see 18.65,
even though machine rounding occured:
o When 10.22 was converted to IEEE double
o When 8.43 was converted to IEEE double
o When the two doubles were added together
This is a proper, useful, and efficient way to "resolve" the machine
rounding problem. It generally beats the pants off of the awkward, slow,
and unmaintainable BigDecimal solution.
> >Err... no. The padded cell crowd, if they are serious about
> >these ridiculous precisions, have many alternatives to Java that
> >are more appropriate for this kind of work.
> >
> Possibly. That doesn't mean the developers of Java weren't trying to
> win over some of them.
If so, then they took the wrong approach. It is not that hard to cobble
together arbitrary precision numbers out of longs and doubles. The hard
part is getting the calculation to run fast enough to fill all those
digits of precision before you die of old age. BigDecimal solves the
minor problem while exacerbating the major problem. Not the best way to
win mindshare.
> >A long will hold the first 92 terms of the classic Fibonacci sequence.
> >Am I to understand that you needed more terms than that?
> >
> I don't know -- I only wrote it, I don't use it. However, I did set a
> limit of 256 (double the long limit and round up to the next power of
> two). It was a nice, round (binarily speaking) value and I figured any
> value larger than that was an error and attention should be brought to
> it. Besides, I didn't even want to test to see how long it would take
> to generate fib(65536)!
It would be much faster with the Binet analytic formula, but you would
need really, really large-precision logarithms to get ones-digit accuracy
in the final result. :-)
> >Besides that, if you use doubles you will lose precision sooner
> >than you will with longs. A double can represent a larger absolute
> >value than a long, but doubles have *less* precision than longs:
> > double: 14 decimal digits of precision.
> > long: 18 decimal digits of precision.
> >
> True. Aamof, I wrote it originally using longs. But as I couldn't get
> a guarantee that even that limit would never, ever be exceeded. Maybe
> I'll insert some code to keep track of the largest value it is asked to
> generate and check it periodically. Then again, it works -- I've gotten
> no complaints -- so maybe I'll leave it be.
That doesn't really prove anything, does it? It would require an extremely
anal-retentive nature to use a packaged call to calculate F(100), say, and
then go behind and write the code to check to see if the result was right!!
> Besides, it stores the values it generates into an array. If called to
> generate a value, and it has already generated that value or higher, it
> indexes into the array and returns. So even though it uses BigInteger,
> the overall performance is excellent.
True, but all this talk about BigInteger is still pulls us away from the
original point. The performance problems with BigDecimal far outweigh those
of BigInteger. After all, BigInteger is still performing binary machine
calculations under the surface, but BigDecimal performs *SIMULATED*
calculations using **PACKED DECIMAL** notation. YUK!! Also, BigInteger has
nothing to do with resolving binary fraction roundoff errors in machine
arithmetic.
> >That is why most statistical calculations which require division of
> >factorials are based on the algebraic reduction of the ratio to least
> >(algebraic) terms. So in the following calculation:
> > (n!)/((n-r)!)
> >The computation would be reduced to something like this:
> > long n = whatever;
> > long r = somethinglessthanwhatever;
> > long result = 1;
> > for( long i = 0; i < r; i++ )
> > {
> > result *= n - i;
> > }
> >
> >In this case, if we are sure the result will be "reasonable",
> >then we can be sure that each of the intermediate terms is
> >"reasonable" as well.
> >
> True, again. Maybe statistics was not the best example to use. I was
> just examining the real-world uses of BI & BD and including the
> possibility of calculations that generate extremely large interim values
> -- and that can't be so conveniently canceled out.
May I refer you to my Stock Exchange example above? :-)
> >If you had taken the time to read the Javadoc before asking this
> >question, ...
> >
> Had I been working with BD, I would have. It was just idle curiosity.
> But thanks for the answer, anyway. 8^)
De nada.
-- Roger
To change your JDJList options, please visit: http://www.sys-con.com/java/list.cfm