Pathological floating point problems: Difference between revisions

Line 228:
 
=={{header|zkl}}==
zkl doesn't have a big rational or big float library (as of this writing) but does have big ints (via GNU GMP). It does have 64 bit doubles.
<lang zkl>Series:=Walker(fcn(vs){ // just keep appending new values to a list
vs.append(111.0 - 1130.0/vs[-1] + 3000.0/(vs[-1]*vs[-2])) }.fp(List(2,-4)));
series:=Series.drop(100).value;</lang>
We'll use the convenient formula given in the referenced paper to create a fraction with big ints
<lang zkl>var BN=Import("zklBigNum"), digitsten2n=BN(10).pow(64);
fcn u(n){ // use formula to create a fraction of big ints
const bB=-3, yY=4;
N:=BN(6).pow(n+1)*bB + BN(5).pow(n+1)*yY;
D:=BN(6).pow(n)*bB + BN(5).pow(n)*yY;
r,m:=tostr(N*digitsten2n/D).toString(), (r.len()-64,32).max(0);
}
String(r[0,m],".",r[m,32]);
 
fcn tostr(bn,m,r){ // convert big int (*10^m) to float string with len r remainder
str,d:=bn.toString(), (str.len()-m).max(0);
String(rstr[0,md],".",rstr[md,32r]);
}
 
Line 247 ⟶ 251:
}</lang>
{{out}}
Note that, at n=100, we still have diverged (at the 15th place) from the Perl6 solution and 12th place from the J solution.
<pre>
1st: Convergent series
Line 259 ⟶ 264:
n = 50; 100.00000000000000000000 6.00017584662718718894561402074719
n =100; 100.00000000000000000000 6.00000001931947792910408680340358
</pre>
Chaotic banking society is just nasty so we use a five hundred digit e (the e:= text is one long line).
<lang zkl>println("\n2nd: Chaotic banking society");
e:="271828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642742746639193200305992181741359662904357290033429526059563073813232862794349076323382988075319525101901157383418793070215408914993488416750924476146066808226480016847741185374234544243710753907774499206955170276183860626133138458300075204493382656029760673711320070932870912744374704723069697720931014169283681902551510865746377211125238978442505695369677078544996996794686445490598793163688923009879312";
var en=e.len(), tenEN=BN(10).pow(en-1);
years,balance:=25, BN(e).sub(tenEN); // in place math
balance=[1..years].reduce(fcn(balance,i){ balance*i - tenEN },balance);
balance=tostr(balance,en,2);
println("After year %d, you will have $%s in your account.".fmt(years,balance));</lang>
{{out}}
<pre>
2nd: Chaotic banking society
After year 25, you will have $.39 in your account.
</pre>
For Rump's example, multiple the formula by 10ⁿ so we can use integer math.
Anonymous user