Pathological floating point problems: Difference between revisions

m
m (→‎{{header|Ring}}: Remove vanity tags)
m (→‎{{header|Wren}}: Minor tidy)
 
(47 intermediate revisions by 18 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 247:
Balance: Num := Ada.Numerics.E - 1.0;
begin
Ada.Text_IO.Put_Line("Chaotic Bank SocientySociety with" &
Integer'Image(After) & " digits");
Ada.Text_IO.Put_Line("year balance");
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>
/*Abhishek Ghosh, 10th November 2017*/
 
#include<stdio.h>
#include<gmp.h>
Line 605 ⟶ 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 634 ⟶ 632:
v_100 : 6.000000019319477929060000000000000000000000000000000000000000000000000000000000
</pre>
 
=={{header|C sharp}}==
{{trans|Visual Basic .NET}}
'''Compiler:''' Roslyn C# (language version >=7.3)
{{works with|.NET Framework|4.6.2}}
{{works with|.NET Core|2.1}}
{{libheader|BigRationalLibrary|1.0.0}}
See VB.NET entry for details (Single is float in C#; Double is double, and Decimal is decimal).
 
The following sections source code must be located in a single file.
 
<syntaxhighlight lang="csharp">#define USE_BIGRATIONAL
#define BANDED_ROWS
#define INCREASED_LIMITS
 
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Numerics;
using Numerics;
 
using static Common;
using static Task1;
using static Task2;
using static Task3;
 
#if !USE_BIGRATIONAL
// Mock structure to make test code work.
struct BigRational
{
public override string ToString() => "NOT USING BIGRATIONAL";
public static explicit operator decimal(BigRational value) => -1;
}
#endif
 
static class Common
{
public const string FMT_STR = "{0,4} {1,-15:G9} {2,-24:G17} {3,-32} {4,-32}";
public static string Headings { get; } =
string.Format(
CultureInfo.InvariantCulture,
FMT_STR,
new[] { "N", "Single", "Double", "Decimal", "BigRational (rounded as Decimal)" });
 
[Conditional("BANDED_ROWS")]
static void SetConsoleFormat(int n)
{
if (n % 2 == 0)
{
Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.White;
}
else
{
Console.BackgroundColor = ConsoleColor.White;
Console.ForegroundColor = ConsoleColor.Black;
}
}
 
public static string FormatOutput(int n, (float sn, double db, decimal dm, BigRational br) x)
{
SetConsoleFormat(n);
return string.Format(CultureInfo.CurrentCulture, FMT_STR, n, x.sn, x.db, x.dm, (decimal)x.br);
}
 
static void Main()
{
WrongConvergence();
 
Console.WriteLine();
ChaoticBankSociety();
 
Console.WriteLine();
SiegfriedRump();
 
SetConsoleFormat(0);
}
}</syntaxhighlight>
 
===Task 1: Converging sequence===
'''See''' [[#VB.NET Task 1]]
 
<syntaxhighlight lang="csharp">static class Task1
{
public static IEnumerable<float> SequenceSingle()
{
// n, n-1, and n-2
float vn, vn_1, vn_2;
vn_2 = 2;
vn_1 = -4;
 
while (true)
{
yield return vn_2;
vn = 111f - (1130f / vn_1) + (3000f / (vn_1 * vn_2));
vn_2 = vn_1;
vn_1 = vn;
}
}
 
public static IEnumerable<double> SequenceDouble()
{
// n, n-1, and n-2
double vn, vn_1, vn_2;
vn_2 = 2;
vn_1 = -4;
 
while (true)
{
yield return vn_2;
vn = 111 - (1130 / vn_1) + (3000 / (vn_1 * vn_2));
vn_2 = vn_1;
vn_1 = vn;
}
}
 
public static IEnumerable<decimal> SequenceDecimal()
{
// n, n-1, and n-2
decimal vn, vn_1, vn_2;
vn_2 = 2;
vn_1 = -4;
 
// Use constants to avoid calling the Decimal constructor in the loop.
const decimal i11 = 111;
const decimal i130 = 1130;
const decimal E000 = 3000;
 
while (true)
{
yield return vn_2;
vn = i11 - (i130 / vn_1) + (E000 / (vn_1 * vn_2));
vn_2 = vn_1;
vn_1 = vn;
}
}
 
#if USE_BIGRATIONAL
public static IEnumerable<BigRational> SequenceRational()
{
// n, n-1, and n-2
BigRational vn, vn_1, vn_2;
vn_2 = 2;
vn_1 = -4;
 
// Same reasoning as for decimal.
BigRational i11 = 111;
BigRational i130 = 1130;
BigRational E000 = 3000;
 
while (true)
{
yield return vn_2;
vn = i11 - (i130 / vn_1) + (E000 / (vn_1 * vn_2));
vn_2 = vn_1;
vn_1 = vn;
}
}
#else
public static IEnumerable<BigRational> SequenceRational()
{
while (true) yield return default;
}
#endif
 
static void IncreaseMaxN(ref int[] arr)
{
int[] tmp = new int[arr.Length + 1];
arr.CopyTo(tmp, 0);
tmp[arr.Length] = 1000;
arr = tmp;
}
 
public static void WrongConvergence()
{
Console.WriteLine("Wrong Convergence Sequence:");
 
int[] displayedIndices = { 3, 4, 5, 6, 7, 8, 20, 30, 50, 100 };
IncreaseMaxN(ref displayedIndices);
 
var indicesSet = new HashSet<int>(displayedIndices);
 
Console.WriteLine(Headings);
 
int n = 1;
// Enumerate the implementations in parallel as tuples.
foreach (var x in SequenceSingle()
.Zip(SequenceDouble(), (sn, db) => (sn, db))
.Zip(SequenceDecimal(), (a, dm) => (a.sn, a.db, dm))
.Zip(SequenceRational(), (a, br) => (a.sn, a.db, a.dm, br)))
{
if (n > displayedIndices.Max()) break;
 
if (indicesSet.Contains(n))
Console.WriteLine(FormatOutput(n, x));
 
n++;
}
}
}</syntaxhighlight>
 
{{out}}
<pre>Wrong Convergence Sequence:
N Single Double Decimal BigRational (rounded as Decimal)
3 18.5 18.5 18.5 18.5
4 9.37837982 9.378378378378379 9.378378378378378378378378378 9.378378378378378378378378378
5 7.80116463 7.8011527377521688 7.80115273775216138328530259 7.8011527377521613832853025937
6 7.15456009 7.1544144809753334 7.154414480975249353527890606 7.1544144809752493535278906539
7 6.80883026 6.8067847369248113 6.806784736923632983941755925 6.8067847369236329839417565963
8 6.62275314 6.592632768721792 6.592632768704438392741992887 6.5926327687044383927420027764
20 100 98.349503122165359 6.04355210719488789087813234 6.0435521101892688677774773641
30 100 99.999999999998934 101.88552052291609961584734802 6.006786093031205758530554048
50 100 100 100.00000000000000000000000068 6.0001758466271871889456140207
100 100 100 100.0 6.0000000193194779291040868034
1000 100 100 100.0 6.0000000000000000000000000000</pre>
 
===Task 2: The Chaotic Bank Society===
'''See''' [[#VB.NET Task 2]]
 
<syntaxhighlight lang="csharp">static class Task2
{
public static IEnumerable<float> ChaoticBankSocietySingle()
{
float balance = (float)(Math.E - 1);
 
for (int year = 1; ; year++)
yield return balance = (balance * year) - 1;
}
 
public static IEnumerable<double> ChaoticBankSocietyDouble()
{
double balance = Math.E - 1;
 
for (int year = 1; ; year++)
yield return balance = (balance * year) - 1;
}
 
public static IEnumerable<decimal> ChaoticBankSocietyDecimal()
{
// 27! is the largest factorial decimal can represent.
decimal balance = CalculateEDecimal(27) - 1;
 
for (int year = 1; ; year++)
yield return balance = (balance * year) - 1;
}
 
#if USE_BIGRATIONAL
public static IEnumerable<BigRational> ChaoticBankSocietyRational()
{
// 100 iterations is precise enough for 25 years.
BigRational brBalance = CalculateERational(100) - 1;
 
for (int year = 1; ; year++)
yield return brBalance = (brBalance * year) - 1;
}
#else
public static IEnumerable<BigRational> ChaoticBankSocietyRational()
{
while (true) yield return default;
}
#endif
 
public static decimal CalculateEDecimal(int terms)
{
decimal e = 1;
decimal fact = 1;
for (int i = 1; i <= terms; i++)
{
fact *= i;
e += decimal.One / fact;
}
 
return e;
}
 
#if USE_BIGRATIONAL
public static BigRational CalculateERational(int terms)
{
BigRational e = 1;
BigRational fact = 1;
for (int i = 1; i < terms; i++)
{
fact *= i;
e += BigRational.Invert(fact);
}
 
return e;
}
#endif
 
[Conditional("INCREASED_LIMITS")]
static void InceaseMaxYear(ref int year) => year = 40;
 
public static void ChaoticBankSociety()
{
Console.WriteLine("Chaotic Bank Society:");
Console.WriteLine(Headings);
 
int maxYear = 25;
InceaseMaxYear(ref maxYear);
 
int i = 0;
foreach (var x in ChaoticBankSocietySingle()
.Zip(ChaoticBankSocietyDouble(), (sn, db) => (sn, db))
.Zip(ChaoticBankSocietyDecimal(), (a, dm) => (a.sn, a.db, dm))
.Zip(ChaoticBankSocietyRational(), (a, br) => (a.sn, a.db, a.dm, br)))
{
if (i >= maxYear) break;
Console.WriteLine(FormatOutput(i + 1, x));
i++;
}
}
}</syntaxhighlight>
 
{{out}}
<pre>Chaotic Bank Society:
N Single Double Decimal BigRational (rounded as Decimal)
1 0.718281865 0.71828182845904509 0.7182818284590452353602874714 0.7182818284590452353602874713
2 0.43656373 0.43656365691809018 0.4365636569180904707205749428 0.4365636569180904707205749427
3 0.309691191 0.30969097075427054 0.3096909707542714121617248284 0.3096909707542714121617248281
4 0.238764763 0.23876388301708218 0.2387638830170856486468993136 0.2387638830170856486468993124
5 0.193823814 0.1938194150854109 0.1938194150854282432344965680 0.1938194150854282432344965623
6 0.162942886 0.16291649051246537 0.1629164905125694594069794080 0.1629164905125694594069793739
7 0.140600204 0.14041543358725761 0.1404154335879862158488558560 0.1404154335879862158488556174
8 0.124801636 0.12332346869806088 0.1233234687038897267908468480 0.1233234687038897267908449393
9 0.123214722 0.10991121828254791 0.1099112183350075411176216320 0.1099112183350075411176044541
10 0.232147217 0.099112182825479067 0.0991121833500754111762163200 0.0991121833500754111760445416
11 1.55361938 0.090234011080269738 0.0902340168508295229383795200 0.0902340168508295229364899583
12 17.6434326 0.082808132963236858 0.0828082022099542752605542400 0.0828082022099542752378795006
13 228.364624 0.076505728522079153 0.0765066287294055783872051200 0.0765066287294055780924335089
14 3196.10474 0.071080199309108139 0.0710928022116780974208716800 0.0710928022116780932940691248
15 47940.5703 0.066202989636622078 0.0663920331751714613130752000 0.0663920331751713994110368720
16 767048.125 0.059247834185953252 0.0622725308027433810092032000 0.0622725308027423905765899521
17 13039817 0.0072131811612052843 0.0586330236466374771564544000 0.0586330236466206398020291865
18 234716704 -0.87016273909830488 0.0553944256394745888161792000 0.0553944256391715164365253585
19 4.45961728E+09 -17.533092042867793 0.0524940871500171875074048000 0.0524940871442588122939818127
20 8.91923497E+10 -351.66184085735586 0.0498817430003437501480960000 0.0498817428851762458796362544
21 1.87303933E+12 -7385.898658004473 0.0475166030072187531100160000 0.0475166005887011634723613427
22 4.12068642E+13 -162490.77047609841 0.0453652661588125684203520000 0.0453652129514255963919495414
23 9.47757884E+14 -3737288.7209502636 0.0434011216526890736680960000 0.0433998978827887170148394524
24 2.27461897E+16 -89694930.302806318 0.0416269196645377680343040000 0.0415975491869292083561468582
25 5.68654735E+17 -2242373258.570158 0.0406729916134442008576000000 0.0399387296732302089036714552
26 1.47850229E+19 -58301704723.824112 0.0574977819495492222976000000 0.0384069715039854314954578354
27 3.99195623E+20 -1574146027544.251 0.5524401126378290020352000000 0.0369882306076066503773615576
28 1.11774772E+22 -44076088771240.031 14.468323153859212056985600000 0.0356704570129862105661236148
29 3.24146835E+23 -1278206574365962 418.58137146191714965258240000 0.0344432533766001064175848308
30 9.72440521E+24 -38346197230978864 12556.441143857514489577472000 0.0332976012980031925275449256
31 3.01456563E+26 -1.1887321141603448E+18 389248.67545958294917690163200 0.0322256402380989683538926936
32 9.64661E+27 -3.8039427653131035E+19 12455956.614706654373660852224 0.0312204876191669873245661979
33 3.18338125E+29 -1.2553011125533242E+21 411046567.28531959433080812339 0.0302760914325105817106845313
34 1.08234959E+31 -4.268023782681302E+22 13975583286.700866207247476195 0.0293871087053597781632740646
35 3.78822341E+32 -1.4938083239384556E+24 489145415033.53031725366166682 0.0285488046875922357145922644
36 1.36376043E+34 -5.3777099661784406E+25 17609234941206.091421131820006 0.0277569687533204857253215188
37 5.04591372E+35 -1.989752687486023E+27 651541692824624.38258187734022 0.0270078438728579718368961961
38 1.91744716E+37 -7.5610602124468873E+28 24758584327335725.538111338928 0.0262980671686029298020554545
39 ∞ -2.9488134828542859E+30 965584788766093294.9863422182 0.0256246195755142622801627278
40 ∞ -1.1795253931417144E+32 38623391550643731798.453688728 0.0249847830205704912065091156</pre>
 
===Task 3: Rump's example===
'''See''' [[#VB.NET Task 3]]
 
<syntaxhighlight lang="csharp">static class Task3
{
public static float SiegfriedRumpSingle(float a, float b)
{
float
a2 = a * a,
b2 = b * b,
b4 = b2 * b2,
b6 = b4 * b2
;
 
// Non-integral literals must be coerced to single using the type suffix.
return 333.75f * b6 +
(a2 * (
11 * a2 * b2 -
b6 -
121 * b4 -
2)) +
5.5f * b4 * b4 +
a / (2 * b);
}
 
public static double SiegfriedRumpDouble(double a, double b)
{
double
a2 = a * a,
b2 = b * b,
b4 = b2 * b2,
b6 = b4 * b2
;
 
// Non-integral literals are doubles by default.
return
333.75 * b6
+ a2 * (
11 * a2 * b * b
- b6
- 121 * b4
- 2)
+ 5.5 * b4 * b4
+ a / (2 * b);
}
 
public static decimal SiegfriedRumpDecimal(decimal a, decimal b)
{
decimal
a2 = a * a,
b2 = b * b,
b4 = b2 * b2,
b6 = b4 * b2
;
 
// The same applies for decimal.
return
333.75m * b6
+ a2 * (
11 * a2 * b * b
- b6
- 121 * b4
- 2)
+ 5.5m * b4 * b4
+ a / (2 * b);
}
 
#if USE_BIGRATIONAL
public static BigRational SiegfriedRumpRational(BigRational a, BigRational b)
{
// Use mixed number constructor to maintain exact precision (333+3/4, 5+1/2).
var c1 = new BigRational(33375, 100);
var c2 = new BigRational(55, 10);
 
return c1 * BigRational.Pow(b, 6)
+ (a * a * (
11 * a * a * b * b
- BigRational.Pow(b, 6)
- 121 * BigRational.Pow(b, 4)
- 2))
+ c2 * BigRational.Pow(b, 8)
+ a / (2 * b);
}
#else
public static IEnumerable<BigRational> SiegfriedRumpRational()
{
while (true) yield return default;
}
#endif
 
public static void SiegfriedRump()
{
Console.WriteLine("Siegfried Rump Formula");
int a = 77617;
int b = 33096;
 
Console.Write("Single: ");
float sn = SiegfriedRumpSingle(a, b);
Console.WriteLine("{0:G9}", sn);
Console.WriteLine();
 
Console.Write("Double: ");
double db = SiegfriedRumpDouble(a, b);
Console.WriteLine("{0:G17}", db);
Console.WriteLine();
 
Console.WriteLine("Decimal:");
decimal dm = 0;
try
{
dm = SiegfriedRumpDecimal(a, b);
}
catch (OverflowException ex)
{
Console.WriteLine("Exception: " + ex.Message);
}
Console.WriteLine($" {dm}");
Console.WriteLine();
 
Console.WriteLine("BigRational:");
BigRational br = SiegfriedRumpRational(a, b);
Console.WriteLine($" Rounded: {(decimal)br}");
Console.WriteLine($" Exact: {br}");
}
}</syntaxhighlight>
 
{{out}}
Note that the output for Single is slightly different from VB.
<pre>Siegfried Rump Formula
Single: -6.338253E+29
 
Double: -2.3611832414348226E+21
 
Decimal:
Exception: Value was either too large or too small for a Decimal.
0
 
BigRational:
Rounded: -0.8273960599468213681411650955
Exact: -54767/66192</pre>
 
=={{header|Clojure}}==
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 675 ⟶ 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 689 ⟶ 1,187:
 
===Task 3: Rump's Example===
<langsyntaxhighlight lang="clojure">(defn rump [a b]
(+ (* (rationalize 333.75) (expt b 6))
(* (expt a 2)
Line 696 ⟶ 1,194:
(/ a (* 2 b))))
; Using BigInt numeric literal style to avoid integer overflow
(double (rump 77617 33096N))</langsyntaxhighlight>
 
{{out}}
Line 702 ⟶ 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 752 ⟶ 1,536:
</pre>
 
=={{header|FreeBASICFactor}}==
These problems are straightforward due to Factor's rational numbers. One needs only take care not to introduce floating point values to the calculations.
<lang freebasic>' FB 1.05.0 Win64
<syntaxhighlight lang="factor">USING: formatting fry io kernel locals math math.functions
math.ranges sequences ;
IN: rosetta-code.pathological
 
: next2 ( x y -- y z )
' As FB's native types have only 64 bit precision at most we need to use the
swap dupd dupd '[ 111 1130 _ / - 3000 _ _ * / + ] call ;
' C library, GMP v6.1.0, for arbitrary precision arithmetic
 
: pathological-sequence ( -- seq )
#Include Once "gmp.bi"
2 -4 100 [ next2 dup ] replicate 2nip { 0 2 -4 } prepend ;
mpf_set_default_prec(640) '' 640 bit precision, enough for this exercise
 
: show-sequence ( -- )
Function v(n As UInteger, prev As __mpf_struct, prev2 As __mpf_struct) As __mpf_struct
{ 3 4 5 6 7 8 20 30 50 100 } dup pathological-sequence nths
Dim As __mpf_struct a, b, c
[ "n = %-3d %21.16f\n" printf ] 2each ;
mpf_init(@a) : mpf_init(@b) : mpf_init(@c)
If n = 0 Then mpf_set_ui(@a, 0UL)
If n = 1 Then mpf_set_ui(@a, 2UL)
If n = 2 Then mpf_set_si(@a, -4L)
If n < 3 Then Return a
mpf_ui_div(@a, 1130UL, @prev)
mpf_mul(@b, @prev, @prev2)
mpf_ui_div(@c, 3000UL, @b)
mpf_ui_sub(@b, 111UL, @a)
mpf_add(@a, @b, @c)
mpf_clear(@b)
mpf_clear(@c)
Return a
End Function
 
CONSTANT: e 106246577894593683/39085931702241241
Function f(a As Double, b As Double) As __mpf_Struct
: balance ( n -- x ) [1,b] e 1 - [ * 1 - ] reduce ;
Dim As __mpf_struct temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8
mpf_init(@temp1) : mpf_init(@temp2) : mpf_init(@temp3) : mpf_init(@temp4)
mpf_init(@temp5) : mpf_init(@temp6) : mpf_init(@temp7) : mpf_init(@temp8)
mpf_set_d(@temp1, a) '' a
mpf_set_d(@temp2, b) '' b
mpf_set_d(@temp3, 333.75) '' 333.75
mpf_pow_ui(@temp4, @temp2, 6UL) '' b ^ 6
mpf_mul(@temp3, @temp3, @temp4) '' 333.75 * b^6
mpf_pow_ui(@temp5, @temp1, 2UL) '' a^2
mpf_pow_ui(@temp6, @temp2, 2UL) '' b^2
mpf_mul_ui(@temp7, @temp5, 11UL) '' 11 * a^2
mpf_mul(@temp7, @temp7, @temp6) '' 11 * a^2 * b^2
mpf_sub(@temp7, @temp7, @temp4) '' 11 * a^2 * b^2 - b^6
mpf_pow_ui(@temp4, @temp2, 4UL) '' b^4
mpf_mul_ui(@temp4, @temp4, 121UL) '' 121 * b^4
mpf_sub(@temp7, @temp7, @temp4) '' 11 * a^2 * b^2 - b^6 - 121 * b^4
mpf_sub_ui(@temp7, @temp7, 2UL) '' 11 * a^2 * b^2 - b^6 - 121 * b^4 - 2
mpf_mul(@temp7, @temp7, @temp5) '' (11 * a^2 * b^2 - b^6 - 121 * b^4 - 2) * a^2
mpf_add(@temp3, @temp3, @temp7) '' 333.75 * b^6 + (11 * a^2 * b^2 - b^6 - 121 * b^4 - 2) * a^2
mpf_set_d(@temp4, 5.5) '' 5.5
mpf_pow_ui(@temp5, @temp2, 8UL) '' b^8
mpf_mul(@temp4, @temp4, @temp5) '' 5.5 * b^8
mpf_add(@temp3, @temp3, @temp4) '' 333.75 * b^6 + (11 * a^2 * b^2 - b^6 - 121 * b^4 - 2) * a^2 + 5.5 * b^8
mpf_mul_ui(@temp4, @temp2, 2UL) '' 2 * b
mpf_div(@temp5, @temp1, @temp4) '' a / (2 * b)
mpf_add(@temp3, @temp3, @temp5) '' 333.75 * b^6 + (11 * a^2 * b^2 - b^6 - 121 * b^4 - 2) * a^2 + 5.5 * b^8 + a / (2 * b)
mpf_clear(@temp1) : mpf_clear(@temp2) : mpf_clear(@temp4) : mpf_clear(@temp5)
mpf_clear(@temp6) : mpf_clear(@temp7) : mpf_clear(@temp8)
Return temp3
End Function
 
:: f ( a b -- x )
Dim As Zstring * 60 z
333+3/4 b 6 ^ * 11 a sq b sq * * b 6 ^ - b 4 ^ 121 * - 2 - a
Dim As __mpf_struct result, prev, prev2
sq * b 8 ^ 5+1/2 * a 2 b * / + + + ;
' We cache the two previous results to avoid recursive calls to v
For i As Integer = 1 To 100
result = v(i, prev, prev2)
If (i >= 3 AndAlso i <= 8) OrElse i = 20 OrElse i = 30 OrElse i = 50 OrElse i = 100 Then
gmp_sprintf(@z,"%53.50Ff",@result) '' express result to 50 decimal places
Print "n ="; i , z
End If
prev2 = prev
prev = result
Next
 
: pathological-demo ( -- )
mpf_clear(@prev) : mpf_clear(@prev2) '' note : prev = result
"Task 1 - Sequence convergence:" print show-sequence nl
 
"Task 2 - Chaotic Bank fund after 25 years:" print
Dim As __mpf_struct e, balance, ii, temp
25 balance "%.16f\n" printf nl
mpf_init(@e) : mpf_init(@balance) : mpf_init(@ii) : mpf_init(@temp)
mpf_set_str(@e, "2.71828182845904523536028747135266249775724709369995", 10) '' e to 50 decimal places
mpf_sub_ui(@balance, @e, 1UL)
 
"Task 3 - Siegfried Rump's example:" print
For i As ULong = 1 To 25
77617 33096 f "77617 33096 f = %.16f\n" printf ;
mpf_set_ui(@ii, i)
mpf_mul(@temp, @balance, @ii)
mpf_sub_ui(@balance, @temp, 1UL)
Next
 
Print
Print "Chaotic B/S balance after 25 years : ";
gmp_sprintf(@z,"%.16Ff",@balance) '' express balance to 16 decimal places
Print z
mpf_clear(@e) : mpf_clear(@balance) : mpf_clear(@ii) : mpf_clear(@temp)
 
Print
Dim rump As __mpf_struct
rump = f(77617.0, 33096.0)
gmp_sprintf(@z,"%.16Ff", @rump) '' express rump to 16 decimal places
Print "f(77617.0, 33096.0) = "; z
 
Print
Print "Press any key to quit"
Sleep</lang>
 
MAIN: pathological-demo</syntaxhighlight>
{{out}}
<pre>
Task 1 - Sequence convergence:
n = 3 18.50000000000000000000000000000000000000000000000000
n = 3 18.5000000000000000
n = 4 9.37837837837837837837837837837837837837837837837838
n = 4 9.3783783783783784
n = 5 7.80115273775216138328530259365994236311239193083573
n = 5 7.8011527377521614
n = 6 7.15441448097524935352789065386036202438123383819727
n = 6 7.1544144809752494
n = 7 6.80678473692363298394175659627200908762327670780193
n = 7 6.8067847369236330
n = 8 6.59263276870443839274200277636599482655298231773461
n = 8 6.5926327687044384
n = 20 6.04355211018926886777747736409754013318771500000612
n = 20 6.0435521101892689
n = 30 6.00678609303120575853055404795323970583307231443837
n = 30 6.0067860930312058
n = 50 6.00017584662718718894561402074719546952373517709933
n = 50 6.0001758466271872
n = 100 6.00000001931947792910408680340358571502435067543695
n = 100 6.0000000193194779
 
Task 2 - Chaotic B/SBank balancefund after 25 years : 0.0399387296732302
0.0399387300490171
 
Task 3 - Siegfried Rump's example:
f(77617.0, 33096.0) = -0.8273960599468214
77617 33096 f = -0.8273960599468214
</pre>
 
Line 880 ⟶ 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 949 ⟶ 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,072 ⟶ 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,107 ⟶ 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,139 ⟶ 1,859:
24**************** 48072289.9364179447293282 0.0415975491869292 0.16679020D-17 12
25**************** 1201807247.4104485511779785 0.0399387296732302 0.11269608D-17 12
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">' FB 1.05.0 Win64
 
' As FB's native types have only 64 bit precision at most we need to use the
' C library, GMP v6.1.0, for arbitrary precision arithmetic
 
#Include Once "gmp.bi"
mpf_set_default_prec(640) '' 640 bit precision, enough for this exercise
 
Function v(n As UInteger, prev As __mpf_struct, prev2 As __mpf_struct) As __mpf_struct
Dim As __mpf_struct a, b, c
mpf_init(@a) : mpf_init(@b) : mpf_init(@c)
If n = 0 Then mpf_set_ui(@a, 0UL)
If n = 1 Then mpf_set_ui(@a, 2UL)
If n = 2 Then mpf_set_si(@a, -4L)
If n < 3 Then Return a
mpf_ui_div(@a, 1130UL, @prev)
mpf_mul(@b, @prev, @prev2)
mpf_ui_div(@c, 3000UL, @b)
mpf_ui_sub(@b, 111UL, @a)
mpf_add(@a, @b, @c)
mpf_clear(@b)
mpf_clear(@c)
Return a
End Function
 
Function f(a As Double, b As Double) As __mpf_Struct
Dim As __mpf_struct temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8
mpf_init(@temp1) : mpf_init(@temp2) : mpf_init(@temp3) : mpf_init(@temp4)
mpf_init(@temp5) : mpf_init(@temp6) : mpf_init(@temp7) : mpf_init(@temp8)
mpf_set_d(@temp1, a) '' a
mpf_set_d(@temp2, b) '' b
mpf_set_d(@temp3, 333.75) '' 333.75
mpf_pow_ui(@temp4, @temp2, 6UL) '' b ^ 6
mpf_mul(@temp3, @temp3, @temp4) '' 333.75 * b^6
mpf_pow_ui(@temp5, @temp1, 2UL) '' a^2
mpf_pow_ui(@temp6, @temp2, 2UL) '' b^2
mpf_mul_ui(@temp7, @temp5, 11UL) '' 11 * a^2
mpf_mul(@temp7, @temp7, @temp6) '' 11 * a^2 * b^2
mpf_sub(@temp7, @temp7, @temp4) '' 11 * a^2 * b^2 - b^6
mpf_pow_ui(@temp4, @temp2, 4UL) '' b^4
mpf_mul_ui(@temp4, @temp4, 121UL) '' 121 * b^4
mpf_sub(@temp7, @temp7, @temp4) '' 11 * a^2 * b^2 - b^6 - 121 * b^4
mpf_sub_ui(@temp7, @temp7, 2UL) '' 11 * a^2 * b^2 - b^6 - 121 * b^4 - 2
mpf_mul(@temp7, @temp7, @temp5) '' (11 * a^2 * b^2 - b^6 - 121 * b^4 - 2) * a^2
mpf_add(@temp3, @temp3, @temp7) '' 333.75 * b^6 + (11 * a^2 * b^2 - b^6 - 121 * b^4 - 2) * a^2
mpf_set_d(@temp4, 5.5) '' 5.5
mpf_pow_ui(@temp5, @temp2, 8UL) '' b^8
mpf_mul(@temp4, @temp4, @temp5) '' 5.5 * b^8
mpf_add(@temp3, @temp3, @temp4) '' 333.75 * b^6 + (11 * a^2 * b^2 - b^6 - 121 * b^4 - 2) * a^2 + 5.5 * b^8
mpf_mul_ui(@temp4, @temp2, 2UL) '' 2 * b
mpf_div(@temp5, @temp1, @temp4) '' a / (2 * b)
mpf_add(@temp3, @temp3, @temp5) '' 333.75 * b^6 + (11 * a^2 * b^2 - b^6 - 121 * b^4 - 2) * a^2 + 5.5 * b^8 + a / (2 * b)
mpf_clear(@temp1) : mpf_clear(@temp2) : mpf_clear(@temp4) : mpf_clear(@temp5)
mpf_clear(@temp6) : mpf_clear(@temp7) : mpf_clear(@temp8)
Return temp3
End Function
 
Dim As Zstring * 60 z
Dim As __mpf_struct result, prev, prev2
' We cache the two previous results to avoid recursive calls to v
For i As Integer = 1 To 100
result = v(i, prev, prev2)
If (i >= 3 AndAlso i <= 8) OrElse i = 20 OrElse i = 30 OrElse i = 50 OrElse i = 100 Then
gmp_sprintf(@z,"%53.50Ff",@result) '' express result to 50 decimal places
Print "n ="; i , z
End If
prev2 = prev
prev = result
Next
 
mpf_clear(@prev) : mpf_clear(@prev2) '' note : prev = result
 
Dim As __mpf_struct e, balance, ii, temp
mpf_init(@e) : mpf_init(@balance) : mpf_init(@ii) : mpf_init(@temp)
mpf_set_str(@e, "2.71828182845904523536028747135266249775724709369995", 10) '' e to 50 decimal places
mpf_sub_ui(@balance, @e, 1UL)
 
For i As ULong = 1 To 25
mpf_set_ui(@ii, i)
mpf_mul(@temp, @balance, @ii)
mpf_sub_ui(@balance, @temp, 1UL)
Next
 
Print
Print "Chaotic B/S balance after 25 years : ";
gmp_sprintf(@z,"%.16Ff",@balance) '' express balance to 16 decimal places
Print z
mpf_clear(@e) : mpf_clear(@balance) : mpf_clear(@ii) : mpf_clear(@temp)
 
Print
Dim rump As __mpf_struct
rump = f(77617.0, 33096.0)
gmp_sprintf(@z,"%.16Ff", @rump) '' express rump to 16 decimal places
Print "f(77617.0, 33096.0) = "; z
 
Print
Print "Press any key to quit"
Sleep</syntaxhighlight>
 
{{out}}
<pre>
n = 3 18.50000000000000000000000000000000000000000000000000
n = 4 9.37837837837837837837837837837837837837837837837838
n = 5 7.80115273775216138328530259365994236311239193083573
n = 6 7.15441448097524935352789065386036202438123383819727
n = 7 6.80678473692363298394175659627200908762327670780193
n = 8 6.59263276870443839274200277636599482655298231773461
n = 20 6.04355211018926886777747736409754013318771500000612
n = 30 6.00678609303120575853055404795323970583307231443837
n = 50 6.00017584662718718894561402074719546952373517709933
n = 100 6.00000001931947792910408680340358571502435067543695
 
Chaotic B/S balance after 25 years : 0.0399387296732302
 
f(77617.0, 33096.0) = -0.8273960599468214
</pre>
 
=={{header|Fōrmulæ}}==
 
{{FormulaeEntry|page=https://formulae.org/?script=examples/Pathological_floating_point_problems}}
 
'''Solution'''
 
'''Case 1. Introduction example'''
 
[[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,234 ⟶ 2,102:
f64, _ := s.Add(s.Add(s, t3), t4).Float64()
return f64
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,256 ⟶ 2,124:
Task 1 includes an extra step, 200 iterations, to demonstrate a closer convergence.
 
<langsyntaxhighlight lang="unicon">#
# Pathological floating point problems
#
Line 1,343 ⟶ 2,211:
show := 10^4
write("Balance after ", y, " years: $", d * show / scale * 1.0 / show)
end</langsyntaxhighlight>
 
{{out}}
Line 1,389 ⟶ 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,403 ⟶ 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,417 ⟶ 2,285:
30 6.0056486887714203
50 6.0001465345613879
100 6.0000000160995649</langsyntaxhighlight>
 
'''The Chaotic Bank Society'''
Line 1,423 ⟶ 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,433 ⟶ 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 1,458 ⟶ 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 1,475 ⟶ 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 1,505 ⟶ 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.
 
=={{header|Java}}==
Uses BigRational class: [[Arithmetic/Rational/Java]]. For comparison purposes, each task is also implemented with standard 64-bit floating point numbers.
 
<syntaxhighlight lang="java">import java.math.BigDecimal;
import java.math.RoundingMode;
 
public class FPProblems {
public static void wrongConvergence() {
int[] INDEXES = new int[] { 3, 4, 5, 6, 7, 8, 20, 30, 50, 100 };
// Standard 64-bit floating point
double[] fpValues = new double[100];
fpValues[0] = 2.0;
fpValues[1] = -4.0;
for (int i = 2; i < fpValues.length; i++) {
fpValues[i] = 111.0 - 1130.0 / fpValues[i - 1] + 3000.0 / (fpValues[i - 1] * fpValues[i - 2]);
}
// Using rational representation
BigRational[] brValues = new BigRational[100];
brValues[0] = BigRational.valueOf(2);
brValues[1] = BigRational.valueOf(-4);
for (int i = 2; i < brValues.length; i++) {
// Using intermediate values for better readability
BigRational clause2 = BigRational.valueOf(1130).divide(brValues[i - 1]);
BigRational clause3 = BigRational.valueOf(3000).divide(brValues[i - 1].multiply(brValues[i - 2]));
brValues[i] = BigRational.valueOf(111).subtract(clause2).add(clause3);
}
System.out.println("Wrong Convergence Sequence");
for (int n : INDEXES) {
BigDecimal value = brValues[n - 1].toBigDecimal(16, RoundingMode.HALF_UP);
System.out.println(" For index " + n + ", FP value is " + fpValues[n - 1] + ", and rounded BigRational value is " + value.toPlainString());
}
return;
}
public static void chaoticBankSociety() {
System.out.println("Chaotic Bank Society");
double balance = Math.E - 1.0;
// Calculate e using first 1000 terms of the reciprocal of factorials formula
BigRational e = BigRational.ONE;
BigRational d = BigRational.ONE;
for (int i = 1; i < 1000; i++) {
d = d.multiply(BigRational.valueOf(i));
e = e.add(d.reciprocal());
}
System.out.println("DEBUG: e=" + e.toBigDecimal(100, RoundingMode.HALF_UP).toPlainString());
// Alternatively,
// BigRational e = BigRational.valueOf(Math.E);
BigRational brBalance = e.subtract(BigRational.ONE);
for (int year = 1; year <= 25; year++) {
balance = (balance * year) - 1.0;
brBalance = brBalance.multiply(BigRational.valueOf(year)).subtract(BigRational.ONE);
BigDecimal bdValue = brBalance.toBigDecimal(16, RoundingMode.HALF_UP);
System.out.println(" Year=" + year + ", FP balance=" + balance + ", BigRational balance=" + bdValue.toPlainString());
}
}
public static void siegfriedRump() {
System.out.println("Siegfried Rump formula");
double fpValue;
{
double a = 77617.0;
double b = 33096.0;
fpValue = 333.75 * Math.pow(b, 6) + a * a * (11.0 * a * a * b * b - Math.pow(b, 6) - 121.0 * Math.pow(b, 4) - 2.0) + 5.5 * Math.pow(b, 8) + a / (2.0 * b);
}
BigRational brValue;
{
BigRational a = BigRational.valueOf(77617);
BigRational b = BigRational.valueOf(33096);
BigRational clause1 = BigRational.valueOf(333.75).multiply(b.pow(6));
BigRational clause2a = BigRational.valueOf(11).multiply(a).multiply(a).multiply(b).multiply(b);
BigRational clause2b = b.pow(6).add(BigRational.valueOf(121).multiply(b.pow(4))).add(BigRational.valueOf(2));
BigRational clause2 = a.multiply(a).multiply(clause2a.subtract(clause2b));
BigRational clause3 = BigRational.valueOf(5.5).multiply(b.pow(8));
BigRational clause4 = a.divide(b.multiply(BigRational.valueOf(2)));
brValue = clause1.add(clause2).add(clause3).add(clause4);
}
System.out.println(" FP value is " + fpValue);
System.out.println(" BigRational rounded value is " + brValue.toBigDecimal(64, RoundingMode.HALF_UP).toPlainString());
System.out.println(" BigRational full value is " + brValue.toString());
}
public static void main(String... args) {
wrongConvergence();
System.out.println();
chaoticBankSociety();
 
System.out.println();
siegfriedRump();
}
}</syntaxhighlight>
{{out}}
<pre>Wrong Convergence Sequence
For index 3, FP value is 18.5, and rounded BigRational value is 18.50000000000000
For index 4, FP value is 9.378378378378379, and rounded BigRational value is 9.378378378378378
For index 5, FP value is 7.801152737752169, and rounded BigRational value is 7.801152737752161
For index 6, FP value is 7.154414480975333, and rounded BigRational value is 7.154414480975249
For index 7, FP value is 6.806784736924811, and rounded BigRational value is 6.806784736923633
For index 8, FP value is 6.592632768721792, and rounded BigRational value is 6.592632768704438
For index 20, FP value is 98.34950312216536, and rounded BigRational value is 6.043552110189269
For index 30, FP value is 99.99999999999893, and rounded BigRational value is 6.006786093031206
For index 50, FP value is 100.0, and rounded BigRational value is 6.000175846627187
For index 100, FP value is 100.0, and rounded BigRational value is 6.000000019319478
 
Chaotic Bank Society
DEBUG: e=2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427
Year=1, FP balance=0.7182818284590451, BigRational balance=0.7182818284590452
Year=2, FP balance=0.4365636569180902, BigRational balance=0.4365636569180905
Year=3, FP balance=0.30969097075427054, BigRational balance=0.3096909707542714
Year=4, FP balance=0.23876388301708218, BigRational balance=0.2387638830170857
Year=5, FP balance=0.1938194150854109, BigRational balance=0.1938194150854282
Year=6, FP balance=0.16291649051246537, BigRational balance=0.1629164905125695
Year=7, FP balance=0.1404154335872576, BigRational balance=0.1404154335879862
Year=8, FP balance=0.12332346869806088, BigRational balance=0.1233234687038897
Year=9, FP balance=0.1099112182825479, BigRational balance=0.1099112183350075
Year=10, FP balance=0.09911218282547907, BigRational balance=0.09911218335007541
Year=11, FP balance=0.09023401108026974, BigRational balance=0.09023401685082952
Year=12, FP balance=0.08280813296323686, BigRational balance=0.08280820220995428
Year=13, FP balance=0.07650572852207915, BigRational balance=0.07650662872940558
Year=14, FP balance=0.07108019930910814, BigRational balance=0.07109280221167809
Year=15, FP balance=0.06620298963662208, BigRational balance=0.06639203317517140
Year=16, FP balance=0.05924783418595325, BigRational balance=0.06227253080274239
Year=17, FP balance=0.007213181161205284, BigRational balance=0.05863302364662064
Year=18, FP balance=-0.8701627390983049, BigRational balance=0.05539442563917152
Year=19, FP balance=-17.533092042867793, BigRational balance=0.05249408714425881
Year=20, FP balance=-351.66184085735586, BigRational balance=0.04988174288517625
Year=21, FP balance=-7385.898658004473, BigRational balance=0.04751660058870116
Year=22, FP balance=-162490.7704760984, BigRational balance=0.04536521295142560
Year=23, FP balance=-3737288.7209502636, BigRational balance=0.04339989788278872
Year=24, FP balance=-8.969493030280632E7, BigRational balance=0.04159754918692921
Year=25, FP balance=-2.242373258570158E9, BigRational balance=0.03993872967323021
 
Siegfried Rump formula
FP value is -1.1805916207174113E21
BigRational rounded value is -0.8273960599468213681411650954798162919990331157843848199178148417
BigRational full value is -54767/66192</pre>
 
=={{header|jq}}==
Line 1,530 ⟶ 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 1,546 ⟶ 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 1,565 ⟶ 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 1,575 ⟶ 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 1,584 ⟶ 2,598:
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
 
The task could be completed even using ```Rational{BigFloat}``` type.
 
<syntaxhighlight lang ="julia"># arbitraryusing precisionPrintf
# arbitrary precision
setprecision(2000)
 
Line 1,625 ⟶ 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 1,643 ⟶ 2,656:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.0.6
 
import java.math.*
Line 1,684 ⟶ 2,697:
f += c8 * a.pow(2, con480)
println("\nf(77617.0, 33096.0) is ${"%18.16f".format(f)}")
}</langsyntaxhighlight>
 
{{out}}
Line 1,792 ⟶ 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 1,812 ⟶ 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 1,832 ⟶ 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 1,838 ⟶ 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>
 
=={{header|Perl 6}}==
All three tasks can be solved by using either the <code>bigrat</code> or <code>bignum</code> core modules.
{{works with|Rakudo|2016-01}}
Both approaches are used, as demonstration.
The simple solution to doing calculations where floating point numbers exhibit pathological behavior is: don't do floating point calculations. :-) Perl 6 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.
<lang perl6>say '1st:==== Convergent series'; ====
The constants in the equation must be represented with a decimal point (even just <code>111.</code>) so that
my @series = 2.FatRat, -4, { 111 - 1130 / $^v + 3000 / ( $^v * $^u ) } ... *;
they are treated as rationals, not integers.
for flat 3..8, 20, 30, 50, 100 -> $n {say "n = {$n.fmt("%3d")} @series[$n-1]"};
<syntaxhighlight lang="perl">use bigrat;
 
@s = qw(2, -4);
say "\n2nd: Chaotic bank society";
for my $n (2..99) {
sub postfix:<!> (Int $n) { [*] 2..$n } # factorial operator
$s[$n]= 111.0 - 1130.0/$s[-1] + 3000.0/($s[-1]*$s[-2]);
my $years = 25;
}
my $balance = sum map { 1 / FatRat.new($_!) }, 1 .. $years + 15; # Generate e-1 to sufficient precision with a Taylor series
put "Starting balance, \$(e-1): \$$balance";
for 1..$years -> $i { $balance = $i * $balance - 1 }
printf("After year %d, you will have \$%1.16g in your account.\n", $years, $balance);
 
for $n (3..8, 20, 30, 35, 50, 100) {
print "\n3rd: Rump's example: f(77617.0, 33096.0) = ";
($nu,$de) = $s[$n-1] =~ m#^(\d+)/(\d+)#;;
sub f (\a, \b) { 333.75*b⁶ + a²*( 11*a²*b² - b⁶ - 121*b⁴ - 2 ) + 5.5*b⁸ + a/(2*b) }
printf "n = %3d %18.15f\n", $n, $nu/$de;
say f(77617.0, 33096.0).fmt("%0.16g");</lang>
}</syntaxhighlight>
{{Out}}
{{out}}
<pre>1st: Convergent series
<pre>n = 3 18.5500000000000000
n = 4 9.378378378378378378379
n = 5 7.801153801152737752162
n = 6 7.154414154414480975249
n = 7 6.806785806784736923633
n = 8 6.5926328592632768704439
n = 20 6.0435521101892689043552110189269
n = 30 6.006786093031205758530554006786093031206
n = 35 6.002716153954351
n = 50 6.0001758466271871889456140207471954695237
n = 50 6.000175846627188
n = 100 6.000000019319478</pre>
 
==== Chaotic bank society ====
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]]
<syntaxhighlight lang="perl">use bignum qw(bexp);
$e = bexp(1,43);
$years = 25;
$balance = $e - 1;
 
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;</syntaxhighlight>
{{out}}
<pre>Starting balance, $(e-1): $1.718281828459045235360287471352662497757247
After year 25, you will have $0.0399387296732302 in your account.</pre>
 
==== Rump's example ====
<syntaxhighlight 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);</syntaxhighlight>
{{out}}
<pre>-0.8273960599468214</pre>
 
=={{header|Phix}}==
Standard maths with the IEEE-754 hardware floats fails predictably (that code left in as comments), so roll out the bigatoms.<br>
Task1: needs at least 120 decimal places to avoid serious divergance, and 196 to be accurate to 78 digits<br>
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)-->
<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>
<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>
<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>
<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>
<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>
<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>
<span style="color: #000080;font-style:italic;">-- v = append(v,111 - 1130/v[n-1] + 3000/(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>
<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>
<span style="color: #000080;font-style:italic;">-- printf(1,"n = %-3d %20.16f\n", {n, v[n]})</span>
<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>
<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>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<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>
<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(1,"\nTask 2\nBalance after 25 years: $%12.10f", balance)</span>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">33096</span>
<span style="color: #000080;font-style:italic;">--atom pa2 = power(a,2),
-- pb2a211 = 11*pa2*power(b,2),
-- pb4121 = 121*power(b,4),
-- pb6 = power(b,6),
-- pb855 = 5.5*power(b,8),
-- 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})</span>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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}}
<pre>
Task 1
n = 3 18.5
n = 4 9.378378
n = 5 7.801153
n = 6 7.154414
n = 7 6.806785
n = 8 6.5926328
n = 20 6.0435521101892689
n = 30 6.006786093031205758530554
n = 50 6.0001758466271871889456140207471954695237
n = 100 6.000000019319477929104086803403585715024350675436952458072592750856521767230266
 
Task 2
2nd: Chaotic bank society
Balance after 25 years: $0.0399387296732302
Starting balance, $(e-1): $1.7182818284590452353602874713526624977572470936999
After year 25, you will have $0.0399387296732302 in your account.
 
Task 3
3rd: Rump's example: f(77617.0, 33096.0) = -0.827396059946821
f(77617, 33096) = -0.827396059946821
</pre>
 
=== gmp version ===
{{libheader|Phix/mpfr}}
Note that bigatom is formally deprecated in favour of gmp. However there are significant benefits to the
former on this task, being easier to read and debug.<br>
Again, I have left native/hopelessly incorrect versions in as comments for comparison.<br>
Task1: needs at least 120 decimal places to avoid serious divergance, and 196 to be accurate to 78 digits.<br>
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)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<span style="color: #000080;font-style:italic;">-- v = append(v,111 - 1130/v[n-1] + 3000/(v[n-1]*v[n-2]))</span>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<span style="color: #000080;font-style:italic;">-- printf(1,"n = %-3d %20.16f\n", {n, v[n]})</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;">"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>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<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>
<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(1,"\nTask 2\nBalance after 25 years: $%12.10f", balance)</span>
<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>
<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>
<span style="color: #008000;">"95749669676277240766303535475945713821785251664274"</span><span style="color: #0000FF;">)</span>
<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: #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>
<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>
<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>
<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>
<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>
<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>
<span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">33096</span>
<span style="color: #000080;font-style:italic;">--atom pa2 = power(a,2),
-- pb2a211 = 11*pa2*power(b,2),
-- pb4121 = 121*power(b,4),
-- pb6 = power(b,6),
-- pb855 = 5.5*power(b,8),
-- 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})
-- (translation of FreeBASIC)</span>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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}}==
<syntaxhighlight lang="picolisp">(scl 150)
(de task1 (N)
(cache '(NIL) N
(cond
((= N 1) 2.0)
((= N 2) -4.0)
(T
(+
(- 111.0 (*/ 1.0 1130.0 (task1 (- N 1))))
(*/
1.0
3000.0
(*/
(task1 (- N 2))
(task1 (- N 1))
1.0 ) ) ) ) ) ) )
(for N (list 3 4 5 6 7 8 20 30 50 100)
(println 'N: N (round (task1 N) 20)) )
 
# task 2
(setq B (- 2.7182818284590452353602874713526624977572470 1.0))
(for N 25
(setq B
(-
(* N B)
1.0 ) ) )
(prinl "bank balance after 25 years: " (round B 20))
 
# task 3
(de pow (A B) # fixedpoint
(*/ 1.0 (** A B) (** 1.0 B)) )
(de task3 (A B)
(let
(A2 (pow A 2)
B2 (pow B 2)
B4 (pow B 4)
B6 (pow B 6)
B8 (pow B 8) )
(+
(*/ 333.75 B6 1.0)
(*/
A2
(-
(*/ 11.0 A2 B2 (** 1.0 2))
B6
(* 121 B4)
2.0 )
1.0 )
(*/ 5.5 B8 1.0)
(*/ 1.0 A (*/ 2.0 B 1.0)) ) ) )
(prinl "Rump's example: " (round (task3 77617.0 33096.0) 20))</syntaxhighlight>
{{out}}
<pre>
N: 3 "18.50000000000000000000"
N: 4 "9.37837837837837837838"
N: 5 "7.80115273775216138329"
N: 6 "7.15441448097524935353"
N: 7 "6.80678473692363298394"
N: 8 "6.59263276870443839274"
N: 20 "6.04355211018926886778"
N: 30 "6.00678609303120575853"
N: 50 "6.00017584662718718895"
N: 100 "6.00000001931947792910"
bank balance after 25 years: 0.03993872967323020745
Rump's example: -0.82739605994682136814
</pre>
 
Line 1,886 ⟶ 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 1,897 ⟶ 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 1,916 ⟶ 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 1,931 ⟶ 3,397:
return(float(decimal_balance))
 
print("Bank balance after 25 years = ", bank(25))</langsyntaxhighlight>
 
{{Out}}
Line 1,938 ⟶ 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 1,961 ⟶ 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 1,972 ⟶ 3,438:
 
print("rump(77617, 33096) = ", rump(77617.0, 33096.0))
</syntaxhighlight>
</lang>
 
{{Out}}
Line 1,985 ⟶ 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,032 ⟶ 3,498:
(displayln "EXACT (Rational) NUMBERS")
(parameterize ([current-do-exact-calculations? #t])
(all-tests)))</langsyntaxhighlight>
 
{{out}}
Line 2,067 ⟶ 3,533:
TASK 2: balance after 25 years = 0.039938729673230209
TASK 3: f(77617, 33096) = -54767/66192 = -0.827396059946821368</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
{{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" line>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]"};
 
say "\n2nd: Chaotic bank society";
sub postfix:<!> (Int $n) { [*] 2..$n } # factorial operator
my $years = 25;
my $balance = sum map { 1 / FatRat.new($_!) }, 1 .. $years + 15; # Generate e-1 to sufficient precision with a Taylor series
put "Starting balance, \$(e-1): \$$balance";
for 1..$years -> $i { $balance = $i * $balance - 1 }
printf("After year %d, you will have \$%1.16g in your account.\n", $years, $balance);
 
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");</syntaxhighlight>
{{Out}}
<pre>1st: Convergent series
n = 3 18.5
n = 4 9.378378
n = 5 7.801153
n = 6 7.154414
n = 7 6.806785
n = 8 6.5926328
n = 20 6.0435521101892689
n = 30 6.006786093031205758530554
n = 50 6.0001758466271871889456140207471954695237
n = 100 6.000000019319477929104086803403585715024350675436952458072592750856521767230266
 
2nd: Chaotic bank society
Starting balance, $(e-1): $1.7182818284590452353602874713526624977572470936999
After year 25, you will have $0.0399387296732302 in your account.
 
3rd: Rump's example: f(77617.0, 33096.0) = -0.827396059946821
</pre>
 
=={{header|REXX}}==
Line 2,074 ⟶ 3,579:
 
A little extra boilerplate code was added to support the specification of how many decimal digits that should be used for the
<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 seems tomight converge to a wrong limit. */
parse arg digs show . /*obtain optional arguments from the CL*/
if digs=='' | digs=="," then digs=150 150 /*Not specified? Then use the default.*/
if show=='' | show=="," then show= 20 20 /* " " " " " " */
numeric digits digs /*have REXX use "digs" decimal digits. */
#= 2 4 5 6 7 8 9 20 30 50 100 /*the indices to display value of V.n */
fin= word(#, words(#) ) /*find the last (largest) index number.*/
w= length(fin) /* " " length (in dec digs) of FIN.*/
v.1= 2 /*the value of the first V element. */
v.2=-4 /* " " " " second " " */
do n=3 to fin; nm1= n-1; nm2= n-2 /*compute some values of the V elements*/
v.n= 111 - 1130/v.nm1 + 3000/(v.nm1*v.nm2) /* " a value of a " element.*/
if wordpos(n, #)\==0 then say 'v.'left(n, w) "=" format(v /*display digs past the dec.n, ,point───┐ show)*/
if end /*wordpos(n*/, #)\==0 then say 'v.'left(n, w) "=" format(v.n, , /*display SHOW digs past the dec. point*/show)
end /*n*/ /*stick a fork in it, we're all done. */</langsyntaxhighlight>
'''{{out|output''' |text=&nbsp; when using the default inputs:}}
<pre>
v.4 = 9.37837837837837837838
Line 2,106 ⟶ 3,611:
 
===The Chaotic Bank Society===
To be truly accurate, the number of decimal digits for &nbsp; <big> ''' ''e'' ''' </big> &nbsp; (theshould &nbsp;have ''$''as &nbsp;many variabledecimal firstdigits value)as &nbsp;given shouldon have 150 decimalthe
<br>digitscommand &nbsp;line (or whatever isif specified), &nbsp; as per the &nbsp; '''digs''' &nbsp; REXX variable's value, but what's currently coded will suffice for the (default) number of years.
 
<br>for the (default) number of years. &nbsp; However, it makes a difference computing the balance after sixty-five years
However, it makes a difference computing the balance &nbsp; (with 341 decimal digits) &nbsp; after &nbsp; '''183''' &nbsp; years &nbsp; (when at
<br>(when at that point, the balance becomes negative and grows increasing negative fast).
<br>that point, &nbsp; the balance becomes negative and grows increasing negative fast).
<lang rexx>/*REXX pgm (pathological FP problem): the chaotic bank society offering a new investment*/
 
With 150 decimal digits, the balance becomes negative after &nbsp; '''96''' &nbsp; years.
<syntaxhighlight lang="rexx">/*REXX pgm (pathological FP problem): the chaotic bank society offering a new investment*/
e=2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713,
||8217852516642742746639193200305992181741359662904357290033429526059563073813232862794,
||3490763233829880753195251019011573834187930702154089149934884167509244761460668082264,
||8001684774118537423454424371075390777449920695517027618386062613313845830007520449338
d = length(e) - length(.) /*subtract one for the decimal point. */
parse arg digs show y . /*obtain optional arguments from the CL*/
if digs=='' | digs=="," then digs=150 d /*Not specified? Then use the default.*/
if show=='' | show=="," then show= 20 /* " " " " " " */
if y=='' | y=="," then y= 25 /* " " " " " " */
numeric digits digs /*have REXX use "digs" decimal digits. */
$= e - 1 /*subtract $1 from e, that's da deposit*/
$=2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642742746639193200305992181741359662904357290033429526
$=$ - 1 /*and subtract one 'cause that's that. */ /* [↑] 150 decimal digits of e */
/* [↑] value of newly opened account. */
do n=1 for y /*compute the value of the account/year*/
$= $*n - 1 1 /* " " " " " account now.*/
end /*n*/
@baf@@= 'BalanceWith after' d " decimal digits, the balance after " y /*display SHOW' digitsyears pastis: the dec. pt.*/'
say @baf@@ y "years: '$"'format($, , show) / 1 /*stick a fork in it, we're all done. */</langsyntaxhighlight>
'''{{out|output''' |text=&nbsp; when using the default inputs:}}
<pre>
BalanceWith 341 decimal digits, the balance after 25 years is: $0.03993872967323020890399387296732302
</pre>
 
===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 2,141 ⟶ 3,654:
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
f: procedure; parse arg a,b; return a2=a333.75* b*2;*6 + b2=b a**2; * (11* b4=b2a**2;* b6=b4b*b2;*2 - b8=b4 b**26,
return 333.75*b6 + a2*(11*a2*b2 - b6 - 121*b4b**4 - 2) + 5.5*b8b**8 + a / (2*b)</langsyntaxhighlight>
'''{{out|output''' |text=&nbsp; when using the default inputs:}}
<pre>
f(a,b)= -0.82739605994682136814
Line 2,149 ⟶ 3,662:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
# Project : Pathological floating point problems
 
Line 2,162 ⟶ 3,675:
ok
next
</syntaxhighlight>
</lang>
Output:
<pre>
Line 2,180 ⟶ 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 2,186 ⟶ 3,699:
puts "%3d -> %0.16f" % [n, ar[n]]
end
</syntaxhighlight>
</lang>
{{Out}}
<pre> 3 -> 18.5000000000000000
Line 2,201 ⟶ 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 2,211 ⟶ 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>
 
=={{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 2,229 ⟶ 3,743:
[(3..8)..., 20, 30, 50, 100].each {|n|
printf("n = %3d -> %s\n", n, series(n))
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,245 ⟶ 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 2,257 ⟶ 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 2,270 ⟶ 3,784:
=={{header|Stata}}==
'''Task 1'''
<langsyntaxhighlight lang="stata">clear
set obs 100
gen n=_n
Line 2,278 ⟶ 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 2,301 ⟶ 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 2,320 ⟶ 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 2,339 ⟶ 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 2,348 ⟶ 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 2,354 ⟶ 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 2,364 ⟶ 4,004:
u(50) : 100
u(100) : 100
</pre>
 
=={{header|Visual Basic .NET}}==
'''Compiler:''' Roslyn Visual Basic (language version >=15.3, e.g. with Visual Studio 2015)
{{works with|.NET Framework|4.6.2}}
{{works with|.NET Core|2.1}}
{{libheader|BigRationalLibrary|1.0.0}}
 
.NET has three built-in non-integral types, Single, Double, and Decimal.
 
Single and Double are 32-bit and 64-bit IEEE floating-point numbers, respectively, and so are susceptible to the rounding errors that this task is designed to demonstrate.
 
Decimal is a fixed-point number intended for use in financial calculations where a high number of significant digits are required and magnitudes are reasonably small. It has a 128-bit size and is stored as a 1-bit sign, 96-bit integer, and scaling factor (from 1 to 10^28) that determines the position of the decimal point. Decimal math in .NET is notoriously slow.
 
.NET Framework and Core do have the arbitrary-precision BigInteger structure, but do not have an arbitrary-precision rational type, though Microsoft did create a prototype BigRational that never made it into the library. Its source has been released on GitHub and a NuGet package was published for it in 2011 (at [https://www.nuget.org/packages/BigRationalLibrary/]). The type is fully functional and is sufficient for these tasks, so this program has been designed to optionally use it (and must be compiled with a reference to the library to do so).
 
The program defines three compiler constants that toggle:
* <code>USE_BIGRATIONAL</code>: whether to use BigRationalLibrary; when False, a mock type and functions are defined that allows the code to be compiled without a reference to the library.
* <code>BANDED_ROWS</code>: whether to change the console colors to format output tables with alternating white-on-black and black-on-white rows.
* <code>INCREASED_LIMITS</code>: whether to additionally display n = 1000 for Wrong Convergence Sequence and up to year 40 for The Chaotic Bank Society.
 
Because of operator overloading, the implementations are visually very similar. Integral literals are used where possible as they implicitly convert to the other types.
 
The non-floating-point implementations calculate e using the reciprocals of factorials formula because Math.E is a double and is not sufficiently precise.
 
Because BigRational.ToString() returns a string containing its exact numerator and denominator, the BigRational results are converted to Decimal for display.
 
The following sections source code must be located in a single file.
 
Main() procedure and output formatting:
 
<syntaxhighlight lang="vbnet">Imports System.Globalization
Imports System.Numerics
Imports Numerics
 
#Const USE_BIGRATIONAL = True
#Const BANDED_ROWS = True
#Const INCREASED_LIMITS = True
 
#If Not USE_BIGRATIONAL Then
' Mock structure to make test code work.
Structure BigRational
Overrides Function ToString() As String
Return "NOT USING BIGRATIONAL"
End Function
Shared Narrowing Operator CType(value As BigRational) As Decimal
Return -1
End Operator
End Structure
#End If
 
Module Common
Public Const FMT_STR = "{0,4} {1,-15:G9} {2,-24:G17} {3,-32} {4,-32}"
Public ReadOnly Property Headings As String =
String.Format(CultureInfo.InvariantCulture,
FMT_STR,
{"N", "Single", "Double", "Decimal", "BigRational (rounded as decimal)"})
 
<Conditional("BANDED_ROWS")>
Sub SetConsoleFormat(n As Integer)
If n Mod 2 = 0 Then
Console.BackgroundColor = ConsoleColor.Black
Console.ForegroundColor = ConsoleColor.White
Else
Console.BackgroundColor = ConsoleColor.White
Console.ForegroundColor = ConsoleColor.Black
End If
End Sub
 
Function FormatOutput(n As Integer, x As (sn As Single, db As Double, dm As Decimal, br As BigRational)) As String
SetConsoleFormat(n)
Return String.Format(CultureInfo.CurrentCulture, FMT_STR, n, x.sn, x.db, x.dm, CDec(x.br))
End Function
 
Sub Main()
WrongConvergence()
Console.WriteLine()
ChaoticBankSociety()
 
Console.WriteLine()
SiegfriedRump()
 
SetConsoleFormat(0)
End Sub
End Module</syntaxhighlight>
 
<!--Anchors for the C# section to link to-->
==={{anchor|VB.NET Task 1}}Task 1: Converging sequence===
Somewhat predictably, Single fairs the worst and Double slightly better. Decimal lasts past iteration 20, and BigRational remains exactly precise.
 
<syntaxhighlight lang="vbnet">Module Task1
Iterator Function SequenceSingle() As IEnumerable(Of Single)
' n, n-1, and n-2
Dim vn, vn_1, vn_2 As Single
vn_2 = 2
vn_1 = -4
 
Do
Yield vn_2
vn = 111 - (1130 / vn_1) + (3000 / (vn_1 * vn_2))
vn_2 = vn_1
vn_1 = vn
Loop
End Function
 
Iterator Function SequenceDouble() As IEnumerable(Of Double)
' n, n-1, and n-2
Dim vn, vn_1, vn_2 As Double
vn_2 = 2
vn_1 = -4
 
Do
Yield vn_2
vn = 111 - (1130 / vn_1) + (3000 / (vn_1 * vn_2))
vn_2 = vn_1
vn_1 = vn
Loop
End Function
 
Iterator Function SequenceDecimal() As IEnumerable(Of Decimal)
' n, n-1, and n-2
Dim vn, vn_1, vn_2 As Decimal
vn_2 = 2
vn_1 = -4
 
' Use constants to avoid calling the Decimal constructor in the loop.
Const i11 As Decimal = 111
Const i130 As Decimal = 1130
Const E000 As Decimal = 3000
 
Do
Yield vn_2
vn = i11 - (i130 / vn_1) + (E000 / (vn_1 * vn_2))
vn_2 = vn_1
vn_1 = vn
Loop
End Function
 
#If USE_BIGRATIONAL Then
Iterator Function SequenceRational() As IEnumerable(Of BigRational)
' n, n-1, and n-2
Dim vn, vn_1, vn_2 As BigRational
vn_2 = 2
vn_1 = -4
 
' Same reasoning as for Decimal.
Dim i11 As BigRational = 111
Dim i130 As BigRational = 1130
Dim E000 As BigRational = 3000
 
Do
Yield vn_2
vn = i11 - (i130 / vn_1) + (E000 / (vn_1 * vn_2))
vn_2 = vn_1
vn_1 = vn
Loop
End Function
#Else
Iterator Function SequenceRational() As IEnumerable(Of BigRational)
Do
Yield Nothing
Loop
End Function
#End If
 
<Conditional("INCREASED_LIMITS")>
Sub IncreaseMaxN(ByRef arr As Integer())
ReDim Preserve arr(arr.Length)
arr(arr.Length - 1) = 1000
End Sub
 
Sub WrongConvergence()
Console.WriteLine("Wrong Convergence Sequence:")
 
Dim displayedIndices As Integer() = {3, 4, 5, 6, 7, 8, 20, 30, 50, 100}
IncreaseMaxN(displayedIndices)
 
Dim indicesSet As New HashSet(Of Integer)(displayedIndices)
 
Console.WriteLine(Headings)
 
Dim n As Integer = 1
' Enumerate the implementations in parallel as tuples.
For Each x In SequenceSingle().
Zip(SequenceDouble(), Function(sn, db) (sn, db)).
Zip(SequenceDecimal(), Function(a, dm) (a.sn, a.db, dm)).
Zip(SequenceRational(), Function(a, br) (a.sn, a.db, a.dm, br))
If n > displayedIndices.Max() Then Exit For
 
If indicesSet.Contains(n) Then
Console.WriteLine(FormatOutput(n, x))
End If
 
n += 1
Next
End Sub
End Module</syntaxhighlight>
 
{{out}}
Note that "Wrong" is not a heading for the first column--a weird optical effect, that would be.
<pre>Wrong Convergence Sequence:
N Single Double Decimal BigRational (rounded as decimal)
3 18.5 18.5 18.5 18.5
4 9.37837791 9.378378378378379 9.378378378378378378378378378 9.378378378378378378378378378
5 7.80114746 7.8011527377521688 7.80115273775216138328530259 7.8011527377521613832853025937
6 7.15434647 7.1544144809753334 7.154414480975249353527890606 7.1544144809752493535278906539
7 6.80583048 6.8067847369248113 6.806784736923632983941755925 6.8067847369236329839417565963
8 6.57857943 6.592632768721792 6.592632768704438392741992887 6.5926327687044383927420027764
20 100 98.349503122165359 6.04355210719488789087813234 6.0435521101892688677774773641
30 100 99.999999999998934 101.88552052291609961584734802 6.006786093031205758530554048
50 100 100 100.00000000000000000000000068 6.0001758466271871889456140207
100 100 100 100.0 6.0000000193194779291040868034
1000 100 100 100.0 6.0000000000000000000000000000</pre>
 
==={{anchor|VB.NET Task 2}}Task 2: The Chaotic Bank Society===
Decimal appears to be doing well by year 25, but begins to degenerate ''the very next year'' and soon overflows.
 
<syntaxhighlight lang="vbnet">Module Task2
Iterator Function ChaoticBankSocietySingle() As IEnumerable(Of Single)
Dim balance As Single = Math.E - 1
Dim year As Integer = 1
 
Do
balance = (balance * year) - 1
Yield balance
year += 1
Loop
End Function
Iterator Function ChaoticBankSocietyDouble() As IEnumerable(Of Double)
Dim balance As Double = Math.E - 1
Dim year As Integer = 1
 
Do
balance = (balance * year) - 1
Yield balance
year += 1
Loop
End Function
 
Iterator Function ChaoticBankSocietyDecimal() As IEnumerable(Of Decimal)
' 27! is the largest factorial decimal can represent.
Dim balance As Decimal = CalculateEDecimal(27) - Decimal.One
Dim year As Integer = 1
 
Do
balance = (balance * year) - Decimal.One
Yield balance
year += 1
Loop
End Function
 
#If USE_BIGRATIONAL Then
Iterator Function ChaoticBankSocietyRational() As IEnumerable(Of BigRational)
' 100 iterations is precise enough for 25 years.
Dim balance As BigRational = CalculateEBigRational(100) - BigRational.One
Dim year As Integer = 1
 
Do
balance = (balance * year) - BigRational.One
Yield balance
year += 1
Loop
End Function
#Else
Iterator Function ChaoticBankSocietyRational() As IEnumerable(Of BigRational)
Do
Yield Nothing
Loop
End Function
#End If
 
Function CalculateEDecimal(terms As Integer) As Decimal
Dim e As Decimal = 1
Dim fact As Decimal = 1
 
For i As Integer = 1 To terms
fact *= i
e += Decimal.One / fact
Next
 
Return e
End Function
 
#If USE_BIGRATIONAL Then
Function CalculateEBigRational(terms As Integer) As BigRational
Dim e As BigRational = 1
Dim fact As BigInteger = 1
 
For i As Integer = 1 To terms
fact *= i
e += BigRational.Invert(fact)
Next
 
Return e
End Function
#End If
 
<Conditional("INCREASED_LIMITS")>
Sub IncreaseMaxYear(ByRef year As Integer)
year = 40
End Sub
 
Sub ChaoticBankSociety()
Console.WriteLine("Chaotic Bank Society:")
Console.WriteLine(Headings)
 
Dim maxYear As Integer = 25
IncreaseMaxYear(maxYear)
 
Dim i As Integer = 0
For Each x In ChaoticBankSocietySingle().
Zip(ChaoticBankSocietyDouble(), Function(sn, db) (sn, db)).
Zip(ChaoticBankSocietyDecimal(), Function(a, dm) (a.sn, a.db, dm)).
Zip(ChaoticBankSocietyRational(), Function(a, br) (a.sn, a.db, a.dm, br))
If i >= maxYear Then Exit For
Console.WriteLine(FormatOutput(i + 1, x))
i += 1
Next
End Sub
End Module</syntaxhighlight>
 
{{out}}
<pre>Chaotic Bank Society:
N Single Double Decimal BigRational (rounded as decimal)
1 0.718281865 0.71828182845904509 0.7182818284590452353602874714 0.7182818284590452353602874713
2 0.43656373 0.43656365691809018 0.4365636569180904707205749428 0.4365636569180904707205749427
3 0.309691191 0.30969097075427054 0.3096909707542714121617248284 0.3096909707542714121617248281
4 0.238764763 0.23876388301708218 0.2387638830170856486468993136 0.2387638830170856486468993124
5 0.193823814 0.1938194150854109 0.1938194150854282432344965680 0.1938194150854282432344965623
6 0.162942886 0.16291649051246537 0.1629164905125694594069794080 0.1629164905125694594069793739
7 0.140600204 0.14041543358725761 0.1404154335879862158488558560 0.1404154335879862158488556174
8 0.124801636 0.12332346869806088 0.1233234687038897267908468480 0.1233234687038897267908449393
9 0.123214722 0.10991121828254791 0.1099112183350075411176216320 0.1099112183350075411176044541
10 0.232147217 0.099112182825479067 0.0991121833500754111762163200 0.0991121833500754111760445416
11 1.55361938 0.090234011080269738 0.0902340168508295229383795200 0.0902340168508295229364899583
12 17.6434326 0.082808132963236858 0.0828082022099542752605542400 0.0828082022099542752378795006
13 228.364624 0.076505728522079153 0.0765066287294055783872051200 0.0765066287294055780924335089
14 3196.10474 0.071080199309108139 0.0710928022116780974208716800 0.0710928022116780932940691248
15 47940.5703 0.066202989636622078 0.0663920331751714613130752000 0.0663920331751713994110368720
16 767048.125 0.059247834185953252 0.0622725308027433810092032000 0.0622725308027423905765899521
17 13039817 0.0072131811612052843 0.0586330236466374771564544000 0.0586330236466206398020291865
18 234716704 -0.87016273909830488 0.0553944256394745888161792000 0.0553944256391715164365253585
19 4.45961728E+09 -17.533092042867793 0.0524940871500171875074048000 0.0524940871442588122939818127
20 8.91923415E+10 -351.66184085735586 0.0498817430003437501480960000 0.0498817428851762458796362544
21 1.8730392E+12 -7385.898658004473 0.0475166030072187531100160000 0.0475166005887011634723613427
22 4.12068642E+13 -162490.77047609841 0.0453652661588125684203520000 0.0453652129514255963919495414
23 9.47757884E+14 -3737288.7209502636 0.0434011216526890736680960000 0.0433998978827887170148394524
24 2.27461897E+16 -89694930.302806318 0.0416269196645377680343040000 0.0415975491869292083561468582
25 5.68654735E+17 -2242373258.570158 0.0406729916134442008576000000 0.0399387296732302089036714552
26 1.47850229E+19 -58301704723.824112 0.0574977819495492222976000000 0.0384069715039854314954578354
27 3.99195623E+20 -1574146027544.251 0.5524401126378290020352000000 0.0369882306076066503773615576
28 1.11774772E+22 -44076088771240.031 14.468323153859212056985600000 0.0356704570129862105661236148
29 3.24146835E+23 -1278206574365962 418.58137146191714965258240000 0.0344432533766001064175848308
30 9.72440521E+24 -38346197230978864 12556.441143857514489577472000 0.0332976012980031925275449256
31 3.01456563E+26 -1.1887321141603448E+18 389248.67545958294917690163200 0.0322256402380989683538926936
32 9.64661E+27 -3.8039427653131035E+19 12455956.614706654373660852224 0.0312204876191669873245661979
33 3.18338125E+29 -1.2553011125533242E+21 411046567.28531959433080812339 0.0302760914325105817106845313
34 1.08234959E+31 -4.268023782681302E+22 13975583286.700866207247476195 0.0293871087053597781632740646
35 3.78822341E+32 -1.4938083239384556E+24 489145415033.53031725366166682 0.0285488046875922357145922644
36 1.36376043E+34 -5.3777099661784406E+25 17609234941206.091421131820006 0.0277569687533204857253215188
37 5.04591372E+35 -1.989752687486023E+27 651541692824624.38258187734022 0.0270078438728579718368961961
38 1.91744716E+37 -7.5610602124468873E+28 24758584327335725.538111338928 0.0262980671686029298020554545
39 ∞ -2.9488134828542859E+30 965584788766093294.9863422182 0.0256246195755142622801627278
40 ∞ -1.1795253931417144E+32 38623391550643731798.453688728 0.0249847830205704912065091156</pre>
 
==={{anchor|VB.NET Task 3}}Task 3: Rump's example===
Because Decimal is fixed point, the polynomial as displayed in the task cannot be evaluated for the specified input because of intermediate values (b<sup>8</sup>, for instance) being too large.
 
Possibly due to JIT optimizations (''and nasal demons resulting from attempting to ensure that floating-point numbers are (un)equal''), the outputs for Single and Double are identical (both equal to that for Double in debug builds) for optimized (release) builds targeting x86 or AnyCPU-prefer-x86. Since the the machine the author used is x64, the Single was likely stored (with extra precision as the CLR specification allows) in a 64-bit register.
 
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.
 
<syntaxhighlight lang="vbnet">Module Task3
Function SiegfriedRumpSingle(a As Single, b As Single) As Single
Dim a2 = a * a,
b2 = b * b,
b4 = b2 * b2,
b6 = b4 * b2
 
' Non-integral literals must be coerced to Single using the type suffix.
Return 333.75F * b6 +
(a2 * (
11 * a2 * b2 -
b6 -
121 * b4 -
2)) +
5.5F * b4 * b4 +
a / (2 * b)
End Function
 
Function SiegfriedRumpDouble(a As Double, b As Double) As Double
Dim a2 = a * a,
b2 = b * b,
b4 = b2 * b2,
b6 = b4 * b2
 
' Non-integral literals are Doubles by default.
Return 333.75 * b6 +
(a2 * (
11 * a2 * b2 -
b6 -
121 * b4 -
2)) +
5.5 * b4 * b4 +
a / (2 * b)
End Function
 
Function SiegfriedRumpDecimal(a As Decimal, b As Decimal) As Decimal
Dim a2 = a * a,
b2 = b * b,
b4 = b2 * b2,
b6 = b4 * b2
 
' The same applies for Decimal.
Return 333.75D * b6 +
(a2 * (
11 * a2 * b2 -
b6 -
121 * b4 -
2)) +
5.5D * b4 * b4 +
a / (2 * b)
End Function
 
#If USE_BIGRATIONAL Then
Function SiegfriedRumpRational(a As BigRational, b As BigRational) As BigRational
' Use mixed number constructor to maintain exact precision (333+3/4, 5+1/2).
Dim c1 As New BigRational(333, 3, 4)
Dim c2 As New BigRational(5, 1, 2)
 
Dim a2 = a * a,
b2 = b * b,
b4 = b2 * b2,
b6 = b4 * b2
 
Return c1 * b6 +
(a2 * (
11 * a2 * b2 -
b6 -
121 * b4 -
2)) +
c2 * b4 * b4 +
a / (2 * b)
End Function
#Else
Function SiegfriedRumpRational(a As Integer, b As Integer) As BigRational
Return Nothing
End Function
#End If
 
Sub SiegfriedRump()
Console.WriteLine("Siegfried Rump Formula:")
Dim a As Integer = 77617
Dim b As Integer = 33096
 
Console.Write("Single: ")
Dim sn As Single = SiegfriedRumpSingle(a, b)
Console.WriteLine("{0:G9}", sn)
Console.WriteLine()
 
Console.Write("Double: ")
Dim db As Double = SiegfriedRumpDouble(a, b)
Console.WriteLine("{0:G17}", db)
Console.WriteLine()
 
Console.WriteLine("Decimal:")
Dim dm As Decimal
Try
dm = SiegfriedRumpDecimal(a, b)
Catch ex As OverflowException
Console.WriteLine("Exception: " + ex.Message)
End Try
Console.WriteLine($" {dm}")
Console.WriteLine()
 
Console.WriteLine("BigRational:")
Dim br As BigRational = SiegfriedRumpRational(a, b)
Console.WriteLine($" Rounded: {CDec(br)}")
Console.WriteLine($" Exact: {br}")
End Sub
End Module</syntaxhighlight>
 
{{out|note=debug build}}
<pre>Siegfried Rump Formula
Single: -6.27969943E+29
 
Double: -2.3611832414348226E+21
 
Decimal:
Exception: Value was either too large or too small for a Decimal.
0
 
BigRational:
Rounded: -0.8273960599468213681411650955
Exact: -54767/66192</pre>
 
{{out|note=release build}}
<pre>Siegfried Rump Formula:
Single: -2.36118324E+21
 
Double: -2.3611832414348226E+21
 
Decimal:
Exception: Value was either too large or too small for a Decimal.
0
 
BigRational:
Rounded: -0.8273960599468213681411650955
Exact: -54767/66192</pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-big}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "./big" for BigRat
import "./fmt" for Fmt
 
var LIMIT = 100
var bigE = BigRat.fromDecimal("2.71828182845904523536028747135266249775724709369995")
 
// v(n) sequence task
var c1 = BigRat.new(111)
var c2 = BigRat.new(1130)
var c3 = BigRat.new(3000)
var v1 = BigRat.two
var v2 = BigRat.new(-4)
for (i in 3..LIMIT) {
var v3 = c1 - c2/v2 + c3/(v2*v1)
Fmt.print("$3d : $19s", i, v3.toDecimal(16, true, true))
v1 = v2
v2 = v3
}
 
// Chaotic Building Society task
var balance = bigE - 1
for (year in 1..25) balance = balance * year - 1
System.print("\nBalance after 25 years is %(balance.toDecimal(16))")
 
// Siegfried Rump task
var a = BigRat.new(77617)
var b = BigRat.new(33096)
var c4 = BigRat.new(33375, 100)
var c5 = BigRat.new(11)
var c6 = BigRat.new(121)
var c7 = BigRat.new(11, 2)
var f = c4 * b.pow(6) + c7 * b.pow(8) + a/(b*2)
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))")</syntaxhighlight>
 
{{out}}
<pre>
3 : 18.5000000000000000
4 : 9.3783783783783784
5 : 7.8011527377521614
6 : 7.1544144809752494
7 : 6.8067847369236330
8 : 6.5926327687044384
9 : 6.4494659337902880
10 : 6.3484520566543571
11 : 6.2744385982163279
12 : 6.2186957398023978
13 : 6.1758373049212301
14 : 6.1423590812383559
15 : 6.1158830665510808
16 : 6.0947394393336811
17 : 6.0777223048472427
18 : 6.0639403224998088
19 : 6.0527217610161522
20 : 6.0435521101892689
21 : 6.0360318810818568
22 : 6.0298473250239019
23 : 6.0247496523668479
24 : 6.0205399840615161
25 : 6.0170582573289876
26 : 6.0141749145508190
27 : 6.0117845878713337
28 : 6.0098012392984846
29 : 6.0081543789122289
30 : 6.0067860930312058
31 : 6.0056486887714203
32 : 6.0047028131881752
33 : 6.0039159416664605
34 : 6.0032611563057406
35 : 6.0027161539543513
36 : 6.0022624374405593
37 : 6.0018846538818819
38 : 6.0015700517342190
39 : 6.0013080341649643
40 : 6.0010897908901841
41 : 6.0009079941545271
42 : 6.0007565473053508
43 : 6.0006303766028389
44 : 6.0005252586505718
45 : 6.0004376772265183
46 : 6.0003647044182955
47 : 6.0003039018761868
48 : 6.0002532387368678
49 : 6.0002110233741743
50 : 6.0001758466271872
51 : 6.0001465345613879
52 : 6.0001221091522881
53 : 6.0001017555560260
54 : 6.0000847948586303
55 : 6.0000706613835716
56 : 6.0000588837928413
57 : 6.0000490693458029
58 : 6.0000408907870884
59 : 6.0000340754236785
60 : 6.0000283960251310
61 : 6.0000236632422855
62 : 6.0000197192908008
63 : 6.0000164326883272
64 : 6.0000136938694348
65 : 6.0000114115318177
66 : 6.0000095095917616
67 : 6.0000079246472413
68 : 6.0000066038639788
69 : 6.0000055032139253
70 : 6.0000045860073981
71 : 6.0000038216699107
72 : 6.0000031847228971
73 : 6.0000026539343389
74 : 6.0000022116109709
75 : 6.0000018430084630
76 : 6.0000015358399141
77 : 6.0000012798662675
78 : 6.0000010665549954
79 : 6.0000008887956715
80 : 6.0000007406629499
81 : 6.0000006172190487
82 : 6.0000005143491543
83 : 6.0000004286242585
84 : 6.0000003571868566
85 : 6.0000002976556961
86 : 6.0000002480464011
87 : 6.0000002067053257
88 : 6.0000001722544322
89 : 6.0000001435453560
90 : 6.0000001196211272
91 : 6.0000000996842706
92 : 6.0000000830702242
93 : 6.0000000692251858
94 : 6.0000000576876542
95 : 6.0000000480730447
96 : 6.0000000400608703
97 : 6.0000000333840583
98 : 6.0000000278200485
99 : 6.0000000231833736
100 : 6.0000000193194779
 
Balance after 25 years is 0.0399387296732302
 
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 2,390 ⟶ 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 Perl6Raku solution and 12th place from the J solution.
<pre>
1st: Convergent series
Line 2,407 ⟶ 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 2,413 ⟶ 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 2,420 ⟶ 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 2,427 ⟶ 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