And I state: no.
Care to explain? I find that with an initial amount of $100 and with
an interest rate over some period of 2.5%, where the rules state that
the interest has been truncated to the nearest cent, the following
statements (assuming amount to be a long, damount and eamount doubles):
amount += amount * 5 / 200;
damount += damount * 5 / 200;
eamount = rint(eamount * 205 / 200);
there are already differences after the third calculation. You really
need "floor" rather than "rint" in the eamount statement to get the
correct results. And this is only a simple problem of compound
interest.
You are confusing levels. If the rule says truncate, then
truncate do not round. The "rounding" required to
convert a double representation to an integer
representation has little to do with the algorithm used
to compute the double representation.
There are two questions:
What algorithm should be implemented?
What data type should be used to implement the algorithm?
The two questions are different, and the first dominates. When you
change
data type should not change the algorithm!
Consider an algorithm for compound intererest with slightly
modified rounding, principal
p, interest rate per period i, number of periods n, currency dollar.
For period 1 to n
p = round to nearest cent ( p + i p)
We can calculate this using a sufficiently large integer type
or a sufficiently large floating point type. Assume p = 100.00
i= .05/year, the period is 6 months and there are 10 periods.
An integer implementation might look like
long p = 10000;
int 1000_i = 50;
int number_of_periods n=10;
int 1000_i_per_n;
1000_i_per_n = 1000_i / 2;
for(i = 1;i<=n;i++){
p += p*1000_i_per_n/1000
if( 2*( p%1000_i_per_n) >= 1000_i_per_n ){
p++;
}
}
At the end we convert to dollars and cents, dollars = p/100,
cents = p%100.
A floating point implemenation might look like
double p = 10000;
double i = .05;
double i_per_n;
int number_of_periods n = 10;
i_per_n = i/2.0;
for(i = 1;i<=10;i++){
p += p*i_per_n;
if( fmod(100*p,1.0) > 0.495) {
p += .01;
}
}
At the end you determine dollars = floor(p), cents = floor(100*p + 0.5)
I see no clear winner here. Both give exaclty the
same answer (even for unrealistically large values
of n) The rounding rule is a bit clearer
in the integer form (and if we specify truncation it can be
ommited altogether in the integer form, not so in the floating
point form) but the interest rate calculation is a bit more
natural in the floating point form. The integer form only works with
interest rate
per period in multiples of .001. This may need to be made
more precise. If accounting rules so specifiy, the interest rate
per period of the floating point form might have to be made less
precise.
Determining whether the final result after a number of f-p
calculations is within 1/2 of the correct result is not doable.
Depends on the kind of rounding needed for the particular problem.
No. The rounding needed for the particluar problem
is performed. The "rounding" needed to convert from the floating
point representation to an integer representation is something
different.
And when the calculations are only slightly difficult you get problems.
Not different than the problems associated with integer
calculations (you have the advantage that a truncation is
a nop with integer math. Given that you need to implement
general rounding rules in any case, I do not see this as
a big advantage)
And how can you be sure of that?
How do you keep track when you should round? In the above compound
interest example I see already that if I do not round at every step
that I get already a wrong result with f-p after three iterations.
If you do not implement the correct algorithm you get
the wrong answer (Duh!).
You have to round after every step with integer arithmetic.
The fact that if the rounding rule is truncation you can
ommit this step is not true in general.
I do not think so. 64-bit integers are becoming quite common, and
they give better precision than double precision f-p.
And both are too small for some real world problems.
The class of problems for which double is insufficient, but
64 bit integer is sufficient, is not very large.
You still need to deal with fractions. Whether
you do so by using a fixed point system or
approximate rational arithmetic, native
support for 64 bits will only take you so far.
And if floating point does not give the accounting answer, and you want
the accounting answer, then don't use floating point.
A sufficiently precise floating point can be used to implement
any accounting algorithm. The question is whether
this is less convenient that using (sufficiently large)
integer arithmetic.
- William Hughes