Yes, Jenda, I know (and I said before) that the Rat type should be used for rational numbers, but would not help for irrational numbers. In whatever base, irrational numbers will be approximations. However, there are many many computer applications that would benefit from accuracy in simple additions or subtractions of rational numbers. For example most applications dealing with monetary amounts. So the Rat type doesn't solve all issues, I agree with that and never made any claim to the opposite, but it would solve many issues.
| [reply] |
So the Rat type doesn't solve all issues, I agree with that and never made any claim to the opposite, but it would solve many issues.
It doesn't solve any issues, because there's a hole drilled in the bottom of the Rat type. Your ship will eventually sink, it's just a question of when.
> .3 - .2 - .1
0 # good
> 3*10**-10 - 2*10**-10 - 1*10**-10
0 # good
> 3*10**-20 - 2*10**-20 - 1*10**-20
-1.50463276905253e-36 # oops
Monetary amounts? You will hit this error very fast if you start compounding interest. | [reply] [d/l] |
On compound interests, as I already said earlier, I would normally use the standard exponential formulas and, of course, end up with floats. For example, with a 1.6% interest rate over 10 years compound annually and an initial value of 10,000:
> my $start_val = 10_000;
10000
> my $end_val = $start_val * (1 + 0.016)**10
11720.2555035677
> say $end_val.WHAT
(Num)
But if I make the same calculation without the exponential formula within a a loop:
> my $end_val = $start_val;
10000
> $end_val *= 1.016 for 1..10
Nil
> say $end_val
11720.25550356773576542599
> say $end_val.WHAT
(Rat)
> say $end_val.nude
(17464541649174296506384 1490116119384765625)
As you can see, I still get a Rat. And, BTW, I get a better accuracy with this loop, but, in fact, we don't really care about this better accuracy, since the final monetary amount will be rounded to two decimal places anyway (although you could conceivably find start values for the error on the floating point value would propagate and make a 1 cent difference on the final rounded value). To tell the truth, I was fairly lucky here: with just 11 years, I would no longer get a Rat.
And, of course, the loop will fall back to floats if we compound the interests monthly:
> my $end_val = $start_val * (1 + 0.016/12)**120
11733.8581431786
> say $end_val.WHAT
(Num)
>
> my $end_val = $start_val;
10000
> $end_val *= 1 + 0.016/12 for 1..120
Nil
> say $end_val
11733.8581431787
> say $end_val.WHAT
(Num)
We get the same result (there is a rounding difference of 1 on the last digit, but we don't care, it will be rounded to 11,733.86 anyway).
So yes, we often fall back on floats when compounding interests, but that really doesn't matter, nobody cares.
A company for which I worked as a freelance consultant had to spend tens of thousands of euros in a software project to fix invoices which looked wrong because of rounding problems on FP arithmetic inaccuracies. One invoice in tens of thousands looked wrong (the total was actually accurate, but the individual values and subtotals did not seem to match); some consumers complained and the legal and/or tax authorities demanded a correction. All these amounts would have matched properly if the calculations had been done with Perl 6 Rat type.
| [reply] [d/l] [select] |
| [reply] [d/l] |
What's the rational value of sqrt(2)? What's the rational value of sin(25)?
If you want to deal with these things precisely, you can use Mathematica, or Python's Sympy.
>>> sqrt(2)
sqrt(2)
>>> sqrt(2) * sqrt(6)
2*sqrt(3)
>>> sin(pi*3/2)
-1
Notice, that's exactly -1. No approximation at all. Sympy knows a lot of mathematical identities. For mathematical work, Python is so far ahead of Perl that it's downright embarrassing. To claim that Perl6 is breaking new ground in this area is simply absurd. | [reply] [d/l] |
For mathematical work, Python is so far ahead of Perl that it's downright embarrassing.
I agree that Python is ahead of Perl on that account and it's very unfortunate.
| [reply] |