Pathological floating point problems: Difference between revisions

m
(Added Wren)
m (→‎{{header|Wren}}: Minor tidy)
 
(19 intermediate revisions by 12 users not shown)
Line 81:
in precision. A lot of more precise formats have been added since.<br>
'''A sequence that seems to converge to a wrong limit'''<br>
<langsyntaxhighlight lang="360asm">* Pathological floating point problems 03/05/2016
PATHOFP CSECT
USING PATHOFP,R13
Line 133:
YREGS
YFPREGS
END PATHOFP</langsyntaxhighlight>
The divergence comes very soon.
{{out}}
Line 159:
===Task 1: Converging Sequence===
 
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO;
 
procedure Converging_Sequence is
Line 204:
Task_With_Short;
Task_With_Long;
end Converging_Sequence;</langsyntaxhighlight>
 
{{out}}
Line 233:
===Task 2: Chaotic Bank Society===
 
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO, Ada.Numerics;
 
procedure Chaotic_Bank is
Line 268:
Task_With_Short;
Task_With_Long;
end Chaotic_Bank;</langsyntaxhighlight>
 
{{out}}
Line 309:
===Task 3: Rump's Example===
 
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO; use Ada.Text_IO;
procedure Rumps_example is
Line 327:
Put("Rump's Example, Long: ");
LIO.Put(C, Fore => 1, Aft => 16, Exp => 0); New_Line;
end Rumps_example; </langsyntaxhighlight>
 
{{out}}
Line 337:
{{works with|ALGOL 68G|Any - tested with release 2.8.3.win32}}
In Algol 68G, we can specify the precision of LONG LONG REAL values
<langsyntaxhighlight lang="algol68">BEGIN
# task 1 #
BEGIN
Line 383:
print( ( "25 year chaotic balance: ", fixed( chaotic balance, -22, 16 ), newline ) )
END
END</langsyntaxhighlight>
{{out}}
<pre>
Line 419:
 
awk code:
<langsyntaxhighlight lang="awk">
BEGIN {
do_task1()
Line 461:
}
 
</syntaxhighlight>
</lang>
 
This version doesn't include the arbitrary-precision libraries, so the program demonstrates the incorrect results:
Line 508:
===First two tasks===
{{libheader|GMP}}
<syntaxhighlight lang="c">
<lang C>
#include<stdio.h>
#include<gmp.h>
Line 603:
return 0;
}
</syntaxhighlight>
</lang>
The reason I included the trivial case was the discovery that the value of 0.3 is stored inexactly even by GMP if 0.1 and 0.2 are set via the mpf_set_d function, a point observed also during the solution of the [[Currency]] task. Thus mpf_set_str has been used to set the values, for the 2nd task, a great learning was not to convert the values into floating points unless they have to be printed out. It's a polynomial with out a single floating point coefficient or exponent, a clear sign that the values must be treated as rationals for the highest accuracy. Thus there are two implementations for this task in the above code, one uses floating points, the other rationals. There is still a loss of accuracy even when floating points are used, probably during the conversion of a rational to a float.
<pre>
Line 643:
The following sections source code must be located in a single file.
 
<langsyntaxhighlight lang="csharp">#define USE_BIGRATIONAL
#define BANDED_ROWS
#define INCREASED_LIMITS
Line 711:
SetConsoleFormat(0);
}
}</langsyntaxhighlight>
 
===Task 1: Converging sequence===
'''See''' [[#VB.NET Task 1]]
 
<langsyntaxhighlight lang="csharp">static class Task1
{
public static IEnumerable<float> SequenceSingle()
Line 833:
}
}
}</langsyntaxhighlight>
 
{{out}}
Line 853:
'''See''' [[#VB.NET Task 2]]
 
<langsyntaxhighlight lang="csharp">static class Task2
{
public static IEnumerable<float> ChaoticBankSocietySingle()
Line 946:
}
}
}</langsyntaxhighlight>
 
{{out}}
Line 995:
'''See''' [[#VB.NET Task 3]]
 
<langsyntaxhighlight lang="csharp">static class Task3
{
public static float SiegfriedRumpSingle(float a, float b)
Line 1,116:
Console.WriteLine($" Exact: {br}");
}
}</langsyntaxhighlight>
 
{{out}}
Line 1,136:
In Clojure, rational numbers are a first class data type! This allow us to avoid these floating point calculation problems. As long as the operations all involve integers, rational numbers will automatically be used behind the scenes. If for some twisted reason you really wanted to introduce the error, you could change a number to a floating point in the equation to force floating point calculations instead.
===Task 1: Converging Sequence===
<langsyntaxhighlight lang="clojure">(def converge-to-six ((fn task1 [a b] (lazy-seq (cons a (task1 b (+ (- 111 (/ 1130 b)) (/ 3000 (* b a))))))) 2 -4))
(def values [3 4 5 6 7 8 20 30 50 100])
; print decimal values:
(pprint (sort (zipmap values (map double (map #(nth converge-to-six (dec %)) values)))))
; print rational values:
(pprint (sort (zipmap values (map #(nth converge-to-six (dec %)) values))))</langsyntaxhighlight>
 
{{out}}
Line 1,173:
 
===Task 2: Chaotic Bank Society===
<langsyntaxhighlight lang="clojure">(def e-ratio 106246577894593683/39085931702241241)
(defn bank [n m] (- (* n m) 1))
(double (reduce bank (- e-ratio 1) (range 1 26)))</langsyntaxhighlight>
 
{{out}}
Line 1,187:
 
===Task 3: Rump's Example===
<langsyntaxhighlight lang="clojure">(defn rump [a b]
(+ (* (rationalize 333.75) (expt b 6))
(* (expt a 2)
Line 1,194:
(/ a (* 2 b))))
; Using BigInt numeric literal style to avoid integer overflow
(double (rump 77617 33096N))</langsyntaxhighlight>
 
{{out}}
Line 1,200:
-0.8273960599468214
</pre>
 
=={{header|Crystal}}==
{{trans|Ruby}}
===Task 1: Muller's sequence===
A) Using BigDecimal "div" (similar to Ruby's "quo" method), default iterations 100, here 132 min for last stable output.
<syntaxhighlight lang="ruby">require "big"
 
ar = [0.to_big_d, 2.to_big_d, -4.to_big_d]
 
100.times { ar << 111 - 1130.to_big_d.div(ar[-1], 132) + 3000.to_big_d.div((ar[-1] * ar[-2]), 132) }
 
[3, 4, 5, 6, 7, 8, 20, 30, 50, 100].each do |n|
puts "%3d -> %0.16f" % [n, ar[n]]
end
</syntaxhighlight>
{{Out}}
<pre> 3 -> 18.5000000000000000
4 -> 9.3783783783783790
5 -> 7.8011527377521617
6 -> 7.1544144809752490
7 -> 6.8067847369236327
8 -> 6.5926327687044388
20 -> 6.0435521101892693
30 -> 6.0067860930312058
50 -> 6.0001758466271875
100 -> 6.0000000193194776
</pre>
 
B) Using BigRationals.
<syntaxhighlight lang="ruby">require "big"
 
ar = [0, 2, -4].map(&.to_big_r)
 
100.times { ar << (111 - 1130.to_big_r / ar[-1] + 3000.to_big_r / (ar[-1] * ar[-2])) }
 
[3, 4, 5, 6, 7, 8, 20, 30, 50, 100].each do |n|
puts "%3d -> %0.16f" % [n, ar[n]]
end
</syntaxhighlight>
{{Out}}
<pre> 3 -> 18.5000000000000000
4 -> 9.3783783783783772
5 -> 7.8011527377521608
6 -> 7.1544144809752490
7 -> 6.8067847369236327
8 -> 6.5926327687044379
20 -> 6.0435521101892684
30 -> 6.0067860930312049
50 -> 6.0001758466271866
100 -> 6.0000000193194776
</pre>
 
===Task 2: Chaotic Bank Society===
C) Unlike Ruby, had to manually create "E" to sufficient precision.
<syntaxhighlight lang="ruby">require "big"
 
def e(precision)
y = BigDecimal.new(10.to_big_i ** precision, precision)
d = y
i = 1
 
while true
d = (d / i).scale_to(y)
y2 = y + d
return y if y2 == y
y = y2
i += 1
end
end
 
balance = e(50) - 1
1.upto(25) { |y| balance = (balance * y) - 1 }
puts "Bank balance after 25 years = #{balance.to_f}"</syntaxhighlight>
{{Out}}
<pre>Bank balance after 25 years = 0.03993872967323021</pre>
 
D) Or from Factor, use large rational approximation for "E = 106246577894593683 / 39085931702241241".
<syntaxhighlight lang="ruby">require "big"
e = 106246577894593683.to_big_d.div(39085931702241241.to_big_d)
 
balance = e - 1
1.upto(25) { |y| balance = (balance * y) - 1 }
puts "Bank balance after 25 years = #{balance.to_f}"</syntaxhighlight>
{{Out}}
<pre>Bank balance after 25 years = 0.03993873004901714</pre>
 
===Task 3: Rump's example===
Using BigRationals.
<syntaxhighlight lang="ruby">require "big"
 
def rump(a, b)
a, b = a.to_big_r, b.to_big_r
333.75.to_big_r * b**6 + a**2 * (11 * a**2 * b**2 - b**6 - 121 * b**4 - 2) + 5.5.to_big_r * b**8 + a / (2 * b)
end
puts "rump(77617, 33096) = #{rump(77617, 33096).to_f}"</syntaxhighlight>
{{out}}<pre>rump(77617, 33096) = -0.8273960599468213
</pre>
 
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
{{libheader| Velthuis.BigIntegers}}
{{libheader| Velthuis.BigRationals}}
{{libheader| Velthuis.BigDecimals}}
{{Trans|Go}}
<syntaxhighlight lang="delphi">
program Pathological_floating_point_problems;
 
{$APPTYPE CONSOLE}
 
uses
System.SysUtils,
Velthuis.BigIntegers,
Velthuis.BigRationals,
Velthuis.BigDecimals;
 
type
TBalance = record
e, d: BigInteger;
end;
 
procedure Sequence(Precision: Integer);
var
v, v1, c111, c1130, c3000, t2, t3: BigRational;
n: integer;
begin
BigDecimal.DefaultPrecision := Precision;
v1 := 2;
v := -4;
n := 2;
c111 := BigRational(111);
c1130 := BigRational(1130);
c3000 := BigRational(3000);
 
var r :=
function(): BigRational
begin
t3 := v * v1;
t3 := BigRational.Create(BigDecimal.Divide(c3000, t3));
t2 := BigRational.Create(BigDecimal.Divide(c1130, v));
result := c111 - t2;
result := result + t3;
end;
 
writeln(' n sequence value');
 
for var x in [3, 4, 5, 6, 7, 8, 20, 30, 50, 100] do
begin
while n < x do
begin
var tmp := BigRational.Create(v);
v := BigRational.Create(r());
v1 := BigRational.Create(tmp);
inc(n);
end;
 
var f := double(v);
writeln(format('%3d %19.16f', [n, f]));
end;
end;
 
procedure Bank();
var
balance: TBalance;
m, one, ef, df: BigInteger;
e, b: BigDecimal;
begin
balance.e := 1;
balance.d := -1;
one := BigInteger.One;
 
for var y := 1 to 25 do
begin
m := y;
balance.e := m * balance.e;
balance.d := m * balance.d;
balance.d := balance.d - one;
end;
 
e := BigDecimal.Create('2.71828182845904523536028747135');
 
ef := balance.e;
df := balance.d;
 
b := e * ef;
b := b + df;
 
writeln(format('Bank balance after 25 years: $%.2f', [b.AsDouble]));
end;
 
function f(a, b: Double): Double;
var
a1, a2, b1, b2, b4, b6, b8, two, t1, t21, t2, t3, t4, t23: BigDecimal;
begin
var fp :=
function(x: double): BigDecimal
begin
Result := BigDecimal.Create(x);
end;
 
a1 := fp(a);
b1 := fp(b);
a2 := a1 * a1;
b2 := b1 * b1;
b4 := b2 * b2;
b6 := b2 * b4;
b8 := b4 * b4;
 
two := fp(2);
t1 := fp(333.75);
t1 := t1 * b6;
t21 := fp(11);
t21 := t21 * a2 * b2;
t23 := fp(121);
t23 := t23 * b4;
 
t2 := t21 - b6;
t2 := (t2 - t23) - two;
t2 := a2 * t2;
 
t3 := fp(5.5);
t3 := t3 * b8;
 
t4 := two * b1;
t4 := a1 / t4;
 
var s := t1 + t2;
s := s + t3;
s := s + t4;
result := s.AsDouble;
end;
 
procedure Rump();
var
a, b: Double;
begin
a := 77617;
b := 33096;
writeln(format('Rump f(%g, %g): %g', [a, b, f(a, b)]));
end;
 
{ TBigRationalHelper }
 
 
begin
for var Precision in [100, 200] do
begin
writeln(#10'Precision: ', Precision);
sequence(Precision);
bank();
rump();
end;
 
readln;
end.</syntaxhighlight>
{{out}}
<pre>Precision: 100
n sequence value
3 18,5000000000000000
4 9,3783783783783790
5 7,8011527377521617
6 7,1544144809752490
7 6,8067847369236327
8 6,5926327687044388
20 6,0435521101892693
30 6,0067860930312058
50 6,0001758466271866
100 100,0000000000000000
Bank balance after 25 years: $0,04
Rump f(77617, 33096): -0,827396059946821
 
Precision: 200
n sequence value
3 18,5000000000000000
4 9,3783783783783772
5 7,8011527377521617
6 7,1544144809752499
7 6,8067847369236336
8 6,5926327687044388
20 6,0435521101892693
30 6,0067860930312067
50 6,0001758466271875
100 6,0000000193194776
Bank balance after 25 years: $0,04
Rump f(77617, 33096): -0,827396059946821</pre>
 
=={{header|Excel}}==
{{works with|Excel 2003|Excel 2015}}
'''A sequence that seems to converge to a wrong limit'''<br>
<syntaxhighlight lang="text"> A1: 2
A2: -4
A3: =111-1130/A2+3000/(A2*A1)
A4: =111-1130/A3+3000/(A3*A2)
...</langsyntaxhighlight>
The result converges to the wrong limit!
{{out}}
Line 1,252 ⟶ 1,538:
=={{header|Factor}}==
These problems are straightforward due to Factor's rational numbers. One needs only take care not to introduce floating point values to the calculations.
<langsyntaxhighlight lang="factor">USING: formatting fry io kernel locals math math.functions
math.ranges sequences ;
IN: rosetta-code.pathological
Line 1,282 ⟶ 1,568:
77617 33096 f "77617 33096 f = %.16f\n" printf ;
 
MAIN: pathological-demo</langsyntaxhighlight>
{{out}}
<pre>
Line 1,314 ⟶ 1,600:
Here, no such attempt is made. In the spirit of Formula Translation, this is a direct translation of the specified formulae into Fortran, with single and double precision results on display. There is no REAL*16 option, nor the REAL*10 that some systems allow to correspond to the eighty-bit floating-point format supported by the floating-point processor. The various integer constants cause no difficulty and I'm not bothering with writing them as <integer>.0 - the compiler can deal with this. The constants with fractional parts happen to be exactly represented in binary so there is no fuss over 333.75 and 333.75D0 whereas by contrast 0.1 and 0.1D0 are not equal. Similarly, there is no attempt to rearrange the formulae, for instance to have <code>A**2 * B**2</code> replaced by <code>(A*B)**2</code>, nor worry over <code>B**8</code> where 33096**8 = 1.439E36 and the largest possible single-precision number is 3.4028235E+38, in part because arithmetic within an expression can be conducted with a greater dynamic range. Most of all, no attention has been given to the subtractions...
 
This would be F77 style Fortran, except for certain conveniences offered by F90, especially the availability of generic functions such as EXP whose type is determined by the type of its parameter, rather than having to use EXP and DEXP for single and double precision respectively, or else... The END statement for subroutines and functions names the routine being ended, a useful matter to have checked. <langsyntaxhighlight Fortranlang="fortran"> SUBROUTINE MULLER
REAL*4 VN,VNL1,VNL2 !The exact precision and dynamic range
REAL*8 WN,WNL1,WNL2 !Depends on the format's precise usage of bits.
Line 1,383 ⟶ 1,669:
WRITE (6,*) "Single precision:",SR4(77617.0,33096.0)
WRITE (6,*) "Double precision:",SR8(77617.0D0,33096.0D0) !Must match the types.
END</langsyntaxhighlight>
 
====Output====
Line 1,506 ⟶ 1,792:
A simple function CBSERIES handles the special case deposit. The only question is how many terms of the series are required to produce a value accurate to the full precision in use. Thanks to the enquiry function EPSILON(x) offered by F90, the smallest number such that ''1 + eps'' differs from ''1'' for the precision of ''x'' is available without the need for cunning programming; this is a constant. An alternative form might be that EPSILON(X) returned the smallest number that, added to X, produced a result different from X in floating-point arithmetic of the precision of X - but this would not be a constant. Since the terms of the series are rapidly diminishing (and all are positive) a new term may be too small to affect the sum; this happens when S + T = S, or 1 + T/S = 1 + eps, thus the test in CBSERIES of T/S >= EPSILON(S) checks that the term affected the sum so that the loop stops for the first term that does not.
 
A misthimk had TINY(S) instead of EPSILON(S), and this demonstrates again the importance of providing output that shows the actual behaviour of a scheme and comparing it to expectations, since it showed that over a hundred terms were being calculated and the last term was tiny. Routine TINY(S) reports the smallest possible floating-point number in the precision of its parameter, which is not what is wanted! EPSILON(S) is tiny, but not so tiny as TINY(S). 2·220446049250313E-016 instead of 2·225073858507201E-308. <langsyntaxhighlight Fortranlang="fortran"> SUBROUTINE CBS !The Chaotic Bank Society.
INTEGER YEAR !A stepper.
REAL*4 V !The balance.
Line 1,541 ⟶ 1,827:
CBSERIES = S !Convergence is ever-faster as N increases.
END FUNCTION CBSERIES !So this is easy.
END SUBROUTINE CBS !Madness! </langsyntaxhighlight>
 
And the output is (slightly decorated to show correct digits in bold):
Line 1,575 ⟶ 1,861:
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang="freebasic">' FB 1.05.0 Win64
 
' As FB's native types have only 64 bit precision at most we need to use the
Line 1,672 ⟶ 1,958:
Print
Print "Press any key to quit"
Sleep</langsyntaxhighlight>
 
{{out}}
Line 1,694 ⟶ 1,980:
=={{header|Fōrmulæ}}==
 
In [http{{FormulaeEntry|page=https://wiki.formulae.org/?script=examples/Pathological_floating_point_problems this] page you can see the solution of this task.}}
 
'''Solution'''
Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text ([http://wiki.formulae.org/Editing_F%C5%8Drmul%C3%A6_expressions more info]). Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation &mdash;i.e. XML, JSON&mdash; they are intended for transportation effects more than visualization and edition.
 
'''Case 1. Introduction example'''
The option to show Fōrmulæ programs and their results is showing images. Unfortunately images cannot be uploaded in Rosetta Code.
 
[[File:Fōrmulæ - Pathological floating point problems 01.png]]
 
[[File:Fōrmulæ - Pathological floating point problems 02.png]]
 
'''Case 2. A sequence that seems to converge to a wrong limit'''
 
[[File:Fōrmulæ - Pathological floating point problems 03.png]]
 
[[File:Fōrmulæ - Pathological floating point problems 04.png]]
 
'''Case 3. The Chaotic Bank Society'''
 
[[File:Fōrmulæ - Pathological floating point problems 05.png]]
 
[[File:Fōrmulæ - Pathological floating point problems 06.png]]
 
'''Case 4. Siegfried Rump's example'''
 
[[File:Fōrmulæ - Pathological floating point problems 07.png]]
 
[[File:Fōrmulæ - Pathological floating point problems 08.png]]
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,794 ⟶ 2,102:
f64, _ := s.Add(s.Add(s, t3), t4).Float64()
return f64
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,816 ⟶ 2,124:
Task 1 includes an extra step, 200 iterations, to demonstrate a closer convergence.
 
<langsyntaxhighlight lang="unicon">#
# Pathological floating point problems
#
Line 1,903 ⟶ 2,211:
show := 10^4
write("Balance after ", y, " years: $", d * show / scale * 1.0 / show)
end</langsyntaxhighlight>
 
{{out}}
Line 1,949 ⟶ 2,257:
Implementation of <code>vn</code>:
 
<langsyntaxhighlight Jlang="j"> vn=: 111 +(_1130 % _1&{) + (3000 % _1&{ * _2&{)</langsyntaxhighlight>
 
Example using IEEE-754 floating point:
 
<langsyntaxhighlight Jlang="j"> 3 21j16 ":"1] 3 4 5 6 7 8 20 30 50 100 ([,.{) (,vn)^:100(2 _4)
3 9.3783783783783861
4 7.8011527377522611
Line 1,963 ⟶ 2,271:
30 100.0000000000000000
50 100.0000000000000000
100 100.0000000000000000</langsyntaxhighlight>
 
Example using exact arithmetic:
 
<langsyntaxhighlight Jlang="j"> 3 21j16 ":"1] 3 4 5 6 7 8 20 30 50 100 ([,.{) (,vn)^:100(2 _4x)
3 9.3783783783783784
4 7.8011527377521614
Line 1,977 ⟶ 2,285:
30 6.0056486887714203
50 6.0001465345613879
100 6.0000000160995649</langsyntaxhighlight>
 
'''The Chaotic Bank Society'''
Line 1,983 ⟶ 2,291:
Let's start this example by using exact arithmetic, to make sure we have the right algorithm. We'll go a bit overboard, in representing ''e'', so we don't have to worry too much about that.
 
<langsyntaxhighlight Jlang="j"> e=: +/%1,*/\1+i.100x
81j76":e
2.7182818284590452353602874713526624977572470936999595749669676277240766303535
21j16":+`*/,_1,.(1+i.-25),e
0.0399387296732302</langsyntaxhighlight>
 
(Aside: here, we are used the same mechanism for adding -1 to ''e'' that we are using to add -1 to the product of the year number and the running balance.)
Line 1,993 ⟶ 2,301:
Next, we will use <math>6157974361033 \div 2265392166685</math> for ''e'', to represent the limit of what can be expressed using 64 bit IEEE 754 floating point.
 
<langsyntaxhighlight Jlang="j"> 31j16":+`*/,_1,.(1+i.-25),6157974361033%2265392166685x
_2053975868590.1852178761057505</langsyntaxhighlight>
 
That's clearly way too low, so let's try instead using <math>(1+6157974361033) \div 2265392166685</math> for ''e''
<langsyntaxhighlight Jlang="j"> 31j16":+`*/,_1,.(1+i.-25),6157974361034%2265392166685x
4793054977300.3491517765983265</langsyntaxhighlight>
 
So, our problem seems to be that there's no way we can express enough bits of ''e'', using 64 bit IEEE-754 floating point arithmetic. Just to confirm:
 
<langsyntaxhighlight Jlang="j"> 1x1
2.71828
+`*/,_1,.(1+i.-25),1x1
_2.24237e9</langsyntaxhighlight>
 
Now let's take a closer look using our rational approximation for ''e'':
 
<langsyntaxhighlight Jlang="j"> 21j16":+`*/,_1,.(1+i.-25),+/%1,*/\1+i.40x
0.0399387296732302
21j16":+`*/,_1,.(1+i.-25),+/%1,*/\1+i.30x
Line 2,018 ⟶ 2,326:
0.0000000000000000
21j16":+`*/,_1,.(1+i.-25),+/%1,*/\1+i.24x
_1.0000000000000000</langsyntaxhighlight>
 
Things go haywire when our approximation for ''e'' uses the same number of terms as our bank's term. So, what does that look like, in terms of precision?
 
<langsyntaxhighlight Jlang="j"> 41j36":+/%1,*/\1+i.26x
2.718281828459045235360287471257428715
41j36":+/%1,*/\1+i.25x
2.718281828459045235360287468777832452
41j36":+/%1,*/\1+i.24x
2.718281828459045235360287404308329608</langsyntaxhighlight>
 
In other words, we go astray when our approximation for ''e'' is inaccurate in the 26th position after the decimal point. But IEEE-754 floating point arithmetic can only represent approximately 16 decimal digits of precision.
Line 2,035 ⟶ 2,343:
Again, we use exact arithmetic to see if we have the algorithm right. That said, we'll also do this in small steps, to make sure we're being exact every step of the way, and to keep from building overly long lines:
 
<langsyntaxhighlight Jlang="j">rump=:4 :0
NB. enforce exact arithmetic
add=. +&x:
Line 2,065 ⟶ 2,373:
 
term1 add term2 add term3 add term4
)</langsyntaxhighlight>
 
Example use:
 
<langsyntaxhighlight Jlang="j"> 21j16": 77617 rump 33096
_0.8273960599468214</langsyntaxhighlight>
 
Note that replacing the definitions of <code>add</code>, <code>sub</code>, <code>div</code>, <code>mul</code> with implementations which promote to floating point gives a very different result:
 
<langsyntaxhighlight Jlang="j"> 77617 rump 33096
_1.39061e21</langsyntaxhighlight>
 
But given that b8 is
 
<langsyntaxhighlight Jlang="j"> 33096^8
1.43947e36</langsyntaxhighlight>
 
we're exceeding the limits of our representation here, if we're using 64 bit IEEE-754 floating point arithmetic.
Line 2,087 ⟶ 2,395:
Uses BigRational class: [[Arithmetic/Rational/Java]]. For comparison purposes, each task is also implemented with standard 64-bit floating point numbers.
 
<langsyntaxhighlight lang="java">import java.math.BigDecimal;
import java.math.RoundingMode;
 
Line 2,183 ⟶ 2,491:
siegfriedRump();
}
}</langsyntaxhighlight>
{{out}}
<pre>Wrong Convergence Sequence
Line 2,236 ⟶ 2,544:
===v series===
The following implementation illustrates how a cache can be used in jq to avoid redundant computations. A JSON object is used as the cache.
<langsyntaxhighlight lang="jq"># Input: the value at which to compute v
def v:
# Input: cache
Line 2,252 ⟶ 2,560:
end
end;
. as $m | {} | v_($m) | .[($m|tostring)] ; </langsyntaxhighlight>
 
Example:<langsyntaxhighlight lang="jq">(3,4,5,6,7,8,20,30,50,100) | v</langsyntaxhighlight>
{{out}}
<pre>18.5
Line 2,271 ⟶ 2,579:
To avoid the pathological issues, the following uses symbolic arithmetic, with {"e": m, "c": n} representing (e*m + n).
 
<langsyntaxhighlight lang="jq"># Given the balance in the prior year, compute the new balance in year n.
# Input: { e: m, c: n } representing m*e + n
def new_balance(n):
Line 2,281 ⟶ 2,589:
def e: 1|exp;
reduce range(0;n) as $i ({}; new_balance($i) )
| (.e * e) + .c;</langsyntaxhighlight>
 
Example:<syntaxhighlight lang ="jq">balance(25)</langsyntaxhighlight>
{{out}}
0
Line 2,292 ⟶ 2,600:
The task could be completed even using ```Rational{BigFloat}``` type.
 
<langsyntaxhighlight lang="julia">using Printf
# arbitrary precision
setprecision(2000)
Line 2,330 ⟶ 2,638:
333.75b ^ 6 + a ^ 2 * ( 11a ^ 2 * b ^ 2 - b ^ 6 - 121b ^ 4 - 2 ) + 5.5b ^ 8 + a / 2b
 
println("\nTask 3 - Siegfried Rump's example:\nf(77617.0, 33096.0) = ", @sprintf "%.20f" f(big(77617.0), big(33096.0)))</langsyntaxhighlight>
 
{{out}}
Line 2,348 ⟶ 2,656:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.0.6
 
import java.math.*
Line 2,389 ⟶ 2,697:
f += c8 * a.pow(2, con480)
println("\nf(77617.0, 33096.0) is ${"%18.16f".format(f)}")
}</langsyntaxhighlight>
 
{{out}}
Line 2,497 ⟶ 2,805:
</pre>
 
=={{header|MathematicaM2000 Interpreter}}==
From n=26 we get wrong numbers (not shown here). For Task 2 only Decimal can show a good result, although has less accuracy.
 
<syntaxhighlight lang="m2000 interpreter">
module Pathological_floating_point_problems{
decimal vn[3]
vn[1]=2
vn[2]=-4
for i=3 to 100
vn[i]=111@-1130@/vn[i-1]+3000@/(vn[i-1]*vn[i-2])
next
n=list:=3,4,5,6,7,8,20,25
k=each(n)
while k
report "n = "+eval$(k)+chr$(9)+(vn[eval(k)])
end while
}
print "Task 1"
Pathological_floating_point_problems
print
print "Task 2"
module Chaotic_Bank_Society {
decimal Balance=2.7182818284590452353602874713@-1@
string frmt="year {0::-2} Balance:{1}"
for i=1 to 25
Balance=Balance*i-1@
rem print format$(frmt, i, Balance)
next i
Print "Starting balance: $e-1"
Print "Balance = (Balance * year) - 1 for 25 years"
print "Balance after 25 years: $"+Balance
}
Chaotic_Bank_Society
</syntaxhighlight>
{{out}}
<pre>
Task 1
n = 3 18.5
n = 4 9.378378378378378378378378378
n = 5 7.80115273775216138328530259
n = 6 7.154414480975249353527890606
n = 7 6.806784736923632983941755925
n = 8 6.592632768704438392741992887
n = 20 6.04355210719488789087813234
n = 25 6.01330401514055310928530167
 
Task 2
Starting balance: $e-1
Balance = (Balance * year) - 1 for 25 years
Balance after 25 years: $0.0391218706091111022592
</pre>
 
 
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
Task 1:
<langsyntaxhighlight Mathematicalang="mathematica">v[1] = 2;
v[2] = -4;
v[n_] := Once[111 - 1130/v[n - 1] + 3000/(v[n - 1]*v[n - 2])]
N[Map[v, {3, 4, 5, 6, 7, 8, 20, 30, 50, 100}], 80]</langsyntaxhighlight>
{{out}}
<pre>{18.500000000000000000000000000000000000000000000000000000000000000000000000000000,
Line 2,517 ⟶ 2,878:
 
Task 2:
<langsyntaxhighlight Mathematicalang="mathematica">year = 1; N[Nest[# year++ - 1 &, E - 1, 25], 30]</langsyntaxhighlight>
{{out}}<pre>0.0399387296732302089036714552104</pre>
 
Task 3:
<langsyntaxhighlight Mathematicalang="mathematica">f[a_, b_] := 333.75`100 b^6 + a^2 (11 a^2 b^2 - b^6 - 121 b^4 - 2) + 5.5`100 b^8 + a/(2 b)
f[77617, 33096]</langsyntaxhighlight>
{{out}}<pre>-0.827396059946821368141165095479816291999033115784384819917814842</pre>
 
=={{header|Nim}}==
{{libheader|bignum}}
{{libheader|nim-decimal}}
Nim floats exist in IEEE 754 32 bits (<code>float32</code>) and 64 bits (<code>float64</code>) formats. The type <code>float</code> is a synonym for <code>float64</code>.
With 64 bits, none of the three tasks can be completed successfully.
 
There exist third party modules for decimal and rationals. We used both or them.
 
For decimal, we get a correct result for the first task, provided we set the precision to 125 at least (we chose 130). In task 2, it is important to set a starting value with a very good precision. One way to do that consists to compute it using the “exp” operator which is provided by the library “decimal”. Another way consists to provide the value as a string with enough decimal digits. Task 3 didn’t cause any problem.
 
For rationals, we encountered an error in task 1, apparently due to some error in the library. Changing the order of the terms solved the issue. For task 2, initializing with a float is not precise enough and we had to provide the initial value as the quotient of two big integers, these ones initialized with a string with enough decimal digits. For task 3, the <code>^</code> operator was missing and, so, we had to defined it. We took the <code>^</code> operator for floats as model.
 
To avoid duplication of code, we used generics.
 
<syntaxhighlight lang="nim">import math, strutils, strformat
import decimal
import bignum
 
####################################################################################################
# Utilities.
 
proc format[T: DecimalType|Rat](val: T; intLen, fractLen: Positive): string =
## Format a decimal or a rational with "intLen" integer digits and "fractLen"
## fractional digits.
let s = when T is DecimalType: ($val).split('.')
else: ($val.toFloat).split('.')
 
result = s[0].align(intLen) & '.'
if s[1].len < fractLen:
result.add s[1].alignLeft(fractLen, '0')
else:
result.add s[1][0..<fractLen]
 
 
proc `^`(a: Rat; b: Natural): Rat =
## Missing exponentiation operator for rationals.
## Adaptation of operator for floats.
case b
of 0: result = newRat(1)
of 1: result = a
of 2: result = a * a
of 3: result = a * a * a
else:
var (a, b) = (a.clone, b)
result = newRat(1)
while true:
if (b and 1) != 0:
result *= a
b = b shr 1
if b == 0: break
a *= a
 
 
####################################################################################################
# Task 1.
 
proc v[T: float|DecimalType|Rat](n: Positive): seq[T] =
## Return the "n" first values for sequence "Vn".
var (v1, v2) = when T is float: (2.0, -4.0)
elif T is Rat: (newRat(2), newRat(-4))
else: (newDecimal(2), newDecimal(-4))
 
result.add default(T) # Dummy value to start at index one.
result.add v1
result.add v2
for _ in 3..n:
# Need to change evaluation order to avoid a bug with rationals.
result.add 3000 / (result[^1] * result[^2]) - 1130 / result[^1] + 111
 
 
setPrec(130) # Default precision is not sufficient.
 
let vfloat = v[float](100)
let vdecimal = v[DecimalType](100)
let vrational = v[Rat](100)
 
echo "Task 1"
echo " n v(n) float v(n) decimal v(n) rational"
for n in [3, 4, 5, 6, 7, 8, 20, 30, 50, 100]:
echo &"{n:>3} {vfloat[n]:>20.16f} {vdecimal[n].format(3, 16)} {vrational[n].format(3, 16)}"
 
 
####################################################################################################
# Task 2.
 
proc balance[T: float|DecimalType|Rat](): T =
## Return the balance after 25 years.
result = when T is float: E - 1
elif T is DecimalType: exp(newDecimal(1)) - 1
else: newInt("17182818284590452353602874713526624977572470") /
newInt("10000000000000000000000000000000000000000000")
 
var n = when T is float: 1.0 else: 1
while n <= 25:
result = result * n - 1
n += 1
 
echo "\nTask 2."
echo "Balance after 25 years (float): ", (&"{balance[float]():.16f}")[0..17]
echo "Balance after 25 years (decimal): ", balance[DecimalType]().format(1, 16)
echo "Balance after 25 years: (rational): ", balance[Rat]().format(1, 16)
 
 
####################################################################################################
# Task 3.
 
const
A = 77617
B = 33096
 
proc rump[T: float|DecimalType|Rat](a, b: T): T =
## Return the value of the Rump's function.
let C1 = when T is float: 333.75
elif T is Rat: newRat(333.75)
else: newDecimal("333.75")
let C2 = when T is float: 5.5
elif T is Rat: newRat(5.5)
else: newDecimal("5.5")
result = C1 * b^6 + a^2 * (11 * a^2 * b^2 - b^6 - 121 * b^4 - 2) + C2 * b^8 + a / (2 * b)
 
echo "\nTask 3"
 
let rumpFloat = rump(A.toFloat, B.toFloat)
let rumpDecimal = rump(newDecimal(A), newDecimal(B))
let rumpRational = rump(newRat(A), newRat(B))
 
echo &"f({A}, {B}) float = ", rumpFloat
echo &"f({A}, {B}) decimal = ", rumpDecimal.format(1, 16)
echo &"f({A}, {B}) rational = ", rumpRational.format(1, 16)</syntaxhighlight>
 
{{out}}
<pre>Task 1
n v(n) float v(n) decimal v(n) rational
3 18.5000000000000000 18.5000000000000000 18.5000000000000000
4 9.3783783783783861 9.3783783783783783 9.3783783783783770
5 7.8011527377522611 7.8011527377521613 7.8011527377521610
6 7.1544144809765555 7.1544144809752493 7.1544144809752490
7 6.8067847369419638 6.8067847369236329 6.8067847369236330
8 6.5926327689743687 6.5926327687044383 6.5926327687044380
20 99.8921123759515694 6.0435521101892688 6.0435521101892680
30 99.9999999999999289 6.0067860930312057 6.0067860930312050
50 100.0000000000000000 6.0001758466271871 6.0001758466271870
100 100.0000000000000000 6.0000000193275677 6.0000000193194780
 
Task 2.
Balance after 25 years (float): -2242373258.570158
Balance after 25 years (decimal): 0.0399387296732302
Balance after 25 years: (rational): 0.0399387296732302
 
Task 3
f(77617, 33096) float = -1.180591620717411e+21
f(77617, 33096) decimal = -0.8273960599468213
f(77617, 33096) rational = -0.8273960599468213</pre>
 
=={{header|PARI/GP}}==
 
Task 1: Define recursive function V(n):
<langsyntaxhighlight lang="parigp">V(n,a=2,v=-4.)=if(n < 3,return(v));V(n--,v,111-1130/v+3000/(v*a))</langsyntaxhighlight>
In order to work set precision to at least 200 digits:
<pre>\p 200: realprecision = 211 significant digits (200 digits displayed)
Line 2,537 ⟶ 3,052:
----
Task 2: Define function balance(deposit,years):
<langsyntaxhighlight lang="parigp">balance(d,y)=d--;for(n=1,y,d=d*n-1);d</langsyntaxhighlight>
 
Output ''balance(exp(1), 25)'':
Line 2,543 ⟶ 3,058:
----
Task 3: Define function f(a,b):
<langsyntaxhighlight lang="parigp">f(a,b)=333.75*b^6+a*a*(11*a*a*b*b-b^6-121*b^4-2)+5.5*b^8+a/(2*b)</langsyntaxhighlight>
 
Output:<pre>f(77617.0,33096.0): -0.827396059946821368141165...</pre>
Line 2,553 ⟶ 3,068:
The constants in the equation must be represented with a decimal point (even just <code>111.</code>) so that
they are treated as rationals, not integers.
<langsyntaxhighlight lang="perl">use bigrat;
 
@s = qw(2, -4);
Line 2,563 ⟶ 3,078:
($nu,$de) = $s[$n-1] =~ m#^(\d+)/(\d+)#;;
printf "n = %3d %18.15f\n", $n, $nu/$de;
}</langsyntaxhighlight>
{{out}}
<pre>n = 3 18.500000000000000
Line 2,580 ⟶ 3,095:
The value of 𝑒 is imported from a module, but could also be calculated, as is done in
[[Calculating_the_value_of_e#Perl|Calculating the value of e]]
<langsyntaxhighlight lang="perl">use bignum qw(bexp);
$e = bexp(1,43);
$years = 25;
Line 2,587 ⟶ 3,102:
print "Starting balance, \$(e-1): \$$balance\n";
for $i (1..$years) { $balance = $i * $balance - 1 }
printf "After year %d, you will have \$%1.15g in your account.\n", $years, $balance;</langsyntaxhighlight>
{{out}}
<pre>Starting balance, $(e-1): $1.718281828459045235360287471352662497757247
Line 2,593 ⟶ 3,108:
 
==== Rump's example ====
<langsyntaxhighlight lang="perl">use bignum;
 
$a = 77617;
$b = 33096;
printf "%0.16f\n", 333.75*$b**6 + $a**2 * ( 11*$a**2 * $b**2 - $b**6 - 121*$b**4 - 2) + 5.5*$b**8 + $a/(2*$b);</langsyntaxhighlight>
{{out}}
<pre>-0.8273960599468214</pre>
Line 2,606 ⟶ 3,121:
Task2: needs at least 41 decimal places (and 42 passed as the first argument to ba_euler)<br>
Task3: apparently only needs just 15 decimal places, then again ba_scale() defines the minimum, and it may (as in is permitted to) use more.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>include builtins\bigatom.e
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">\</span><span style="color: #000000;">bigatom</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
puts(1,"Task 1\n")
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Task 1\n"</span><span style="color: #0000FF;">)</span>
constant {fns,fmts} = columnize({{3,1},{4,6},{5,6},{6,6},{7,6},{8,7},{20,16},{30,24},{50,40},{100,78}})
<span style="color: #008080;">constant</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">fns</span><span style="color: #0000FF;">,</span><span style="color: #000000;">fmts</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">columnize</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">6</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">8</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">20</span><span style="color: #0000FF;">,</span><span style="color: #000000;">16</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">30</span><span style="color: #0000FF;">,</span><span style="color: #000000;">24</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">50</span><span style="color: #0000FF;">,</span><span style="color: #000000;">40</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">100</span><span style="color: #0000FF;">,</span><span style="color: #000000;">78</span><span style="color: #0000FF;">}})</span>
{} = ba_scale(196)
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ba_scale</span><span style="color: #0000FF;">(</span><span style="color: #000000;">196</span><span style="color: #0000FF;">)</span>
sequence v = {2,-4}
<span style="color: #004080;">sequence</span> <span style="color: #000000;">v</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">4</span><span style="color: #0000FF;">}</span>
for n=3 to 100 do
<span style="color: #008080;">for</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">3</span> <span style="color: #008080;">to</span> <span style="color: #000000;">100</span> <span style="color: #008080;">do</span>
-- v = append(v,111 - 1130/v[n-1] + 3000/(v[n-1]*v[n-2]))
<span style="color: #000080;font-style:italic;">-- v = append(v,ba_add(ba_sub(111,ba_divide( - 1130,/v[n-1])),ba_divide( + 3000,ba_multiply/(v[n-1],*v[n-2]))))</span>
<span style="color: #000000;">v</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">v</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ba_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ba_sub</span><span style="color: #0000FF;">(</span><span style="color: #000000;">111</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ba_divide</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1130</span><span style="color: #0000FF;">,</span><span style="color: #000000;">v</span><span style="color: #0000FF;">[</span><span style="color: #000000;">n</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])),</span><span style="color: #000000;">ba_divide</span><span style="color: #0000FF;">(</span><span style="color: #000000;">3000</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ba_multiply</span><span style="color: #0000FF;">(</span><span style="color: #000000;">v</span><span style="color: #0000FF;">[</span><span style="color: #000000;">n</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span><span style="color: #000000;">v</span><span style="color: #0000FF;">[</span><span style="color: #000000;">n</span><span style="color: #0000FF;">-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]))))</span>
if n<9 or find(n,{20,30,50,100}) then
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;"><</span><span style="color: #000000;">9</span> <span style="color: #008080;">or</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">20</span><span style="color: #0000FF;">,</span><span style="color: #000000;">30</span><span style="color: #0000FF;">,</span><span style="color: #000000;">50</span><span style="color: #0000FF;">,</span><span style="color: #000000;">100</span><span style="color: #0000FF;">})</span> <span style="color: #008080;">then</span>
-- printf(1,"n = %-3d %20.16f\n", {n, v[n]})
<span style="color: #000080;font-style:italic;">-- printf(1,"n = %-3d %20.16f\n", {n, v[n]})</span>
string fmt = sprintf("%%.%dB",fmts[find(n,fns)])
<span style="color: #004080;">string</span> <span style="color: #000000;">fmt</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%%.%dB"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">fmts</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">fns</span><span style="color: #0000FF;">)])</span>
printf(1,"n = %-3d %s\n", {n, ba_sprintf(fmt,v[n])})
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"n = %-3d %s\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ba_sprintf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fmt</span><span style="color: #0000FF;">,</span><span style="color: #000000;">v</span><span style="color: #0000FF;">[</span><span style="color: #000000;">n</span><span style="color: #0000FF;">])})</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
 
puts(1,"\nTask 2\n")
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\nTask 2\n"</span><span style="color: #0000FF;">)</span>
--atom balance = exp(1)-1
<span style="color: #000080;font-style:italic;">--atom balance = exp(1)-1
--for i=1 to 25 do balance = balance*i-1 end for
--printf(for i=1,"\nTask 2\nBalance afterto 25 years:do $%12.10f",balance = balance)*i-1 end for
--printf(1,"\nTask 2\nBalance after 25 years: $%12.10f", balance)</span>
{} = ba_scale(41)
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ba_scale</span><span style="color: #0000FF;">(</span><span style="color: #000000;">41</span><span style="color: #0000FF;">)</span>
bigatom balance = ba_sub(ba_euler(42,true),1)
<span style="color: #000000;">bigatom</span> <span style="color: #000000;">balance</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ba_sub</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ba_euler</span><span style="color: #0000FF;">(</span><span style="color: #000000;">42</span><span style="color: #0000FF;">,</span><span style="color: #004600;">true</span><span style="color: #0000FF;">),</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
for i=1 to 25 do balance = ba_sub(ba_multiply(balance,i),1) end for
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">25</span> <span style="color: #008080;">do</span> <span style="color: #000000;">balance</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ba_sub</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ba_multiply</span><span style="color: #0000FF;">(</span><span style="color: #000000;">balance</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">),</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
ba_printf(1,"Balance after 25 years: $%.16B\n\n", balance)
<span style="color: #000000;">ba_printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Balance after 25 years: $%.16B\n\n"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">balance</span><span style="color: #0000FF;">)</span>
 
puts(1,"Task 3\n")
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Task 3\n"</span><span style="color: #0000FF;">)</span>
{} = ba_scale(15) -- fine!
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ba_scale</span><span style="color: #0000FF;">(</span><span style="color: #000000;">15</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- fine!</span>
integer a = 77617,
<span style="color: #004080;">integer</span> <span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">77617</span><span style="color: #0000FF;">,</span>
b = 33096
<span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">33096</span>
--atom pa2 = power(a,2),
<span style="color: #000080;font-style:italic;">--atom pa2 = power(a,2),
-- pb2a211 = 11*pa2*power(b,2),
-- pb4121pb2a211 = 12111*pa2*power(b,42),
-- pb6pb4121 = 121*power(b,64),
-- pb855pb6 = 5.5*power(b,86),
-- pb855 = 5.5*power(b,8),
-- f_ab = 333.75 * pb6 + pa2 * (pb2a211 - pb6 - pb4121 - 2) + pb855 + a/(2*b)
-- f_ab = 333.75 * pb6 + pa2 * (pb2a211 - pb6 - pb4121 - 2) + pb855 + a/(2*b)
--printf(1,"f(%d, %d) = %.15f\n\n", {a, b, f_ab})
--printf(1,"f(%d, %d) = %.15f\n\n", {a, b, f_ab})</span>
bigatom pa2 = ba_power(a,2),
<span style="color: #000000;">bigatom</span> <span style="color: #000000;">pa2</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ba_power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">),</span>
pb2a211 = ba_multiply(11,ba_multiply(pa2,ba_power(b,2))),
<span style="color: #000000;">pb2a211</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ba_multiply</span><span style="color: #0000FF;">(</span><span style="color: #000000;">11</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ba_multiply</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pa2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ba_power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">))),</span>
pb4121 = ba_multiply(121,ba_power(b,4)),
<span style="color: #000000;">pb4121</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ba_multiply</span><span style="color: #0000FF;">(</span><span style="color: #000000;">121</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ba_power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">)),</span>
pb6 = ba_power(b,6),
<span style="color: #000000;">pb6</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ba_power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">),</span>
pa2mid = ba_multiply(pa2,ba_sub(ba_sub(ba_sub(pb2a211,pb6),pb4121),2)),
<span style="color: #000000;">pa2mid</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ba_multiply</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pa2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ba_sub</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ba_sub</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ba_sub</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pb2a211</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pb6</span><span style="color: #0000FF;">),</span><span style="color: #000000;">pb4121</span><span style="color: #0000FF;">),</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)),</span>
pb633375 = ba_multiply(333.75,pb6),
<span style="color: #000000;">pb633375</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ba_multiply</span><span style="color: #0000FF;">(</span><span style="color: #000000;">333.75</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pb6</span><span style="color: #0000FF;">),</span>
pb855 = ba_multiply(5.5,ba_power(b,8)),
<span style="color: #000000;">pb855</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ba_multiply</span><span style="color: #0000FF;">(</span><span style="color: #000000;">5.5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ba_power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">8</span><span style="color: #0000FF;">)),</span>
f_ab = ba_add(ba_add(ba_add(pb633375,pa2mid),pb855),ba_divide(a,ba_multiply(2,b)))
<span style="color: #000000;">f_ab</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ba_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ba_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ba_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pb633375</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pa2mid</span><span style="color: #0000FF;">),</span><span style="color: #000000;">pb855</span><span style="color: #0000FF;">),</span><span style="color: #000000;">ba_divide</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ba_multiply</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)))</span>
printf(1,"f(%d, %d) = %s\n", {a, b, ba_sprintf("%.15B",f_ab)})</lang>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"f(%d, %d) = %s\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ba_sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%.15B"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f_ab</span><span style="color: #0000FF;">)})</span>
<!--</syntaxhighlight>-->
Aside: obviously you don't ''have'' to use lots of temps like that, but I find that style often makes things much easier to debug.
{{out}}
Line 2,680 ⟶ 3,197:
Task2: needs at least 41 decimal places (and e-1 accurately specified to at least 42 decimal places).<br>
Task3: needs at least 36 decimal places (my suspicions above re bigatom in 15 now seem correct).
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>include builtins\mpfr.e
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
puts(1,"Task 1\n")
<span style="color: #7060A8;">requires</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1.0.0"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (mpfr_set_default_prec[ision] has been renamed)</span>
constant {fns,fmts} = columnize({{3,1},{4,6},{5,6},{6,6},{7,6},{8,7},{20,16},{30,24},{50,40},{100,78}})
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">\</span><span style="color: #004080;">mpfr</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
mpfr_set_default_prec(-196)
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Task 1\n"</span><span style="color: #0000FF;">)</span>
sequence v = {mpfr_init(2),mpfr_init(-4)}
<span style="color: #008080;">constant</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">fns</span><span style="color: #0000FF;">,</span><span style="color: #000000;">fdp</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">columnize</span><span style="color: #0000FF;">({{</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">6</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">8</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">20</span><span style="color: #0000FF;">,</span><span style="color: #000000;">16</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">30</span><span style="color: #0000FF;">,</span><span style="color: #000000;">24</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">50</span><span style="color: #0000FF;">,</span><span style="color: #000000;">40</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">100</span><span style="color: #0000FF;">,</span><span style="color: #000000;">78</span><span style="color: #0000FF;">}})</span>
mpfr t1 = mpfr_init()
<span style="color: #7060A8;">mpfr_set_default_precision</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">196</span><span style="color: #0000FF;">)</span>
for n=3 to 100 do
<span style="color: #004080;">sequence</span> <span style="color: #000000;">v</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #7060A8;">mpfr_init</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">mpfr_init</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">4</span><span style="color: #0000FF;">)}</span>
-- v = append(v,111 - 1130/v[n-1] + 3000/(v[n-1]*v[n-2]))
<span style="color: #004080;">mpfr</span> <span style="color: #000000;">t1</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpfr_init</span><span style="color: #0000FF;">()</span>
mpfr_set_si(t1,1130)
<span style="color: #008080;">for</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">3</span> <span style="color: #008080;">to</span> <span style="color: #000000;">100</span> <span style="color: #008080;">do</span>
mpfr_div(t1,t1,v[n-1])
<span style="color: #000080;font-style:italic;">-- v = append(v,111 - 1130/v[n-1] + 3000/(v[n-1]*v[n-2]))</span>
mpfr_si_sub(t1,111,t1)
<span style="color: #7060A8;">mpfr_set_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1130</span><span style="color: #0000FF;">)</span>
mpfr t2 = mpfr_init()
<span style="color: #7060A8;">mpfr_div</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">v</span><span style="color: #0000FF;">[</span><span style="color: #000000;">n</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span>
mpfr_mul(t2,v[n-1],v[n-2])
<span style="color: #7060A8;">mpfr_si_sub</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">111</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t1</span><span style="color: #0000FF;">)</span>
mpfr_si_div(t2,3000,t2)
<span style="color: #004080;">mpfr</span> <span style="color: #000000;">t2</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpfr_init</span><span style="color: #0000FF;">()</span>
mpfr_add(t2,t1,t2)
<span style="color: #7060A8;">mpfr_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">v</span><span style="color: #0000FF;">[</span><span style="color: #000000;">n</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span><span style="color: #000000;">v</span><span style="color: #0000FF;">[</span><span style="color: #000000;">n</span><span style="color: #0000FF;">-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">])</span>
v = append(v,t2)
<span style="color: #7060A8;">mpfr_si_div</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3000</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t2</span><span style="color: #0000FF;">)</span>
if n<9 or find(n,{20,30,50,100}) then
<span style="color: #7060A8;">mpfr_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t2</span><span style="color: #0000FF;">)</span>
-- printf(1,"n = %-3d %20.16f\n", {n, v[n]})
<span style="color: #000000;">v</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">v</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t2</span><span style="color: #0000FF;">)</span>
string fmt = sprintf("%%.%dRf",fmts[find(n,fns)])
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;"><</span><span style="color: #000000;">9</span> <span style="color: #008080;">or</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">20</span><span style="color: #0000FF;">,</span><span style="color: #000000;">30</span><span style="color: #0000FF;">,</span><span style="color: #000000;">50</span><span style="color: #0000FF;">,</span><span style="color: #000000;">100</span><span style="color: #0000FF;">})</span> <span style="color: #008080;">then</span>
printf(1,"n = %-3d %s\n", {n, mpfr_sprintf(fmt,v[n])})
<span style="color: #000080;font-style:italic;">-- printf(1,"n = %-3d %20.16f\n", {n, v[n]})</span>
end if
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"n = %-3d %s\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">mpfr_get_fixed</span><span style="color: #0000FF;">(</span><span style="color: #000000;">v</span><span style="color: #0000FF;">[</span><span style="color: #000000;">n</span><span style="color: #0000FF;">],</span><span style="color: #000000;">fdp</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">fns</span><span style="color: #0000FF;">)])})</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
 
puts(1,"\nTask 2\n")
--atom balance = exp(1)-1
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\nTask 2\n"</span><span style="color: #0000FF;">)</span>
--for i=1 to 25 do balance = balance*i-1 end for
<span style="color: #000080;font-style:italic;">--atom balance = exp(1)-1
--printf(1,"\nTask 2\nBalance after 25 years: $%12.10f", balance)
--for i=1 to 25 do balance = balance*i-1 end for
mpfr_set_default_prec(-41)
--printf(1,"\nTask 2\nBalance after 25 years: $%12.10f", balance)</span>
mpfr balance = mpfr_init("1.71828182845904523536028747135266249775724709369995"&
<span style="color: #7060A8;">mpfr_set_default_precision</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">41</span><span style="color: #0000FF;">)</span>
"95749669676277240766303535475945713821785251664274")
<span style="color: #004080;">mpfr</span> <span style="color: #000000;">balance</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpfr_init</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1.71828182845904523536028747135266249775724709369995"</span><span style="color: #0000FF;">&</span>
for i=1 to 25 do
<span style="color: #008000;">"95749669676277240766303535475945713821785251664274"</span><span style="color: #0000FF;">)</span>
mpfr_mul_si(balance,balance,i)
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">25</span> <span style="color: #008080;">do</span>
mpfr_sub_si(balance,balance,1)
<span style="color: #7060A8;">mpfr_mul_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">balance</span><span style="color: #0000FF;">,</span><span style="color: #000000;">balance</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
end for
<span style="color: #7060A8;">mpfr_sub_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">balance</span><span style="color: #0000FF;">,</span><span style="color: #000000;">balance</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
mpfr_printf(1,"Balance after 25 years: $%.16Rf\n\n", balance)
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
 
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Balance after 25 years: $%s\n\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #7060A8;">mpfr_get_fixed</span><span style="color: #0000FF;">(</span><span style="color: #000000;">balance</span><span style="color: #0000FF;">,</span><span style="color: #000000;">16</span><span style="color: #0000FF;">)})</span>
 
puts(1,"Task 3\n")
mpfr_set_default_prec(-36)
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Task 3\n"</span><span style="color: #0000FF;">)</span>
integer a = 77617,
<span style="color: #7060A8;">mpfr_set_default_precision</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">36</span><span style="color: #0000FF;">)</span>
b = 33096
<span style="color: #004080;">integer</span> <span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">77617</span><span style="color: #0000FF;">,</span>
--atom pa2 = power(a,2),
<span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">33096</span>
-- pb2a211 = 11*pa2*power(b,2),
<span style="color: #000080;font-style:italic;">--atom pa2 = power(a,2),
-- pb4121 = 121*power(b,4),
-- pb6pb2a211 = 11*pa2*power(b,62),
-- pb855pb4121 = 5.5121*power(b,84),
-- pb6 = power(b,6),
-- f_ab = 333.75 * pb6 + pa2 * (pb2a211 - pb6 - pb4121 - 2) + pb855 + a/(2*b)
-- pb855 = 5.5*power(b,8),
--printf(1,"f(%d, %d) = %.15f\n\n", {a, b, f_ab})
-- f_ab = 333.75 * pb6 + pa2 * (pb2a211 - pb6 - pb4121 - 2) + pb855 + a/(2*b)
-- (translation of FreeBASIC)
--printf(1,"f(%d, %d) = %.15f\n\n", {a, b, f_ab})
mpfr {t2,t3,t4,t5,t6,t7} = mpfr_inits(6)
-- (translation of FreeBASIC)</span>
mpfr_set_d(t1, a) -- a
<span style="color: #004080;">mpfr</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">t2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t6</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t7</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpfr_inits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">6</span><span style="color: #0000FF;">)</span>
mpfr_set_d(t2, b) -- b
<span style="color: #7060A8;">mpfr_set_d</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- a</span>
mpfr_set_d(t3, 333.75) -- 333.75
<span style="color: #7060A8;">mpfr_set_d</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- b </span>
mpfr_pow_si(t4, t2, 6) -- b ^ 6
<span style="color: #7060A8;">mpfr_set_d</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">333.75</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- 333.75</span>
mpfr_mul(t3, t3, t4) -- 333.75 * b^6
<span style="color: #7060A8;">mpfr_pow_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- b ^ 6</span>
mpfr_pow_si(t5, t1, 2) -- a^2
<span style="color: #7060A8;">mpfr_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t4</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- 333.75 * b^6</span>
mpfr_pow_si(t6, t2, 2) -- b^2
<span style="color: #7060A8;">mpfr_pow_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- a^2</span>
mpfr_mul_si(t7, t5, 11) -- 11 * a^2
<span style="color: #7060A8;">mpfr_pow_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- b^2</span>
mpfr_mul(t7, t7, t6) -- 11 * a^2 * b^2
<span style="color: #7060A8;">mpfr_mul_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">11</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- 11 * a^2</span>
mpfr_sub(t7, t7, t4) -- 11 * a^2 * b^2 - b^6
<span style="color: #7060A8;">mpfr_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t6</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- 11 * a^2 * b^2</span>
mpfr_pow_si(t4, t2, 4) -- b^4
<span style="color: #7060A8;">mpfr_sub</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t4</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- 11 * a^2 * b^2 - b^6</span>
mpfr_mul_si(t4, t4, 121) -- 121 * b^4
<span style="color: #7060A8;">mpfr_pow_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- b^4</span>
mpfr_sub(t7, t7, t4) -- 11 * a^2 * b^2 - b^6 - 121 * b^4
<span style="color: #7060A8;">mpfr_mul_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">121</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- 121 * b^4</span>
mpfr_sub_si(t7, t7, 2) -- 11 * a^2 * b^2 - b^6 - 121 * b^4 - 2
<span style="color: #7060A8;">mpfr_sub</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t4</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- 11 * a^2 * b^2 - b^6 - 121 * b^4</span>
mpfr_mul(t7, t7, t5) -- (11 * a^2 * b^2 - b^6 - 121 * b^4 - 2) * a^2
<span style="color: #7060A8;">mpfr_sub_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- 11 * a^2 * b^2 - b^6 - 121 * b^4 - 2</span>
mpfr_add(t3, t3, t7) -- 333.75 * b^6 + (11 * a^2 * b^2 - b^6 - 121 * b^4 - 2) * a^2
<span style="color: #7060A8;">mpfr_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t5</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (11 * a^2 * b^2 - b^6 - 121 * b^4 - 2) * a^2</span>
mpfr_set_d(t4, 5.5) -- 5.5
<span style="color: #7060A8;">mpfr_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t7</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- 333.75 * b^6 + (11 * a^2 * b^2 - b^6 - 121 * b^4 - 2) * a^2</span>
mpfr_pow_si(t5, t2, 8) -- b^8
<span style="color: #7060A8;">mpfr_set_d</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5.5</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- 5.5</span>
mpfr_mul(t4, t4, t5) -- 5.5 * b^8
<span style="color: #7060A8;">mpfr_pow_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- b^8 </span>
mpfr_add(t3, t3, t4) -- 333.75 * b^6 + (11 * a^2 * b^2 - b^6 - 121 * b^4 - 2) * a^2 + 5.5 * b^8
<span style="color: #7060A8;">mpfr_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t5</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- 5.5 * b^8</span>
mpfr_mul_si(t4, t2, 2) -- 2 * b
<span style="color: #7060A8;">mpfr_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t4</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- 333.75 * b^6 + (11 * a^2 * b^2 - b^6 - 121 * b^4 - 2) * a^2 + 5.5 * b^8</span>
mpfr_div(t5, t1, t4) -- a / (2 * b)
<span style="color: #7060A8;">mpfr_mul_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- 2 * b</span>
mpfr_add(t3, t3, t5) -- 333.75 * b^6 + (11 * a^2 * b^2 - b^6 - 121 * b^4 - 2) * a^2 + 5.5 * b^8 + a / (2 * b)
<span style="color: #7060A8;">mpfr_div</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t4</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- a / (2 * b)</span>
printf(1,"f(%d, %d) = %s\n", {a, b, mpfr_sprintf("%.15Rf",t3)})
<span style="color: #7060A8;">mpfr_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t5</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- 333.75 * b^6 + (11 * a^2 * b^2 - b^6 - 121 * b^4 - 2) * a^2 + 5.5 * b^8 + a / (2 * b)</span>
{t1,t2,t3,t4,t5,t6,t7} = mpfr_free({t1,t2,t3,t4,t5,t6,t7})</lang>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"f(%d, %d) = %s\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">mpfr_get_fixed</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">15</span><span style="color: #0000FF;">)})</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">t1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t6</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t7</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpfr_free</span><span style="color: #0000FF;">({</span><span style="color: #000000;">t1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t6</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t7</span><span style="color: #0000FF;">})</span>
<!--</syntaxhighlight>-->
Identical output
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(scl 150)
(de task1 (N)
(cache '(NIL) N
Line 2,809 ⟶ 3,329:
(*/ 5.5 B8 1.0)
(*/ 1.0 A (*/ 2.0 B 1.0)) ) ) )
(prinl "Rump's example: " (round (task3 77617.0 33096.0) 20))</langsyntaxhighlight>
{{out}}
<pre>
Line 2,832 ⟶ 3,352:
Using rational numbers via standard library <code>fractions</code>
 
<langsyntaxhighlight Pythonlang="python">from fractions import Fraction
 
def muller_seq(n:int) -> float:
Line 2,843 ⟶ 3,363:
 
for n in [3, 4, 5, 6, 7, 8, 20, 30, 50, 100]:
print("{:4d} -> {}".format(n, muller_seq(n)))</langsyntaxhighlight>
 
{{Out}}
Line 2,862 ⟶ 3,382:
Using <code>decimal</code> numbers with a high precision
 
<langsyntaxhighlight Pythonlang="python">from decimal import Decimal, getcontext
 
def bank(years:int) -> float:
Line 2,877 ⟶ 3,397:
return(float(decimal_balance))
 
print("Bank balance after 25 years = ", bank(25))</langsyntaxhighlight>
 
{{Out}}
Line 2,884 ⟶ 3,404:
 
'''but, still incorrectly diverging after some time, aprox. 250 years'''
<langsyntaxhighlight Pythonlang="python">for year in range(200, 256, 5):
print(year, '->', bank(year))
</syntaxhighlight>
</lang>
 
{{Out}}
Line 2,907 ⟶ 3,427:
Using rational numbers via standard library <code>fractions</code>
 
<langsyntaxhighlight Pythonlang="python">from fractions import Fraction
 
def rump(generic_a, generic_b) -> float:
Line 2,918 ⟶ 3,438:
 
print("rump(77617, 33096) = ", rump(77617.0, 33096.0))
</syntaxhighlight>
</lang>
 
{{Out}}
Line 2,931 ⟶ 3,451:
The examples below use real numbers, and the <code>x</code> function is used to transform them to floats, if desired, with the function <code>exact->inexact</code>.
 
<langsyntaxhighlight lang="racket">#lang racket
 
(define current-do-exact-calculations? (make-parameter exact->inexact))
Line 2,978 ⟶ 3,498:
(displayln "EXACT (Rational) NUMBERS")
(parameterize ([current-do-exact-calculations? #t])
(all-tests)))</langsyntaxhighlight>
 
{{out}}
Line 3,018 ⟶ 3,538:
{{works with|Rakudo|2016-01}}
The simple solution to doing calculations where floating point numbers exhibit pathological behavior is: don't do floating point calculations. :-) Raku is just as susceptible to floating point error as any other C based language, however, it offers built-in rational Types; where numbers are represented as a ratio of two integers. For normal precision it uses Rats - accurate to 1/2^64, and for arbitrary precision, FatRats, whose denominators can grow as large as available memory. Rats don't require any special setup to use. Any decimal number within its limits of precision is automatically stored as a Rat. FatRats require explicit coercion and are "sticky". Any FatRat operand in a calculation will cause all further results to be stored as FatRats.
<syntaxhighlight lang="raku" perl6line>say '1st: Convergent series';
my @series = 2.FatRat, -4, { 111 - 1130 / $^v + 3000 / ( $^v * $^u ) } ... *;
for flat 3..8, 20, 30, 50, 100 -> $n {say "n = {$n.fmt("%3d")} @series[$n-1]"};
Line 3,032 ⟶ 3,552:
print "\n3rd: Rump's example: f(77617.0, 33096.0) = ";
sub f (\a, \b) { 333.75*b⁶ + a²*( 11*a²*b² - b⁶ - 121*b⁴ - 2 ) + 5.5*b⁸ + a/(2*b) }
say f(77617.0, 33096.0).fmt("%0.16g");</langsyntaxhighlight>
{{Out}}
<pre>1st: Convergent series
Line 3,061 ⟶ 3,581:
<br>calculations, &nbsp; as well how many fractional decimal digits &nbsp; (past the decimal point) &nbsp; should be displayed.
===A sequence that seems to converge to a wrong limit===
<langsyntaxhighlight lang="rexx">/*REXX pgm (pathological FP problem): a sequence that might converge to a wrong limit. */
parse arg digs show . /*obtain optional arguments from the CL*/
if digs=='' | digs=="," then digs= 150 /*Not specified? Then use the default.*/
Line 3,075 ⟶ 3,595:
/*display digs past the dec. point───┐ */
if wordpos(n, #)\==0 then say 'v.'left(n, w) "=" format(v.n, , show)
end /*n*/ /*stick a fork in it, we're all done. */</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
<pre>
Line 3,099 ⟶ 3,619:
With 150 decimal digits, the balance becomes negative after &nbsp; '''96''' &nbsp; years.
<langsyntaxhighlight lang="rexx">/*REXX pgm (pathological FP problem): the chaotic bank society offering a new investment*/
e=2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713,
||8217852516642742746639193200305992181741359662904357290033429526059563073813232862794,
||3490763233829880753195251019011573834187930702154089149934884167509244761460668082264,
||8001684774118537423454424371075390777449920695517027618386062613313845830007520449338
d = length(e) - 1 length(.) /*subtract unityone for the decimal point. */
parse arg digs show y . /*obtain optional arguments from the CL*/
if digs=='' | digs=="," then digs= d /*Not specified? Then use the default.*/
Line 3,116 ⟶ 3,636:
end /*n*/
@@@= 'With ' d " decimal digits, the balance after " y ' years is: '
say @@@ '$'format($, , show) / 1 /*stick a fork in it, we're all done. */</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
<pre>
Line 3,123 ⟶ 3,643:
 
===Siegfried Rump's example===
<langsyntaxhighlight lang="rexx">/*REXX pgm (pathological FP problem): the Siegfried Rump's example (problem dated 1988).*/
parse arg digs show . /*obtain optional arguments from the CL*/
if digs=='' | digs=="," then digs=150 /*Not specified? Then use the default.*/
Line 3,135 ⟶ 3,655:
/*──────────────────────────────────────────────────────────────────────────────────────*/
f: procedure; parse arg a,b; return 333.75* b**6 + a**2 * (11* a**2* b**2 - b**6,
- 121*b**4 - 2) + 5.5*b**8 + a / (2*b)</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
<pre>
Line 3,142 ⟶ 3,662:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
# Project : Pathological floating point problems
 
Line 3,155 ⟶ 3,675:
ok
next
</syntaxhighlight>
</lang>
Output:
<pre>
Line 3,173 ⟶ 3,693:
===Task 1: Muller's sequence===
Ruby numbers have a "quo" division method, which returns a rational (a fraction) when possible, avoiding Float inaccuracy.
<langsyntaxhighlight Rubylang="ruby">ar = [0, 2, -4]
100.times{ar << (111 - 1130.quo(ar[-1])+ 3000.quo(ar[-1]*ar[-2])) }
Line 3,179 ⟶ 3,699:
puts "%3d -> %0.16f" % [n, ar[n]]
end
</syntaxhighlight>
</lang>
{{Out}}
<pre> 3 -> 18.5000000000000000
Line 3,194 ⟶ 3,714:
===Task 2: The Chaotic Bank Society===
Using BigDecimal provides a way to specify the number of digits for E. 50 seems to be sufficient.
<langsyntaxhighlight Rubylang="ruby">require 'bigdecimal/math'
balance = BigMath.E(50) - 1
1.upto(25){|y| balance = balance * y - 1}
puts "Bank balance after 25 years = #{balance.to_f}"</langsyntaxhighlight>
{{Out}}
<pre>Bank balance after 25 years = 0.03993872967323021
Line 3,204 ⟶ 3,724:
===Task 3: Rump's example===
Rationals again.
<langsyntaxhighlight Rubylang="ruby">def rump(a,b)
a, b = a.to_r, b.to_r
333.75r * b**6 + a**2 * ( 11 * a**2 * b**2 - b**6 - 121 * b**4 - 2 ) + 5.5r * b**8 + a / (2 * b)
end
 
puts "rump(77617, 33096) = #{rump(77617, 33096).to_f}"</langsyntaxhighlight>
{{out}}<pre>rump(77617, 33096) = -0.8273960599468214
</pre>
Line 3,215 ⟶ 3,735:
=={{header|Sidef}}==
'''Muller's sequence'''
<langsyntaxhighlight lang="ruby">func series (n) {
var (u, v) = (2, -4)
(n-2).times { (u, v) = (v, 111 - 1130/v + 3000/(v * u)) }
Line 3,223 ⟶ 3,743:
[(3..8)..., 20, 30, 50, 100].each {|n|
printf("n = %3d -> %s\n", n, series(n))
}</langsyntaxhighlight>
{{out}}
<pre>
Line 3,239 ⟶ 3,759:
 
'''The Chaotic Bank Society'''
<langsyntaxhighlight lang="ruby">var years = 25
var balance = (1 .. years+15 -> sum_by {|n| 1 / n! })
say "Starting balance, $(e-1): $#{balance}"
for i in (1..years) { balance = (i*balance - 1) }
printf("After year %d, you will have $%1.16g in your account.\n", years, balance)</langsyntaxhighlight>
{{out}}
<pre>
Line 3,251 ⟶ 3,771:
 
'''Siegfried Rump's example'''
<langsyntaxhighlight lang="ruby">func f (a, b) {
(333.75 * b**6) + (a**2 * ((11 * a**2 * b**2) -
b**6 - (121 * b**4) - 2)) + (5.5 * b**8) + a/(2*b)
}
 
say f(77617.0, 33096.0)</langsyntaxhighlight>
{{out}}
<pre>
Line 3,264 ⟶ 3,784:
=={{header|Stata}}==
'''Task 1'''
<langsyntaxhighlight lang="stata">clear
set obs 100
gen n=_n
Line 3,272 ⟶ 3,792:
replace v=111-1130/v[_n-1]+3000/(v[_n-1]*v[_n-2]) in 3/l
format %20.16f v
list if inlist(n,3,4,5,6,7,8,20,30,50,100), noobs</langsyntaxhighlight>
 
'''Output'''
Line 3,295 ⟶ 3,815:
'''Task 2'''
 
<langsyntaxhighlight lang="stata">clear
set obs 26
gen year=_n-1
gen balance=exp(1)-1 in 1
replace balance=year*balance[_n-1]-1 in 2/l
list balance if year==25, noobs</langsyntaxhighlight>
 
'''Output'''
Line 3,314 ⟶ 3,834:
If we replace exp(1)-1 by its value computed in higher precision by other means, the result is different, owing to the extreme sensibility of the computation.
 
<langsyntaxhighlight lang="stata">clear
set obs 26
gen year=_n-1
gen balance=1.71828182845904523 in 1
replace balance=year*balance[_n-1]-1 in 2/l
list balance if year==25, noobs</langsyntaxhighlight>
 
'''Output'''
Line 3,333 ⟶ 3,853:
We can check the hexadecimal representation of both numbers. Note they differ only in the last bit:
 
<langsyntaxhighlight lang="stata">di %21x exp(1)-1
di %21x 1.71828182845904523</langsyntaxhighlight>
 
'''Output'''
Line 3,342 ⟶ 3,862:
+1.b7e151628aed3X+000
</pre>
 
 
=={{header|Swift}}==
 
Using mkrd's Swift-BigInt library.
 
<syntaxhighlight lang="swift">extension Numeric where Self: Strideable {
@inlinable
public func power(_ n: Self) -> Self {
return stride(from: 0, to: n, by: 1).lazy.map({_ in self }).reduce(1, *)
}
}
 
protocol PathologicalFloat: SignedNumeric, Strideable, ExpressibleByFloatLiteral {
static var e: Self { get }
 
static func /(_ lhs: Self, _ rhs: Self) -> Self
}
 
extension Double: PathologicalFloat {
static var e: Double { Double("2.71828182845904523536028747135266249")! }
}
 
extension Float: PathologicalFloat {
static var e: Float { Float("2.7182818284590")! }
}
 
extension Decimal: PathologicalFloat {
static var e: Decimal { Decimal(string: "2.71828182845904523536028747135266249")! }
}
 
extension BDouble: PathologicalFloat {
static var e: BDouble { BDouble("2.71828182845904523536028747135266249")! }
 
public func advanced(by n: BDouble) -> BDouble { self + n }
public func distance(to other: BDouble) -> BDouble { abs(self - other) }
}
 
func badSequence<T: PathologicalFloat>(n: Int) -> T {
guard n != 1 else { return 2 }
guard n != 2 else { return -4 }
 
var a: T = 2, b: T = -4
 
for _ in stride(from: 2, to: n, by: 1) {
(a, b) = (b, 111 - 1130 / b + 3000 / (a * b))
}
 
return b
}
 
func chaoticBank<T: PathologicalFloat>(years: T) -> T {
var balance = T.e - 1
 
for year: T in stride(from: 1, through: 25, by: 1) {
balance = (balance * year) - 1
}
 
return balance
}
 
func rumpFunction<T: PathologicalFloat>(_ a: T, _ b: T) -> T {
let aSquared = a.power(2)
let bSix = b.power(6)
 
let f1 = 333.75 * bSix
let f2 = aSquared * (11 * aSquared * b.power(2) - bSix - 121 * b.power(4) - 2)
let f3 = 5.5 * b.power(8) + a / (2 * b)
 
return f1 + f2 + f3
}
 
func fmt<T: CVarArg>(_ n: T) -> String { String(format: "%16.16f", n) }
 
print("Bad sequence")
for i in [3, 4, 5, 6, 7, 8, 20, 30, 50, 100] {
let vFloat: Float = badSequence(n: i)
let vDouble: Double = badSequence(n: i)
let vDecimal: Decimal = badSequence(n: i)
let vBigDouble: BDouble = badSequence(n: i)
 
print("v(\(i)) as Float \(fmt(vFloat)); as Double = \(fmt(vDouble)); as Decimal = \(vDecimal); as BDouble = \(vBigDouble.decimalExpansion(precisionAfterDecimalPoint: 16, rounded: false))")
}
 
 
let bankFloat: Float = chaoticBank(years: 25)
let bankDouble: Double = chaoticBank(years: 25)
let bankDecimal: Decimal = chaoticBank(years: 25)
let bankBigDouble: BDouble = chaoticBank(years: 25)
 
print("\nChaotic bank")
print("After 25 years your bank will be \(bankFloat) if stored as a Float")
print("After 25 years your bank will be \(bankDouble) if stored as a Double")
print("After 25 years your bank will be \(bankDecimal) if stored as a Decimal")
print("After 25 years your bank will be \(bankBigDouble.decimalExpansion(precisionAfterDecimalPoint: 16, rounded: false)) if stored as a BigDouble")
 
let rumpFloat: Float = rumpFunction(77617.0, 33096.0)
let rumpDouble: Double = rumpFunction(77617.0, 33096.0)
let rumpDecimal: Decimal = rumpFunction(77617.0, 33096.0)
let rumpBigDouble: BDouble = rumpFunction(77617.0, 33096.0)
 
print("\nRump's function")
print("rump(77617.0, 33096.0) as Float \(rumpFloat); as Double = \(rumpDouble); as Decimal = \(rumpDecimal); as BDouble = \(rumpBigDouble.decimalExpansion(precisionAfterDecimalPoint: 16, rounded: false))")</syntaxhighlight>
 
{{out}}
 
<pre>Bad sequence
v(3) as Float 18.5000000000000000; as Double = 18.5000000000000000; as Decimal = 18.5; as BDouble = 18.5000000000000000
v(4) as Float 9.3783798217773438; as Double = 9.3783783783783790; as Decimal = 9.378378378378378378378378378378378379; as BDouble = 9.3783783783783783
v(5) as Float 7.8011646270751953; as Double = 7.8011527377521688; as Decimal = 7.8011527377521613832853025936598347208; as BDouble = 7.8011527377521613
v(6) as Float 7.1545600891113281; as Double = 7.1544144809753334; as Decimal = 7.154414480975249353527890653858927037; as BDouble = 7.1544144809752493
v(7) as Float 6.8088302612304688; as Double = 6.8067847369248113; as Decimal = 6.806784736923632983941756596252083488; as BDouble = 6.8067847369236329
v(8) as Float 6.6227531433105469; as Double = 6.5926327687217920; as Decimal = 6.592632768704438392742002776072632593; as BDouble = 6.5926327687044383
v(20) as Float 100.0000000000000000; as Double = 98.3495031221653591; as Decimal = 6.043552110189180069946503928146085357; as BDouble = 6.0435521101892688
v(30) as Float 100.0000000000000000; as Double = 99.9999999999989342; as Decimal = 5.864835170633765923137784097537303066; as BDouble = 6.0067860930312057
v(50) as Float 100.0000000000000000; as Double = 100.0000000000000000; as Decimal = 100.00000000000000000002294175104747792; as BDouble = 6.0001758466271871
v(100) as Float 100.0000000000000000; as Double = 100.0000000000000000; as Decimal = 100; as BDouble = 6.0000000193194779
 
Chaotic bank
After 25 years your bank will be -1.2804254e+18 if stored as a Float
After 25 years your bank will be -2242373258.570158 if stored as a Double
After 25 years your bank will be 0.03993872955290591987527254016 if stored as a Decimal
After 25 years your bank will be 0.0399387295529059 if stored as a BigDouble
 
Rump's function
rump(77617.0, 33096.0) as Float -6.338253e+29; as Double = -1.1805916207174113e+21; as Decimal = -1; as BDouble = -0.8273960599468213</pre>
 
=={{header|TI-83 BASIC}}==
Line 3,348 ⟶ 3,994:
u(1)=2
u(2)=-4
<langsyntaxhighlight lang="ti83b"> nMin=1
u(n)=111-1130/u(n-1) + 3000/(u(n-1)*u(n-2))
u(nMin)={-4;2}</langsyntaxhighlight>
The result converges to the wrong limit!
{{out}}
Line 3,389 ⟶ 4,035:
Main() procedure and output formatting:
 
<langsyntaxhighlight lang="vbnet">Imports System.Globalization
Imports System.Numerics
Imports Numerics
Line 3,442 ⟶ 4,088:
SetConsoleFormat(0)
End Sub
End Module</langsyntaxhighlight>
 
<!--Anchors for the C# section to link to-->
Line 3,448 ⟶ 4,094:
Somewhat predictably, Single fairs the worst and Double slightly better. Decimal lasts past iteration 20, and BigRational remains exactly precise.
 
<langsyntaxhighlight lang="vbnet">Module Task1
Iterator Function SequenceSingle() As IEnumerable(Of Single)
' n, n-1, and n-2
Line 3,554 ⟶ 4,200:
Next
End Sub
End Module</langsyntaxhighlight>
 
{{out}}
Line 3,575 ⟶ 4,221:
Decimal appears to be doing well by year 25, but begins to degenerate ''the very next year'' and soon overflows.
 
<langsyntaxhighlight lang="vbnet">Module Task2
Iterator Function ChaoticBankSocietySingle() As IEnumerable(Of Single)
Dim balance As Single = Math.E - 1
Line 3,677 ⟶ 4,323:
Next
End Sub
End Module</langsyntaxhighlight>
 
{{out}}
Line 3,730 ⟶ 4,376:
Each of these three tasks are susceptible to this phenomenon; the outputs of this program for floating-point arithmetic should not be expected to be the same on different systems.
 
<langsyntaxhighlight lang="vbnet">Module Task3
Function SiegfriedRumpSingle(a As Single, b As Single) As Single
Dim a2 = a * a,
Line 3,838 ⟶ 4,484:
Console.WriteLine($" Exact: {br}")
End Sub
End Module</langsyntaxhighlight>
 
{{out|note=debug build}}
Line 3,872 ⟶ 4,518:
{{libheader|Wren-big}}
{{libheader|Wren-fmt}}
<langsyntaxhighlight ecmascriptlang="wren">import "./big" for BigRat
import "./fmt" for Fmt
 
var LIMIT = 100
Line 3,906 ⟶ 4,552:
var c8 = c5 * a.pow(2) * b.pow(2) - b.pow(6) - c6 * b.pow(4) - 2
f = f + c8 * a.pow(2)
System.print("\nf(77617.0, 33096.0) is %(f.toDecimal(16))")</langsyntaxhighlight>
 
{{out}}
Line 4,012 ⟶ 4,658:
 
f(77617.0, 33096.0) is -0.8273960599468214
</pre>
 
=={{header|XPL0}}==
This shows the results from the IEEE 754 double precision (64-bit) FPU
built into the Raspberry Pi 4. Identical results were obtained from
EXPL-32 on an Intel Inspiron. A Duron 850 gave identical results for the
first task, but the second task diverged to positive values after 17
years. The Duron also gave a large positive value for the third task.
<syntaxhighlight lang "XPL0">func real F(A, B);
real A, B;
return 333.75*Pow(B,6.) +
A*A*(11.*A*A*B*B - Pow(B,6.) - 121.*Pow(B,4.) - 2.) +
5.5*Pow(B,8.) + A/(2.*B);
 
real V1, V2, V3, Bal;
int N, Year;
[V1:= 2.; V2:= -4.; \task 1
for N:= 3 to 100 do
[V3:= 111. - 1130./V2 + 3000./(V1*V2);
case N of
3,4,5,6,7,8,20,30,50,100:
[Format(3, 0); RlOut(0, float(N));
Format(5, 16); RlOut(0, V3); CrLf(0);
]
other [];
V1:= V2; V2:= V3;
];
CrLf(0); \task 2
Bal:= Exp(1.) - 1.;
for Year:= 1 to 25 do
[Bal:= Bal*float(Year) - 1.;
Format(2, 0); RlOut(0, float(Year));
Format(12, 16); RlOut(0, Bal); CrLf(0);
];
CrLf(0); \task 3
RlOut(0, F(77617., 33096.));
CrLf(0);
]</syntaxhighlight>
{{out}}
<pre>
3 18.5000000000000000
4 9.3783783783783800
5 7.8011527377521700
6 7.1544144809753300
7 6.8067847369248100
8 6.5926327687217900
20 98.3495031221654000
30 99.9999999999989000
50 100.0000000000000000
100 100.0000000000000000
 
1 0.7182818284590450
2 0.4365636569180900
3 0.3096909707542710
4 0.2387638830170820
5 0.1938194150854110
6 0.1629164905124650
7 0.1404154335872580
8 0.1233234686980610
9 0.1099112182825480
10 0.0991121828254790
11 0.0902340110802700
12 0.0828081329632370
13 0.0765057285220790
14 0.0710801993091080
15 0.0662029896366220
16 0.0592478341859530
17 0.0072131811612050
18 -0.8701627390983050
19 -17.5330920428678000
20 -351.6618408573560000
21 -7385.8986580044700000
22 -162490.7704760980000000
23 -3737288.7209502600000000
24 -89694930.3028063000000000
25 -2242373258.5701600000000000
 
-1180591620717410000000.0000000000000000
</pre>
 
=={{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.
<langsyntaxhighlight 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;</langsyntaxhighlight>
We'll use the convenient formula given in the referenced paper to create a fraction with big ints
<langsyntaxhighlight lang="zkl">var BN=Import("zklBigNum"), ten2n=BN(10).pow(64);
 
fcn u(n){ // use formula to create a fraction of big ints
Line 4,038 ⟶ 4,762:
foreach n in (T(3,4,5,6,7,8,20,30,50,100)){
"n =%3d; %3.20F %s".fmt(n,series[n-1],u(n-1)).println();
}</langsyntaxhighlight>
{{out}}
Note that, at n=100, we still have diverged (at the 15th place) from the Raku solution and 12th place from the J solution.
Line 4,055 ⟶ 4,779:
</pre>
Chaotic banking society is just nasty so we use a five hundred digit e (the e:= text is one long line).
<langsyntaxhighlight lang="zkl">println("\n2nd: Chaotic banking society");
e:="271828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642742746639193200305992181741359662904357290033429526059563073813232862794349076323382988075319525101901157383418793070215408914993488416750924476146066808226480016847741185374234544243710753907774499206955170276183860626133138458300075204493382656029760673711320070932870912744374704723069697720931014169283681902551510865746377211125238978442505695369677078544996996794686445490598793163688923009879312";
var en=(e.len()-1), tenEN=BN(10).pow(en);
Line 4,061 ⟶ 4,785:
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));</langsyntaxhighlight>
{{out}}
<pre>
Line 4,068 ⟶ 4,792:
</pre>
For Rump's example, multiple the formula by 10ⁿ so we can use integer math.
<langsyntaxhighlight lang="zkl">fcn rump(a,b){ b=BN(b);
b2,b4,b6,b8:=b.pow(2),b.pow(4),b.pow(6),b.pow(8);
a2:=BN(a).pow(2);
Line 4,075 ⟶ 4,799:
tostr(r,66,32)
}
println("\n3rd: Rump's example: f(77617.0, 33096.0) = ",rump(77617,33096));</langsyntaxhighlight>
{{out}}
<pre>
9,476

edits