Engel expansion: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
(New draft task and Raku example)
 
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(37 intermediate revisions by 9 users not shown)
Line 11:
 
 
Tiny amountamounts of imprecision can cause wild variation from actual values as the (reciprocal) terms grow smaller. It can be quite challenging to maintain precision in later terms.
 
 
Line 43:
 
 
=={{header|RakuJ}}==
<syntaxhighlight lang="j">to_engle=: {{>.@% ({.~ i.&0)<:@(* >.@%)^:(i.30) y}}
<lang perl6>sub to-engel ( $rat ) {
from_engle=: {{+/%*/\y}}</syntaxhighlight>
my $u = $rat;
 
do while $u { my $a = ceiling 1 / $u; $u = $u × $a - 1; $a }
Task examples:<syntaxhighlight lang="j"> to_engle 3.14159265358979
1 1 1 8 8 17 19 300 1991 2767 8641 16313 1628438 7702318 25297938 431350188 765676622 776491263 1739733589 2329473788 6871947674 17179869184
from_engle to_engle 3.14159265358979
3.14159
3.14159265358979-from_engle to_engle 3.14159265358979
0
to_engle 2.71828182845904
1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 17 60 89 126 565 686 1293 7419 13529 59245 65443 133166 225384 655321 656924
from_engle to_engle 2.71828182845904
2.71828
2.71828182845904-from_engle to_engle 2.71828182845904
0
to_engle 1.414213562373095
1 3 5 5 16 18 78 102 120 144 277 286 740 38370 118617 120453 169594 5696244 6316129 10129640 67108864
from_engle to_engle 1.414213562373095
1.41421
1.414213562373095-from_engle to_engle 1.414213562373095
0</syntaxhighlight>
(by default, J displays the first six digits of floating point numbers)
 
Stretch goal (note that we seem to have a problem here with e, presumably because of the limited length of the series):<syntaxhighlight lang="j"> pi175=: (%10x^175)*<.@o.10x^175
e101=: +/ %@!@i. 101x
sq2_179=: (10x^179)%~<.@%:2*10x^2*179
177j175":pi175
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211
103j101":e101
2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642743
180j178":sq2_179
1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927558
to_engle pi175
1 1 1 8 8 17 19 300 1991 2492 7236 10586 34588 63403 70637 1236467 5417668 5515697 5633167 7458122 9637848 9805775 41840855 58408380 213130873 424342175 2366457522 4109464489 21846713216 27803071890 31804388758
to_engle e101
1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
to_engle sq2_179
1 3 5 5 16 18 78 102 120 144 251 363 1402 31169 88630 184655 259252 298770 4196070 38538874 616984563 1975413035 5345718057 27843871197 54516286513 334398528974 445879679626 495957494386 2450869042061 2629541150828 3557465729164
0.0+pi175-from_engle to_engle pi175
8.21074e_177
0.0+e101-from_engle to_engle e101
1.25532e_34
0.0+sq2_179-from_engle to_engle sq2_179
9.66281e_196</syntaxhighlight>
 
=={{header|Julia}}==
<syntaxhighlight lang="julia">tobigrational(s) = (d = length(s) - something(findfirst(==('.'), s), 0); parse(BigInt, replace(s, '.' => "")) // big"10"^d)
 
toEngel(x) = (a = BigInt[]; while x != 0; y = ceil(big"1" // x); push!(a, y); x = x * y - 1; end; a)
 
fromEngel(a) = sum(accumulate((x, y) -> x // y, BigInt.(a)))
 
function testEngels(s)
biginput = length(s) > 21
r = tobigrational(s)
println("\nNumber: $s")
eng = toEngel(r)
println("Engel expansion: ", biginput ? eng[1:min(length(s), 30)] : Int64.(eng), " ($(length(eng)) components)")
r2 = fromEngel(eng)
println("Back to rational: ", biginput ? BigFloat(r2) : Float64(r2))
end
 
setprecision(700)
 
foreach(testEngels, [
"3.14159265358979",
"2.71828182845904",
"1.414213562373095",
"7.59375",
"3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211",
"2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642743",
"1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927558",
"25.628906",
])
</syntaxhighlight>{{out}}
<pre>
Number: 3.14159265358979
Engel expansion: [1, 1, 1, 8, 8, 17, 19, 300, 1991, 2768, 4442, 4830, 10560, 37132, 107315, 244141, 651042, 1953125] (18 components)
Back to rational: 3.14159265358979
 
Number: 2.71828182845904
Engel expansion: [1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 82, 144, 321, 2289, 9041, 21083, 474060, 887785, 976563, 1953125] (27 components)
Back to rational: 2.71828182845904
 
Number: 1.414213562373095
Engel expansion: [1, 3, 5, 5, 16, 18, 78, 102, 120, 144, 260, 968, 18531, 46065, 63005, 65105, 78125] (17 components)
Back to rational: 1.414213562373095
 
Number: 7.59375
Engel expansion: [1, 1, 1, 1, 1, 1, 1, 2, 6, 8] (10 components)
Back to rational: 7.59375
 
Number: 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211
Engel expansion: BigInt[1, 1, 1, 8, 8, 17, 19, 300, 1991, 2492, 7236, 10586, 34588, 63403, 70637, 1236467, 5417668, 5515697, 5633167, 7458122, 9637848, 9805775, 41840855, 58408380, 213130873, 424342175, 2366457522, 4109464489, 21846713216, 27803071890] (231 components)
Back to rational: 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211000000000000000000000000000000000001
 
Number: 2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642743
Engel expansion: BigInt[1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29] (150 components)
Back to rational: 2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003
 
Number: 1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927558
Engel expansion: BigInt[1, 3, 5, 5, 16, 18, 78, 102, 120, 144, 251, 363, 1402, 31169, 88630, 184655, 259252, 298770, 4196070, 38538874, 616984563, 1975413035, 5345718057, 27843871197, 54516286513, 334398528974, 445879679626, 495957494386, 2450869042061, 2629541150527] (185 components)
Back to rational: 1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927558000000000000000000000000000000001
 
Number: 25.628906
Engel expansion: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 33, 33, 35, 58, 62, 521, 3125] (34 components)
Back to rational: 25.628906
</pre>
 
=={{header|Maxima}}==
<syntaxhighlight lang="maxima">
engel_encode(x) := block (
[a:[]],
while(x > 0) do (
ai: ceiling(1/x),
x: x*ai - 1,
a: append(a, [ai])
),
return(a)
);
engel_decode(a) := block (
[x:0, my_product:1],
for ai in a do (
my_product: my_product*ai,
x: x + 1/(my_product)
),
return(x)
);
</syntaxhighlight>
{{out}}
<pre>
engel_encode(3.14159265358979);
[1,1,1,8,8,17,19,300,1991,2767,8641,16313,1628438,7702318,25297938,431350188,765676622,776491263,1739733589,2329473788,6871947674,17179869184]
engel_decode(%);
7074237752028433/2251799813685248
 
engel_encode(2.71828182845904);
[1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,17,60,89,126,565,686,1293,7419,13529,59245,65443,133166,225384,655321,656924,2365071,2618883,5212339,107374183,178956971,536870912]
engel_decode(%);
3060513257434031/1125899906842624
 
engel_encode(1.414213562373095);
[1,3,5,5,16,18,78,102,120,144,277,286,740,38370,118617,120453,169594,5696244,6316129,10129640,67108864]
engel_decode(%);
1592262918131443/1125899906842624
</pre>
 
=={{header|Nim}}==
===Task===
We use the module “rationals” from the standard library which is limited to <code>int64</code> numerators and denominators. We had to define a conversion function from string to Rational as using the provided conversion function from float to Rational gave inaccurate results.
<syntaxhighlight lang="Nim">import std/[math, rationals, strutils]
 
type Fract = Rational[int64]
 
func engel(x: Fract): seq[Natural] =
## Return the Engel expansion of rational "x".
var u = x
while u.num != 0:
let a = ceil(u.den.float / u.num.float).toInt
result.add a
u = u * a - 1
 
func toRational(s: string): Fract =
## Convert the string representation of a real to a rational
## without using an intermediate float representation.
var num = 0i64
var den = 1i64
var i = 0
var c = s[0]
while c != '.':
num = 10 * num + ord(c) - ord('0')
inc i
c = s[i]
inc i
while i < s.len:
num = 10 * num + ord(s[i]) - ord('0')
den *= 10
inc i
result = num // den
 
 
for val in ["3.14159265358979", "2.71828182845904", "1.414213562373095"]:
let e = engel(val.toRational)
echo "Value: ", val
echo "Engel expansion: ", e.join(" ")
echo()
</syntaxhighlight>
 
{{out}}
<pre>Value: 3.14159265358979
Engel expansion: 1 1 1 8 8 17 19 300 1991 2768 4442 4830 10560 37132 107315 244141 651042 1953125
 
Value: 2.71828182845904
Engel expansion: 1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 17 82 144 321 2289 9041 21083 474060 887785 976563 1953125
 
Value: 1.414213562373095
Engel expansion: 1 3 5 5 16 18 78 102 120 144 260 968 18531 46065 63005 65105 78125
</pre>
 
===Stretch task===
{{libheader|bignum}}
The package “bignum” provides a “Rat” type but lacks a function to convert the string representing a real number to a <code>Rat</code>.
<syntaxhighlight lang="Nim">import std/strutils
import bignum
 
func engel(x: Rat): seq[Int] =
## Return the Engel expansion of rational "x".
var u = x
while u.num != 0:
let a = (u.denom + u.num - 1) div u.num
result.add a
u = u * a - 1
 
func toRat(s: string): Rat =
## Convert the string representation of a real to a rational.
var num = newInt(0)
var den = newInt(1)
var i = 0
var c = s[0]
while c != '.':
num = 10 * num + ord(c) - ord('0')
inc i
c = s[i]
inc i
while i < s.len:
num = 10 * num + ord(s[i]) - ord('0')
den *= 10
inc i
result = newRat(num, den)
 
for val in ["3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211",
"2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642743",
"1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927558"]:
let e = engel(val.toRat)
echo "Value: ", val
echo "Engel expansion: ", e[0..29].join(" ")
echo "Number of terms: ", e.len
echo()
</syntaxhighlight>
 
{{out}}
<pre>Value: 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211
Engel expansion: 1 1 1 8 8 17 19 300 1991 2492 7236 10586 34588 63403 70637 1236467 5417668 5515697 5633167 7458122 9637848 9805775 41840855 58408380 213130873 424342175 2366457522 4109464489 21846713216 27803071890
Number of terms: 231
 
Value: 2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642743
Engel expansion: 1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
Number of terms: 150
 
Value: 1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927558
Engel expansion: 1 3 5 5 16 18 78 102 120 144 251 363 1402 31169 88630 184655 259252 298770 4196070 38538874 616984563 1975413035 5345718057 27843871197 54516286513 334398528974 445879679626 495957494386 2450869042061 2629541150527
Number of terms: 185
</pre>
 
=={{header|Perl}}==
{{trans|Raku}}
<syntaxhighlight lang="perl" line>use v5.36;
use bigrat;
use experimental <builtin for_list>;
use List::Util <min product>;
 
sub ceiling ($n) { $n == int $n ? $n : int $n + 1 }
sub abbr ($d) { my $l = length $d; $l < 61 ? $d : substr($d,0,30) . '..' . substr($d,-30) . " ($l digits)" }
 
sub to_engel ($rat) {
my @E;
while ($rat) {
push @E, ceiling 1/$rat;
$rat = $rat*$E[-1] - 1;
}
@E
}
 
sub from_engel (@expanded) {
my @a;
sum( map { push @a, $_; 1/product(@a) } @expanded )
}
 
for my($rat,$p) (
# low precision 𝜋, 𝑒, √2 and 1.5 to powers
3.14159265358979, 15,
2.71828182845904, 15,
1.414213562373095, 16,
1.5**5, 6,
1.5**8, 10,
 
# high precision 𝜋, 𝑒, and √2
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211, 176,
2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642743, 102,
1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927558, 179,
) {
say "Rational number: " . abbr $rat->as_float($p);
my $terms = join ' ', my @expanded = to_engel $rat;
say "Engel expansion: " . (length($terms) > 100 ? $terms =~ s/^(.{90}\S*).*$/$1/r . '... (' . +@expanded . ' terms)' : $terms);
say " Converted back: " . abbr from_engel(@expanded)->as_float($p);
say '';
}</syntaxhighlight>
{{out}}
<pre>Rational number: 3.14159265358979
Engel expansion: 1 1 1 8 8 17 19 300 1991 2768 4442 4830 10560 37132 107315 244141 651042 1953125
Converted back: 3.14159265358979
 
Rational number: 2.71828182845904
Engel expansion: 1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 17 82 144 321 2289 9041 21083 474060 887785 976563 1953125
Converted back: 2.71828182845904
 
Rational number: 1.414213562373095
Engel expansion: 1 3 5 5 16 18 78 102 120 144 260 968 18531 46065 63005 65105 78125
Converted back: 1.414213562373095
 
Rational number: 7.59375
Engel expansion: 1 1 1 1 1 1 1 2 6 8
Converted back: 7.59375
 
Rational number: 25.62890625
Engel expansion: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 4 32
Converted back: 25.62890625
 
Rational number: 3.1415926535897932384626433832..081284811174502841027019385211 (177 digits)
Engel expansion: 1 1 1 8 8 17 19 300 1991 2492 7236 10586 34588 63403 70637 1236467 5417668 5515697 5633167... (231 terms)
Converted back: 3.1415926535897932384626433832..081284811174502841027019385211 (177 digits)
 
Rational number: 2.7182818284590452353602874713..035354759457138217852516642743 (103 digits)
Engel expansion: 1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33... (150 terms)
Converted back: 2.7182818284590452353602874713..035354759457138217852516642743 (103 digits)
 
Rational number: 1.4142135623730950488016887242..999358314132226659275055927558 (180 digits)
Engel expansion: 1 3 5 5 16 18 78 102 120 144 251 363 1402 31169 88630 184655 259252 298770 4196070 38538874... (185 terms)
Converted back: 1.4142135623730950488016887242..999358314132226659275055927558 (180 digits)</pre>
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">include</span> <span style="color: #004080;">mpfr</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #7060A8;">mpfr_set_default_precision</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">134</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- see notes</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">toEngel</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">engel</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #004080;">mpfr</span> <span style="color: #000000;">u</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpfr_init</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpfr_init</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">while</span> <span style="color: #7060A8;">mpfr_cmp_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">u</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">do</span>
<span style="color: #7060A8;">mpfr_si_div</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">u</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">mpfr_ceil</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">engel</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">mpfr_get_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">mpfr_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">u</span><span style="color: #0000FF;">,</span><span style="color: #000000;">u</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">mpfr_sub_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">u</span><span style="color: #0000FF;">,</span><span style="color: #000000;">u</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;">while</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">engel</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">fromEngel</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">engel</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">mpfr</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpfr_init</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">prod</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpfr_init</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">r</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;">e</span> <span style="color: #008080;">in</span> <span style="color: #000000;">engel</span> <span style="color: #008080;">do</span>
<span style="color: #7060A8;">mpfr_set_d</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">,</span><span style="color: #000000;">e</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">mpfr_si_div</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">r</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">mpfr_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">prod</span><span style="color: #0000FF;">,</span><span style="color: #000000;">prod</span><span style="color: #0000FF;">,</span><span style="color: #000000;">r</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">mpfr_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">prod</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">rats</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span>
<span style="color: #008000;">"3.14159265358979"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"2.71828182845904"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"1.414213562373095"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"7.59375"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642743"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"1.414213562373095048801688724209698078569671875376948073176679737990732478462107038850387"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"25.628906"</span>
<span style="color: #0000FF;">}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">rat</span> <span style="color: #008080;">in</span> <span style="color: #000000;">rats</span> <span style="color: #008080;">do</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;">"Rational number : %s\n"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">rat</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">engel</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">toEngel</span><span style="color: #0000FF;">(</span><span style="color: #000000;">rat</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">dix</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'.'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rat</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">places</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">rat</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">dix</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">engel</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">cp</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpfr_get_fixed</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fromEngel</span><span style="color: #0000FF;">(</span><span style="color: #000000;">engel</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">places</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;">places</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">dix</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">rat</span><span style="color: #0000FF;">[</span><span style="color: #000000;">dix</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">dix</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">cp</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</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;">"Engel expansion : %s\n"</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">engel</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #7060A8;">min</span><span style="color: #0000FF;">(</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,</span><span style="color: #000000;">30</span><span style="color: #0000FF;">)],</span><span style="color: #008000;">" "</span><span style="color: #0000FF;">,</span><span style="color: #000000;">fmt</span><span style="color: #0000FF;">:=</span><span style="color: #008000;">"%d"</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;">"Number of terms : %d, places : %d (%d correct)\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,</span><span style="color: #000000;">places</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cp</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;">"Back to rational: %s\n\n"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
I could only get pi accurate to 125 decimal places and root2 to 87, so cut the input strings accordingly.<br>
Increasing the precision helps but only up to a (relatively small) point, ie that 134 ''is'' needed, nowt greater helps at all. <br>
You may or may not have better luck with completely rewriting this to use mpq (rationals).<br>
In fact it works slightly better in a browser (which uses rationals behind the scenes) than on desktop/Phix, as shown below. <br>
<pre>
Rational number : 3.14159265358979
Engel expansion : 1 1 1 8 8 17 19 300 1991 2768 4442 4830 10560 37132 107315 244141 651042 1953125 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647
Number of terms : 83, places : 14 (14 correct)
Back to rational: 3.14159265358979
 
Rational number : 2.71828182845904
Engel expansion : 1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 17 82 144 321 2289 9041 21083 474060 887785 976563 1953125 2147483647 2147483647 2147483647
Number of terms : 101, places : 14 (14 correct)
Back to rational: 2.71828182845904
 
Rational number : 1.414213562373095
Engel expansion : 1 3 5 5 16 18 78 102 120 144 260 968 18531 46065 63005 65105 78125 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647
Number of terms : 67, places : 15 (15 correct)
Back to rational: 1.414213562373095
 
Rational number : 7.59375
Engel expansion : 1 1 1 1 1 1 1 2 6 8
Number of terms : 10, places : 5 (5 correct)
Back to rational: 7.59375
 
Rational number : 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384
Engel expansion : 1 1 1 8 8 17 19 300 1991 2492 7236 10586 34588 63403 70637 1236467 5417668 5515697 5633167 7458122 9637848 9805775 41840855 58408380 213130873 424342175 2147483647 2147483647 2147483647 2147483647
Number of terms : 181, places : 125 (125 correct)
Back to rational: 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384
 
Rational number : 2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642743
Engel expansion : 1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
Number of terms : 222, places : 101 (101 correct)
Back to rational: 2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642743
 
Rational number : 1.414213562373095048801688724209698078569671875376948073176679737990732478462107038850387
Engel expansion : 1 3 5 5 16 18 78 102 120 144 251 363 1402 31169 88630 184655 259252 298770 4196070 38538874 616984563 1975413038 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647 2147483647
Number of terms : 175, places : 87 (87 correct)
Back to rational: 1.414213562373095048801688724209698078569671875376948073176679737990732478462107038850387
 
Rational number : 25.628906
Engel expansion : 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 4 33 33 35
Number of terms : 65, places : 6 (6 correct)
Back to rational: 25.628906
</pre>
Output under p2js:
<pre>
Rational number : 3.14159265358979
Engel expansion : 1 1 1 8 8 17 19 300 1991 2768 4442 4830 10560 37132 107315 244141 651042 1953125
Number of terms : 18, places : 14 (14 correct)
Back to rational: 3.14159265358979
 
Rational number : 2.71828182845904
Engel expansion : 1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 17 82 144 321 2289 9041 21083 474060 887785 976563 1953125
Number of terms : 27, places : 14 (14 correct)
Back to rational: 2.71828182845904
 
Rational number : 1.414213562373095
Engel expansion : 1 3 5 5 16 18 78 102 120 144 260 968 18531 46065 63005 65105 78125
Number of terms : 17, places : 15 (15 correct)
Back to rational: 1.414213562373095
 
Rational number : 7.59375
Engel expansion : 1 1 1 1 1 1 1 2 6 8
Number of terms : 10, places : 5 (5 correct)
Back to rational: 7.59375
 
Rational number : 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384
Engel expansion : 1 1 1 8 8 17 19 300 1991 2492 7236 10586 34588 63403 70637 1236467 5417668 5515697 5633167 7458122 9637848 9805775 41840855 58408380 213130873 424342175 2717375531 323878055376 339280401894 386771504748
Number of terms : 161, places : 125 (125 correct)
Back to rational: 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384
 
Rational number : 2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642743
Engel expansion : 1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
Number of terms : 150, places : 101 (101 correct)
Back to rational: 2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642743
 
Rational number : 1.414213562373095048801688724209698078569671875376948073176679737990732478462107038850387
Engel expansion : 1 3 5 5 16 18 78 102 120 144 251 363 1402 31169 88630 184655 259252 298770 4196070 38538874 616984563 1975413038 7855284583 34680535992 47012263568 82957997141 1709576125547 42630379527673 164312229775505 404736776022426
Number of terms : 110, places : 87 (87 correct)
Back to rational: 1.414213562373095048801688724209698078569671875376948073176679737990732478462107038850387
 
Rational number : 25.628906
Engel expansion : 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 4 33 33 35
Number of terms : 34, places : 6 (6 correct)
Back to rational: 25.628906
</pre>
 
=={{header|Quackery}}==
 
Quackery uses bignum rationals and only generates approximations when the programmer deems it necessary, so loss of precision is not an issue.
 
<syntaxhighlight lang="Quackery"> [ $ "bigrat.qky" loadfile ] now!
 
[ /mod 0 != + ] is ceiling ( n/d --> n )
 
[ [] unrot
[ 2dup 1/v ceiling
dip rot
dup dip
[ join unrot ]
1 v* 1 1 v-
2dup v0= until ]
2drop ] is v->engel ( n/d --> [ )
 
[ 0 1 rot
1 1 rot
witheach
[ n->v v/
2swap 2over v+
2swap ]
2drop ] is engel->v ( [ --> n/d )
 
$ "3.14159265358979 2.71828182845904 1.414213562373095"
nest$
witheach
[ $->v drop
2dup 200 point$ echo$ cr
v->engel
dup witheach [ echo i if sp ] cr
engel->v
200 point$ echo$ cr
cr ]
 
$ "3.1415926535897932384626433832795028841971693993751058"
$ "209749445923078164062862089986280348253421170679821480" join
$ "865132823066470938446095505822317253594081284811174502" join
$ "841027019385211" join
nested
$ "2.7182818284590452353602874713526624977572470936999595"
$ "7496696762772407663035354759457138217852516642743" join
nested join
$ "1.4142135623730950488016887242096980785696718753769480"
$ "731766797379907324784621070388503875343276415727350138" join
$ "462309122970249248360558507372126441214970999358314132" join
$ "226659275055927558" join
nested join
witheach
[ $->v drop
2dup 200 point$ echo$ cr cr
v->engel
dup 30 split drop
witheach [ echo i if sp ]
say "... " cr cr
engel->v
200 point$ echo$ cr cr
cr ]</syntaxhighlight>
 
{{out}}
 
<pre>3.14159265358979
1 1 1 8 8 17 19 300 1991 2768 4442 4830 10560 37132 107315 244141 651042 1953125
3.14159265358979
 
2.71828182845904
1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 17 82 144 321 2289 9041 21083 474060 887785 976563 1953125
2.71828182845904
 
1.414213562373095
1 3 5 5 16 18 78 102 120 144 260 968 18531 46065 63005 65105 78125
1.414213562373095
 
 
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211
 
1 1 1 8 8 17 19 300 1991 2492 7236 10586 34588 63403 70637 1236467 5417668 5515697 5633167 7458122 9637848 9805775 41840855 58408380 213130873 424342175 2366457522 4109464489 21846713216 27803071890...
 
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211
 
 
2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642743
 
1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29...
 
2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642743
 
 
1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927558
 
1 3 5 5 16 18 78 102 120 144 251 363 1402 31169 88630 184655 259252 298770 4196070 38538874 616984563 1975413035 5345718057 27843871197 54516286513 334398528974 445879679626 495957494386 2450869042061 2629541150527...
 
1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927558</pre>
 
=={{header|Raku}}==
<syntaxhighlight lang="raku" line>sub to-engel ($rat is copy) { do while $rat { my $a = ceiling 1 / $rat; $rat = $rat × $a - 1; $a } }
 
sub from-engel (@expanded) { sum [\×] @expanded.map: { FatRat.new: 1, $_ } }
 
for # low precision 𝜋, 𝑒, √2 and 1.5 to a power
for flat
# low precision 𝜋, 𝑒, √2 and 1.5 to a power
3.14159265358979, 2.71828182845904, 1.414213562373095, 1.5 ** 5,
 
Line 67 ⟶ 641:
my @expanded = $rat.&to-engel;
put "Engel expansion: " ~ @expanded.head(30);
say " Converted back to rational: " ~ @expanded.&from-engel;
put '';
}</langsyntaxhighlight>
{{out}}
<pre>Rational number: 3.14159265358979
Engel expansion: 1 1 1 8 8 17 19 300 1991 2768 4442 4830 10560 37132 107315 244141 651042 1953125
Converted back to rational: 3.14159265358979
 
Rational number: 2.71828182845904
Engel expansion: 1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 17 82 144 321 2289 9041 21083 474060 887785 976563 1953125
Converted back to rational: 2.71828182845904
 
Rational number: 1.414213562373095
Engel expansion: 1 3 5 5 16 18 78 102 120 144 260 968 18531 46065 63005 65105 78125
Converted back to rational: 1.414213562373095
 
Rational number: 7.59375
Engel expansion: 1 1 1 1 1 1 1 2 6 8
Converted back to rational: 7.59375
 
Rational number: 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211
Engel expansion: 1 1 1 8 8 17 19 300 1991 2492 7236 10586 34588 63403 70637 1236467 5417668 5515697 5633167 7458122 9637848 9805775 41840855 58408380 213130873 424342175 2366457522 4109464489 21846713216 27803071890
Converted back to rational: 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211
 
Rational number: 2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642743
Engel expansion: 1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
Converted back to rational: 2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642743
 
Rational number: 1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927558
Engel expansion: 1 3 5 5 16 18 78 102 120 144 251 363 1402 31169 88630 184655 259252 298770 4196070 38538874 616984563 1975413035 5345718057 27843871197 54516286513 334398528974 445879679626 495957494386 2450869042061 2629541150527
Converted back to rational: 1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927558
 
Rational number: 25.628906
Engel expansion: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 4 32
Converted back to rational: 25.628906</pre>
 
=={{header|Wren}}==
{{libheader|Wren-big}}
{{libheader|Wren-fmt}}
As in the case of the Raku example, I've limited the display of the Engel expansion to a maximum of 30 terms though I've also shown the total number of terms.
 
However, I've also limited the number of terms accumulated by the 'fromEngel' function to 70 which is just enough to reproduce the high precision rationals in decimal notation. To accumulate all the terms in a reasonable time would require the use of Wren-gmp which I've tried to avoid so the solution will run under Wren-CLI.
<syntaxhighlight lang="wren">import "./big" for BigRat
import "./fmt" for Fmt
 
var toEngel = Fn.new { |x|
var engel = []
var u = BigRat.fromDecimal(x)
while (true) {
var a = u.inverse.ceil
engel.add(a.toBigInt)
u = u * a - BigRat.one
if (u == 0) return engel
}
}
 
var fromEngel = Fn.new { |engel|
var sum = BigRat.zero
var prod = BigRat.one
for (e in engel) {
var r = BigRat.new(e).inverse
prod = prod * r
sum = sum + prod
}
return sum
}
 
var rats = [
"3.14159265358979", "2.71828182845904", "1.414213562373095", "7.59375",
"3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211",
"2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642743",
"1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927558",
"25.628906"
]
for (rat in rats) {
Fmt.print("Rational number : $s", rat)
var dix = rat.indexOf(".") + 1
var places = rat.count - dix
var engel = toEngel.call(rat)
Fmt.print("Engel expansion : $i", engel.take(30).toList)
Fmt.print("Number of terms : $d", engel.count)
Fmt.print("Back to rational: $s\n", fromEngel.call(engel.take(70).toList).toDecimal(places))
}</syntaxhighlight>
 
{{out}}
<pre>
Rational number : 3.14159265358979
Engel expansion : 1 1 1 8 8 17 19 300 1991 2768 4442 4830 10560 37132 107315 244141 651042 1953125
Number of terms : 18
Back to rational: 3.14159265358979
 
Rational number : 2.71828182845904
Engel expansion : 1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 17 82 144 321 2289 9041 21083 474060 887785 976563 1953125
Number of terms : 27
Back to rational: 2.71828182845904
 
Rational number : 1.414213562373095
Engel expansion : 1 3 5 5 16 18 78 102 120 144 260 968 18531 46065 63005 65105 78125
Number of terms : 17
Back to rational: 1.414213562373095
 
Rational number : 7.59375
Engel expansion : 1 1 1 1 1 1 1 2 6 8
Number of terms : 10
Back to rational: 7.59375
 
Rational number : 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211
Engel expansion : 1 1 1 8 8 17 19 300 1991 2492 7236 10586 34588 63403 70637 1236467 5417668 5515697 5633167 7458122 9637848 9805775 41840855 58408380 213130873 424342175 2366457522 4109464489 21846713216 27803071890
Number of terms : 231
Back to rational: 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211
 
Rational number : 2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642743
Engel expansion : 1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
Number of terms : 150
Back to rational: 2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642743
 
Rational number : 1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927558
Engel expansion : 1 3 5 5 16 18 78 102 120 144 251 363 1402 31169 88630 184655 259252 298770 4196070 38538874 616984563 1975413035 5345718057 27843871197 54516286513 334398528974 445879679626 495957494386 2450869042061 2629541150527
Number of terms : 185
Back to rational: 1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927558
 
Rational number : 25.628906
Engel expansion : 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 4 33 33 35
Number of terms : 34
Back to rational: 25.628906
</pre>
9,476

edits