# Golden ratio/Convergence

Golden ratio/Convergence
You are encouraged to solve this task according to the task description, using any language you may know.

The golden ratio can be defined as the continued fraction

${\displaystyle \phi =1+{1 \over {1+{1 \over {1+{1 \over {1+\cdots }}}}}}}$

Thus ${\displaystyle \phi =1+{1/\phi }}$. Multiplying both sides by ${\displaystyle \phi }$ and solving the resulting quadratic equation for its positive solution, one gets ${\displaystyle \phi =(1+{\sqrt {5}})/2\approx 1.61803398875}$.

The golden ratio has the slowest convergence of any continued fraction, as one might guess by noting that the denominators are made of the smallest positive integer. This task treats the problem of convergence in a somewhat backwards fashion: we are going to iterate the recursion ${\displaystyle \phi _{n+1}=1+{1/\phi _{n}}}$, ${\displaystyle \phi _{0}=1}$, and see how long it takes to get an answer.

Iterate ${\displaystyle \phi _{n+1}=1+{1/\phi _{n}}}$, ${\displaystyle \phi _{0}=1}$, until ${\displaystyle |\phi _{n+1}-\phi _{n}|\leq 1\times 10^{-5}}$. Report the final value of ${\displaystyle \phi _{n+1}}$, the number of iterations required, and the error with respect to ${\displaystyle (1+{\sqrt {5}})/2}$.

I used fixed point numbers, to show that in Ada it was no difficulty to do so.

procedure golden_ratio_convergence is

-- This is a fixed-point type. I typed a bunch of "0"
-- without counting them.
type number is delta 0.000000000000001 range -10.0 .. 10.0;

one : constant number := number (1.0);
phi : constant number := number (1.61803398874989484820458683436563811772030917980576286213544862270526046281890244970720720418939113748475); -- OEIS A001622
phi0, phi1 : number;
count : integer;

begin
count := 1;
phi0 := 1.0;
phi1 := (one + (one / phi0));
while abs (phi1 - phi0) > number (1.0e-5) loop
count := count + 1;
phi0 := phi1;
phi1 := (one + (one / phi0));
end loop;
put ("Result:");
put (phi1'image);
put (" after");
put (count'image);
put_line (" iterations");
put ("The error is approximately ");
put_line (number'image (phi1 - phi));
end golden_ratio_convergence;
Output:
Result: 1.618032786885245 after 14 iterations
The error is approximately -0.000001201864649

## ALGOL 60

Translation of: Scheme
Works with: GNU Marst

This program is written in the GNU Marst dialect of Algol 60, which of course differs from the reference language (that is, the standard printed form of it).

(Side note: there is also an Algol 60 implementation as part of Racket, but I have not tried it.)

procedure iterate (phi0, n0, phi, n);
value phi0, n0;
real phi0, phi;
integer n0, n;
begin
phi := 1.0 + (1.0 / phi0);
n := n0 + 1;
if 100000.0 * abs (phi - phi0) > 1.0 then
iterate (phi, n, phi, n)
end iterate;

begin
real phi;
integer n;

iterate (1.0, 0, phi, n);
outstring (1, "Result: ");
outreal (1, phi);
outstring (1, "after ");
outinteger (1, n);
outstring (1, "iterations\n");
outstring (1, "The error is approximately ");
outreal (1, phi - (0.5 * (1.0 + sqrt (5.0))));
outstring (1, "\n")
end
Output:
Result: 1.61803278689 after 14 iterations
The error is approximately -1.20186464914e-06

## ALGOL 68

Translation of: RATFOR

...but basically similar to many of the other samples, e.g. the Wren sample.

BEGIN # calculate the Golden Ratio and show the number of iterations required #

INT  count := 0;
REAL phi0  := 1, diff := 1e20;

WHILE 1e-5 < diff DO
REAL phi1 = 1.0 + ( 1.0 / phi0 );
diff     := ABS ( phi1 - phi0 );
phi0     := phi1;
count   +:= 1
OD;

print( ( "Result:", fixed( phi0, -9, 6 ), " after ", whole( count, 0 ), " iterations", newline ) );
print( ( "The error is approximately ", fixed( phi0 - ( 0.5 * ( 1 + sqrt( 5 ) ) ), -9, 6 ), newline ) )

END
Output:
Result: 1.618033 after 14 iterations
The error is approximately -0.000001

## ALGOL W

Translation of: RATFOR
begin % calculate the Golden Ratio and show the number of iterations required %

integer count;
real    phi0, diff;

count := 0;
phi0  := 1;
diff  := 1'20;

while 1'-5 < diff do begin
real phi1;
phi1  := 1.0 + ( 1.0 / phi0 );
diff  := abs( phi1 - phi0 );
phi0  := phi1;
count := count + 1
end while_1e_5_lt_diff ;

write( i_w := 1, s_w := 0, "Result:", phi0, " after ", count, " iterations" );
write( i_w := 1, s_w := 0, "The error is approximately ", phi0 - ( 0.5 * ( 1 + sqrt( 5 ) ) ) )

end.
Output:
Result: 1.6180327'+00 after 14 iterations
The error is approximately -1.2018646'-06

## ATS

%{^
#include <math.h>
%}

extern fn sqrt : double -<> double = "mac#sqrt"

fun
iterate {n   : nat}
(phi : double,
n   : int n) : @(double, intGte 1) =
let
val phi1 = 1.0 + (1.0 / phi)
and n1 = succ n
in
if abs (phi1 - phi) <= 1.0e-5 then
@(phi1, n1)
else
iterate {n + 1} (phi1, n1)
end

implement
main0 () =
let
val @(phi, n) = iterate {0} (1.0, 0)
val _ = $extfcall (int, "printf", "Result: %.10f after %d iterations\n", phi, n) val _ =$extfcall (int, "printf",
"The error is approximately %.10f\n",
phi - (0.5 * (1.0 + sqrt (5.0))))
in
end
Output:
Result: 1.6180327869 after 14 iterations
The error is approximately -0.0000012019

## BASIC

### Applesoft BASIC

The GW-BASIC solution works without any changes.

### Bas

Translation of: C
Works with: Bas version 2.4

Although bas does not require it, it is purposely made to support it: this program is written in BASIC such as we used to write decades ago.

100 I = 0
110 P0 = 1.0
120 P1 = 1.0 + (1.0 / P0)
130 D = ABS (P1 - P0)
140 P0 = P1
150 I = I + 1
160 IF 1.0E-5 < D THEN 120
170 PRINT "RESULT:" P1 "AFTER" I "ITERATIONS"
180 E = P1 - (0.5 * (1.0 + SQR (5.0)))
190 PRINT "THE ERROR IS APPROXIMATELY " E
Output:
RESULT: 1.618033 AFTER 14 ITERATIONS
THE ERROR IS APPROXIMATELY -1.201865e-06

### BASIC256

Translation of: FreeBASIC
call iterate()
end

subroutine iterate()
iter = 0
phi0 = 1.0
do
phi1 = 1.0 + (1.0 / phi0)
diferencia = abs(phi1 - phi0)
phi0 = phi1
iter += 1
until (1.0e-5 > diferencia)

print "Result: "; phi1; " after "; iter; " iterations"
print "The error is approximately "; phi1 - (0.5 * (1.0 + sqrt(5.0)))
end subroutine
Output:
Result: 1.61803278689 after 14 iterations
The error is approximately -0.00000120186

### Chipmunk Basic

Works with: Chipmunk Basic version 3.6.4
Translation of: FreeBASIC
100 iterate
110 end
120 sub iterate()
130 iter = 0
140 phi0 = 1
150 do
160  phi1 = 1+(1/phi0)
170  diff = abs(phi1-phi0)
180  phi0 = phi1
190  iter = iter+1
200 loop until (1.000000E-05 > diff)
210 print "Result: ";phi1;" after ";iter;" iterations"
220 print "The error is approximately ";phi1-(0.5*(1+sqr(5)))
230 end sub
Output:
Result: 1.618033  after 14  iterations
The error is approximately -1.201865E-06

### Craft Basic

precision 6

define i = 0, d = 0, phi0 = 1, phi1 = 0

do

let phi1 = 1 / phi0 + 1
let d = abs(phi1 - phi0)
let phi0 = phi1
let i = i + 1

wait

loopuntil .00001 > d

print "result: ", phi1, " after ", i, " iterations"
print "the error is approximately ", phi1 - (.5 * (1 + sqrt(5)))
Output:
result: 1.618033 after 14 iterations
the error is approximately -0.000001

### FreeBASIC

Translation of: C
Sub using_Single
Dim As Integer iter = 0
Dim As Single phi0 = 1.0f
Dim As Single phi1
Dim As Single diferencia
Do
phi1 = 1.0f + (1.0f / phi0)
diferencia = Abs(phi1 - phi0)
phi0 = phi1
iter += 1
Loop While (1.0e-5f < diferencia)

Print "Using type Single --"
Print Using "Result: #.########## after ## iterations"; phi1; iter
Print Using "The error is approximately #.##########"; phi1 - (0.5f * (1.0f + Sqr(5.0f)))
End Sub

Sub using_Double
Dim As Integer iter = 0
Dim As Double phi0 = 1.0
Dim As Double phi1
Dim As Double diferencia
Do
phi1 = 1.0 + (1.0 / phi0)
diferencia = Abs(phi1 - phi0)
phi0 = phi1
iter += 1
Loop While (1.0e-5 < diferencia)

Print "Using type Double --"
Print Using "Result: #.########## after ## iterations"; phi1; iter
Print Using "The error is approximately #.##########"; phi1 - (0.5 * (1.0 + Sqr(5.0)))
End Sub

using_Single
Print
using_Double

Sleep
Output:
Using type Single --
Result: 1.6180328131 after 14 iterations
The error is approximately -.0000011921

Using type Double --
Result: 1.6180327869 after 14 iterations
The error is approximately -.0000012019

### Gambas

Translation of: FreeBASIC
Public Sub Main()

using_Single
Print
using_Float

End

Sub using_Single()

Dim iter As Integer = 0
Dim phi0 As Single = 1.0
Dim phi1 As Single
Dim diferencia As Single

Do
phi1 = 1.0 + (1.0 / phi0)
diferencia = Abs(phi1 - phi0)
phi0 = phi1
iter += 1
Loop While (1.0e-5 < diferencia)

Print "Using type Single --"
Print "Result: "; Format$(phi1, "#.##########"); " after "; iter; " iterations" Print "The error is approximately "; Format$(phi1 - (0.5 * (1.0 + Sqr(5.0))), "#.##########")

End Sub

Sub using_Float()

Dim iter As Integer = 0
Dim phi0 As Float = 1.0
Dim phi1 As Float
Dim diferencia As Float

Do
phi1 = 1.0 + (1.0 / phi0)
diferencia = Abs(phi1 - phi0)
phi0 = phi1
iter += 1
Loop While (1.0e-5 < diferencia)

Print "Using type Float --"
Print "Result: "; Format$(phi1, "#.##########"); " after "; iter; " iterations" Print "The error is approximately "; Format$(phi1 - (0.5 * (1.0 + Sqr(5.0))), "#.##########")

End Sub
Output:
Using type Single --
Result: 1,6180328131 after 14 iterations
The error is approximately -0,0000011757

Using type Float --
Result: 1,6180327869 after 14 iterations
The error is approximately -0,0000012019

### GW-BASIC

Works with: Applesoft BASIC
Works with: Chipmunk Basic
Works with: PC-BASIC version any
Works with: QBasic
Works with: Quite BASIC
Works with: MSX BASIC version any
Translation of: BASIC256
100 CLS : rem  100 HOME for Applesoft BASIC : DELETE for Minimal BASIC
110 LET I = 0
120 LET P0 = 1
130 LET P1 = 1+(1/P0)
140 LET D = ABS(P1-P0)
150 LET P0 = P1
160 LET I = I+1
170 IF .00001 < D THEN 130
180 PRINT "Result: ";P1;" after ";I;" iterations"
190 PRINT "The error is approximately ";P1-(.5*(1+SQR(5)))
200 END

### Minimal BASIC

The GW-BASIC solution works without any changes.

### MSX Basic

The GW-BASIC solution works without any changes.

### PureBasic

Translation of: FreeBASIC
Procedure using_Float()
Define iter.i = 0
Define.f phi0 = 1.0, phi1, diff
Repeat
phi1 = 1.0 + (1.0 / phi0)
diff = Abs(phi1 - phi0)
phi0 = phi1
iter + 1
Until (1.0e-5 > diff)

PrintN("Using type Float --")
PrintN("Result: " + FormatNumber((phi1), 10) + " after " + Str(iter) + " iterations")
PrintN("The error is approximately " + FormatNumber((phi1 - (0.5 * (1.0 + Sqr(5.0)))), 10))
EndProcedure

Procedure using_Double()
Define iter.i = 0
Define.d phi0 = 1.0, phi1, diff
Repeat
phi1 = 1.0 + (1.0 / phi0)
diff = Abs(phi1 - phi0)
phi0 = phi1
iter + 1
Until (1.0e-5 > diff)

PrintN("Using type Double --")
PrintN("Result: " + FormatNumber((phi1), 10) + " after " + Str(iter) + " iterations")
PrintN("The error is approximately " + FormatNumber((phi1 - (0.5 * (1.0 + Sqr(5.0)))), 10))
EndProcedure

OpenConsole()
using_Float()
PrintN("")
using_Double()
Input()
CloseConsole()
Output:
Using type Float --
Result: 1.6180328131 after 14 iterations
The error is approximately -0.0000011757

Using type Double --
Result: 1.6180327869 after 14 iterations
The error is approximately -0.0000012019

### QBasic

Works with: QBasic version 1.1
Works with: QuickBasic version 4.5
Translation of: BASIC256
SUB iterate
iter = 0
phi0 = 1!
DO
phi1 = 1! + (1! / phi0)
diff = ABS(phi1 - phi0)
phi0 = phi1
iter = iter + 1
LOOP UNTIL (.00001 > diff)

PRINT "Result: "; phi1; " after "; iter; " iterations"
PRINT "The error is approximately "; phi1 - (.5 * (1! + SQR(5!)))
END SUB

CALL iterate
END
Output:
Result:  1.618033  after  14  iterations
The error is approximately -1.175678E-06

### Quite BASIC

The GW-BASIC solution works without any changes.

### True BASIC

Translation of: QBasic
SUB iterate
LET iter = 0
LET phi0 = 1
DO
LET phi1 = 1+(1/phi0)
LET diff = abs(phi1-phi0)
LET phi0 = phi1
LET iter = iter+1
LOOP until (.00001 > diff)
PRINT "Result: "; phi1; " after "; iter; " iterations"
PRINT "The error is approximately "; phi1-(.5*(1+sqr(5)))
END SUB

CALL iterate
END

### Yabasic

Translation of: FreeBASIC
iterate()
end

sub iterate()
iter = 0
phi0 = 1.0
repeat
phi1 = 1.0 + (1.0 / phi0)
diferencia = abs(phi1 - phi0)
phi0 = phi1
iter = iter + 1
until (1.0e-5 > diferencia)

print "Result: ", phi1, " after ", iter, " iterations"
e$= str$(phi1 - (0.5 * (1.0 + sqrt(5.0))), "%2.10f")
print "The error is approximately ", e$end sub Output: Result: 1.61803 after 14 iterations The error is approximately -0.0000012019 ## C #include <stdio.h> #include <math.h> static void using_float () /* C2x does not require "void". */ { int count = 0; float phi0 = 1.0f; float phi1; float difference; do { phi1 = 1.0f + (1.0f / phi0); difference = fabsf (phi1 - phi0); phi0 = phi1; count += 1; } while (1.0e-5f < difference); printf ("Using type float --\n"); printf ("Result: %f after %d iterations\n", phi1, count); printf ("The error is approximately %f\n", phi1 - (0.5f * (1.0f + sqrtf (5.0f)))); } static void using_double () /* C2x does not require "void". */ { int count = 0; double phi0 = 1.0; double phi1; double difference; do { phi1 = 1.0 + (1.0 / phi0); difference = fabs (phi1 - phi0); phi0 = phi1; count += 1; } while (1.0e-5 < difference); printf ("Using type double --\n"); printf ("Result: %f after %d iterations\n", phi1, count); printf ("The error is approximately %f\n", phi1 - (0.5 * (1.0 + sqrt (5.0)))); } int main () /* C2x does not require "void". */ { using_float (); printf ("\n"); using_double (); } Output: Using type float -- Result: 1.618033 after 14 iterations The error is approximately -0.000001 Using type double -- Result: 1.618033 after 14 iterations The error is approximately -0.000001 ## C# Translation of: Java using System; public class GoldenRatio { static void Iterate() { double oldPhi = 1.0, phi = 1.0, limit = 1e-5; int iters = 0; while (true) { phi = 1.0 + 1.0 / oldPhi; iters++; if (Math.Abs(phi - oldPhi) <= limit) break; oldPhi = phi; } Console.WriteLine($"Final value of phi : {phi:0.00000000000000}");
double actualPhi = (1.0 + Math.Sqrt(5.0)) / 2.0;
Console.WriteLine($"Number of iterations : {iters}"); Console.WriteLine($"Error (approx) : {phi - actualPhi:0.00000000000000}");
}

public static void Main(string[] args) {
Iterate();
}
}
Output:
Final value of phi : 1.61803278688525
Number of iterations : 14
Error (approx) : -0.00000120186465

## C++

Translation of: Wren
#include <iostream>
#include <cmath>
#include <iomanip>

using namespace std;

int main() {
double oldPhi = 1.0, phi = 1.0, limit = 1e-5;
int iters = 0;
while (true) {
phi = 1.0 + 1.0 / oldPhi;
iters++;
if (abs(phi - oldPhi) <= limit) break;
oldPhi = phi;
}
cout.setf(ios::fixed);
cout << "Final value of phi : " << setprecision(14) << phi << endl;
double actualPhi = (1.0 + sqrt(5.0)) / 2.0;
cout << "Number of iterations : "<< iters << endl;
cout << "Error (approx) : " << setprecision(14) << phi - actualPhi << endl;
return 0;
}
Output:
Final value of phi : 1.61803278688525
Number of iterations : 14
Error (approx) : -0.00000120186465

## COBOL

Translation of: Bas
Works with: GnuCOBOL version 3.1.2.0

I decided to see what a conditional GOTO looks like in COBOL. As long as I was doing that, I also used uppercase.

The arithmetic is done in decimal fixed-point.

*> -*- mode: cobol -*-
IDENTIFICATION DIVISION.
PROGRAM-ID. GOLDEN_RATIO_CONVERGENCE.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 PHI0 PIC 9(1)V9(12).
01 PHI1 PIC 9(1)V9(12).
01 DIFF PIC S9(1)V9(12).
01 ERR PIC S9(1)V9(12).
01 NOMINAL-VALUE PIC 9(1)V9(12).
01 ITER PIC 9(2).

PROCEDURE DIVISION.
MOVE 0 TO ITER
MOVE 1.0 TO PHI0.
LOOP.
COMPUTE PHI1 = 1.0 + (1.0 / PHI0)
COMPUTE DIFF = FUNCTION ABS (PHI1 - PHI0)
MOVE PHI1 TO PHI0
IF 100000 * DIFF > 1.0
GO TO LOOP
END-IF
DISPLAY 'RESULT: ' PHI1 ' AFTER ' ITER ' ITERATIONS'
MOVE 1.61803398874989 TO NOMINAL-VALUE
COMPUTE ERR = PHI1 - NOMINAL-VALUE
DISPLAY 'THE ERROR IS APPROXIMATELY ' ERR.
Output:
RESULT: 1.618032786885 AFTER 14 ITERATIONS
THE ERROR IS APPROXIMATELY -0.000001201864

## Common Lisp

Translation of: Scheme

Note that, although standard Scheme guarantees a tail recursion will act like a GOTO rather than an ordinary subroutine call, Common Lisp does not. Therefore this implementation, translated from the Scheme, may require stack space. The amount will be very little.

(You could use this recursive method in C and many other languages where tail recursions are not guaranteed to be "proper". The compiler's optimizer may or may not turn the tail call into a GOTO.)

(defun iterate (phi n)
;; This is a tail recursive definition, copied from the
;; Scheme. Common Lisp does not guarantee proper tail calls, but the
;; depth of recursion will not be too great.
(let ((phi1 (1+ (/ phi)))
(n1 (1+ n)))
(if (<= (abs (- phi1 phi)) 1/100000)
(values phi1 n1)
(iterate phi1 n1))))

(multiple-value-bind (phi n) (iterate 1 0)
(princ "Result: ")
(princ phi)
(princ " (")
(princ (* 1.0 phi))
(princ ") after ")
(princ n)
(princ " iterations")
(terpri)
(princ "The error is approximately ")
(princ (- phi (* 0.5 (+ 1.0 (sqrt 5.0)))))
(terpri))
Output:
Result: 987/610 (1.6180328) after 14 iterations
The error is approximately -1.1920929e-6

## Dart

Translation of: C
import 'dart:math';

void iterate() {
int count = 0;
double phi0 = 1.0;
double phi1;
double difference;
do {
phi1 = 1.0 + (1.0 / phi0);
difference = (phi1 - phi0).abs();
phi0 = phi1;
count += 1;
} while (1.0e-5 < difference);

print("Result: $phi1 after$count iterations");
print("The error is approximately ${phi1 - (0.5 * (1.0 + sqrt(5.0)))}"); } void main() { iterate(); } Output: Result: 1.6180327868852458 after 14 iterations The error is approximately -0.0000012018646491362972 ## EasyLang phi0 = 1 repeat phi = 1 + 1 / phi0 until abs (phi - phi0) < 1e-5 phi0 = phi iter += 1 . numfmt 10 0 print "Iterations: " & iter print "Result: " & phi print "Error: " & phi - (1 + sqrt 5) / 2 ## EDSAC order code By working with 1 - phi_n instead of phi_n, we bring the values into the EDSAC range [-1,1) without a change of scale. [GoldenRatio/Convergence for Rosetta Code. EDSAC program, Initial Orders 2] [----------------------------------------------------------------- Given phi_n as in the task description, let u_n = 1 - phi_n. Then u_0 = 0 and the recurrence is u_(n+1) = 1/(u_n - 1). To keep the arguments of the division subroutine D6 within range, the recurrence is calculated as u_(n+1) = (1/4)/(u_n/4 - 1/4). -----------------------------------------------------------------] [Arrange the storage] T47K P300F [M parameter: main routine] T48K P56F [& (Delta) parameter: library s/r D6 (division)] T49K P92F [L parameter: library s/r P1 (prints real)] T50K P200F [X parameter: library s/r P7 (prints integer)] [-------------------------------------------------------------------------- Library subroutine R2, reads values as positive integers at load time, and is then overwritten.] GKT20FVDL8FA40DUDTFI40FA40FS39FG@S2FG23FA5@T5@E4@E13Z T#M [tell R2 where to store values] [Values when interpreted as reals are 1/4, 0.00001, -0.6180339887] 4294967296F171799F23741995290#TZ [-------------------------------------------------------------------------- [Library subroutine M3, prints header at load time, and is then overwritten. Here, last character sets teleprinter to figures.] PFGKIFAFRDLFUFOFE@A6FG@E8FEZPF *AIMING!AT!#1!A!*PHI@&ITERATIONS!!!FINAL!VALUE!!!!!ABS!ERROR@&#.. PK [after header, blank tape and PK (WWG, 1951, page 91)] [-------------------------------------------------------------------------- M parameter: Main routine] E25K TM GK [Constants read in by R2 are stored here] [0] [1/4] [2] [0.00001, test for convergence] [4] [limit as adapted for EDSAC, (1 - sqrt(5))/2 = -0.618...] T6Z [don't overwrite constants: load from relative location 6] [6] PF PF [current term] [8] PF PF [previous term] [10] PF [number of iterations, right justified] [11] PD [17-bit constant 1] [Enter here with acc = 0] [12] T6#@ [u_0 := 0] T10@ [count of iterations := 0] [Loop to get next term] [14] TF [clear acc] A10@ A11@ T10@ [inc number of iterations] A#@ TD [0D := 1/4 for division subroutine] A6#@ U8#@ [previous term := current term u_n] R1F [shift 2 right, acc := u_n/4] S#@ T4D [4D := u_n/4 - 1/4 for division subroutine] A25@ G& [call dvision s/r, 0D := u_(n+1)] AD U6#@ [store u_(n+1)] S8#@ E33@ [acc := u_(n+1) - u_n, skip if >= 0] T4D S4D [else negate to get absolute difference] [33] S2#@ [test for convergence] E14@ [loop back if not converged] [Here when converged] TF TD [clear acc and whole of 0D (including sandwich bit)] A10@ TF [0D := count of iterations, extended to 35 bits] A39@ GX O79@ [print count and space] A6#@ TD [final value to 0D for printing] A44@ G59@ O79@ [print value and space] A4#@ S6#@ E52@ [acc := error, skip if >= 0] TD SD [else negate to get absolute value] [52] TD [absolute error to 0D for printing] A53@ G59@ O80@ O81@ [print error and new line] O82@ [print null to flush teleprinter buffer] ZF [halt machine] [---------------------------------------------------------------------------- Wrapper for library subroutine P1. Adds '0.' before the decimal part, preceded by space or minus sign.] [59] A3F T76@ [plant return link as usual] [61] AD G65@ [acc := number to print; jump if < 0] O79@ E68@ [write space, join common code] [65] TD SD [acc := number negated] O61@ [write minus sign] [68] YF YF [rounding: add 2^-34, nearest possible to 0.5*(10^-10)] O77@ O78@ [print '0.'] TD [pass value to print subroutine] A73@ GL P10F [call P1, print 10 decimals] [76] ZF [(planted) jump back to caller] [77] PF [digit '0' in figures mode] [78] MF [full stop, here used for decimal point] [79] !F [space] [80] @F [carriage return] [81] &F [line feed] [82] K4096F [null char] [-------------------------------------------------------------------------- Library subroutine P1: prints non-negative fraction in 0D, without '0.'] E25K TL GKA18@U17@S20@T5@H19@PFT5@VDUFOFFFSFL4FTDA5@A2FG6@EFU3FJFM1F [-------------------------------------------------------------------------- Library subroutine P7, prints long strictly positive integer; 10 characters, right justified, padded left with spaces. Even address; 35 storage locations; working position 4D.] E25K TX GKA3FT26@H28#@NDYFLDT4DS27@TFH8@S8@T1FV4DAFG31@SFLDUFOFFFSF L4FT4DA1FA27@G11@XFT28#ZPFT27ZP1024FP610D@524D!FO30@SFL8FE22@ [-------------------------------------------------------------------------- Library subroutine D6: Division, accurate, fast. 0D := 0D/4D, where 4D <> 0, -1. 36 locations, working positons 6D and 8D.] E25K T& GKA3FT34@S4DE13@T4DSDTDE2@T4DADLDTDA4DLDE8@RDU4DLD A35@T6DE25@U8DN8DA6DT6DH6DS6DN4DA4DYFG21@SDVDTDEFW1526D [-------------------------------------------------------------------------- M parameter again: define entry point] E25K TM GK E12Z PF [enter with acc = 0] Output: AIMING AT 1 - PHI ITERATIONS FINAL VALUE ABS ERROR 14 -0.6180327869 0.0000012019 ## Fortran ### Fortran77 Translation of: Bas Not only did I use FORTRAN 77, but I used all uppercase and made sure to use an arithmetic IF. The arithmetic IF was deleted from the language in the 2018 standard, but once was common practice. I also made sure to use implicit types. The first letter of a variable name determines its type. The variables here are all single precision, except "I", which is an integer. I had considered leaving the variable names the same as in the Bas code, but decided FORTRAN 77 programmers would not have used such names. PROGRAM GRCONV I = 0 PHI0 = 1.0 10 PHI1 = 1.0 + (1.0 / PHI0) DIFF = ABS (PHI1 - PHI0) PHI0 = PHI1 I = I + 1 IF (DIFF - 1.0E-5) 20, 20, 10 20 ERR = PHI1 - (0.5 * (1.0 + SQRT (5.0))) WRITE (*,100) PHI1, I 100 FORMAT ('RESULT:', F12.8, ' AFTER', I3, ' ITERATIONS') WRITE (*,110) ERR 110 FORMAT ('THE ERROR IS APPROXIMATELY', F12.8) END Output: This is output after compiling with f2c. Formatted output from gfortran will look different. RESULT: 1.61803281 AFTER 14 ITERATIONS THE ERROR IS APPROXIMATELY -.00000118 ### Fortran 2018 Translation of: Scheme This program will work with older dialects of Fortran, but I have checked that it can be compiled with "gfortran -std=f2018". The 2018 standard would be likely to complain were I doing something not considered appropriate anymore. I based this program on the Scheme, to demonstrate that you can do recursion, which you cannot do in standard Fortran 77. (By the way, "IF-ELSE-ENDIF" was already in Fortran 77. I simply did not use it, in the F77 program.) program golden_ratio_convergence implicit none ! Double precision. integer, parameter :: dp = selected_real_kind (14) real(kind = dp) :: phi integer :: n call iterate (1.0_dp, 0, phi, n) write (*,100) phi, n write (*,110) phi - (0.5_dp * (1.0_dp + sqrt (5.0_dp))) 100 format ('Result:', F12.8, ' after', I3, ' iterations') 110 format ('The error is approximately', F12.8) contains recursive subroutine iterate (phi0, n0, phi, n) real(kind = dp), value :: phi0 ! pass by value integer, value :: n0 real(kind = dp), intent(out) :: phi ! pass by ref, output only integer, intent(out) :: n ! Local variables will be on the stack, because the subroutine was ! declared recursive. real(kind = dp) :: phi1 integer :: n1 phi1 = 1.0_dp + (1.0_dp / phi0) n1 = n0 + 1 if (abs (phi1 - phi0) <= 1.0e-5_dp) then phi = phi1 n = n1 else call iterate (phi1, n1, phi, n) end if end subroutine iterate end program golden_ratio_convergence Output: Result: 1.61803279 after 14 iterations The error is approximately -0.00000120 ## Go Translation of: Wren package main import ( "fmt" "math" ) func main() { oldPhi := 1.0 var phi float64 iters := 0 limit := 1e-5 for { phi = 1.0 + 1.0/oldPhi iters++ if math.Abs(phi-oldPhi) <= limit { break } oldPhi = phi } fmt.Printf("Final value of phi : %16.14f\n", phi) actualPhi := (1.0 + math.Sqrt(5.0)) / 2.0 fmt.Printf("Number of iterations : %d\n", iters) fmt.Printf("Error (approx) : %16.14f\n", phi-actualPhi) } Output: Final value of phi : 1.61803278688525 Number of iterations : 14 Error (approx) : -0.00000120186465 ## Hy Translation of: Scheme (import math) (defn iterate [phi n] (setv phi1 (+ 1.0 (/ 1.0 phi))) (setv n1 (+ n 1)) (if (<= (abs (- phi1 phi)) 1e-5) [phi1 n1] (iterate phi1 n1))) (setv [phi n] (iterate 1.0 0)) (print "Result:" phi "after" n "iterations") (print "The error is approximately" (- phi (* 0.5 (+ 1 (math.sqrt 5))))) Output: Result: 1.6180327868852458 after 14 iterations The error is approximately -1.2018646491362972e-06 ## Icon Translation of: M4 For the sake of interest I translated this from the m4 rather than the Object Icon. Thus the calculations are done in scaled integer arithmetic. Every current implementation of Icon should have multiple precision integers. Therefore the full task can easily be carried out, unlike in the m4. Note that "one" and "one_squared" are different integers. They can both be viewed as fixed-point "1", but with the implicit decimal point in different positions. Where the number "100000" occurs, this represents its true integer value, which is ${\displaystyle 1 \over {1\times {10^{-5}}}}$. (To come up with a value of "one" I simply typed "1" and then typed a bunch of "0" without counting them.) (Comment: this code should work in Unicon, but Unicon deserves its own entry.) global one, one_squared procedure main () local result, phi, n, floatphi one := 1000000000000000000 one_squared := one * one result := iterate (one, 0) phi := result[1] n := result[2] floatphi := real (phi) / one write ("Result: ", phi, "/", one, " (", floatphi, ")") write (" ", n, " iterations") write ("The error is approximately ", floatphi - (0.5 * (1 + sqrt (5)))) end procedure iterate (phi, n) local phi1, n1 phi1 := one + (one_squared / phi) n1 := n + 1 if 100000 * abs (phi1 - phi) <= one then return [phi1, n1] else return iterate (phi1, n1) end Output: Result: 1618032786885245901/1000000000000000000 (1.618032787) 14 iterations The error is approximately -1.201864649e-06 ## J (Using IEEE754 64 bit binary floating point, of course): (,({:p)-~{&p)>:1 i.~1e_5>:|2 -/\p=. 1&(+%)^:a:1 NB. iterations and error 14 _1.20186e_6 In other words, wait for the series to converge (32 iterations - a few microseconds), check the pairwise differences and calculate the discrepancy. ## jq Adapted from Wren Works with: jq Also works with gojq, the Go implementation of jq Only minor adaptations are required for the following to work with jaq, the Rust implementation of jq, so the output shown below includes a run using jaq. def phi: (1 + (5|sqrt)) / 2; # epsilon > 0 def phi($epsilon):
{ phi: 1, oldPhi: (1+$epsilon), iters:0} | until( (.phi - .oldPhi) | length <$epsilon;
.oldPhi = .phi
| .phi = 1 + (1 / .oldPhi)
| .iters += 1 )

| "Final value of phi : \(.phi) vs \(phi)",
"Number of iterations : \(.iters)",
"Absolute error (approx) : \((.phi - phi) | length)";

phi(1e-5)
Output:

jq (the C implementation):

Final value of phi : 1.6180327868852458 vs 1.618033988749895
Number of iterations : 14
Absolute error (approx) : 1.2018646491362972e-06

gojq (the Go implementation):

Final value of phi : 1.6180327868852458 vs 1.618033988749895
Number of iterations : 14
Absolute error (approx) : 0.0000012018646491362972

jaq (the Rust implementation):

Final value of phi : 1.6180327868852458 vs 1.618033988749895
Number of iterations : 14
Absolute error (approx) : 1.2018646491362972e-6

## Java

Translation of: Wren
public class GoldenRatio {
static void iterate() {
double oldPhi = 1.0, phi = 1.0, limit = 1e-5;
int iters = 0;
while (true) {
phi = 1.0 + 1.0 / oldPhi;
iters++;
if (Math.abs(phi - oldPhi) <= limit) break;
oldPhi = phi;
}
System.out.printf("Final value of phi : %16.14f\n", phi);
double actualPhi = (1.0 + Math.sqrt(5.0)) / 2.0;
System.out.printf("Number of iterations : %d\n", iters);
System.out.printf("Error (approx) : %16.14f\n", phi - actualPhi);
}

public static void main(String[] args) {
iterate();
}
}
Output:
Final value of phi : 1.61803278688525
Number of iterations : 14
Error (approx) : -0.00000120186465

## Julia

Translation of: Wren
function iterate_phi(limit::T) where T <: Real
phi, oldphi, iters = one(limit), one(limit), 0
while true
phi = 1 + 1 / oldphi
iters += 1
abs(phi - oldphi) <= limit && break
oldphi = phi
end
println("Final value of phi : $phi") println("Number of iterations :$iters")
println("Error (approx) : $(phi - (1 + sqrt(T(5))) / 2)") end iterate_phi(1 / 10^5) iterate_phi(1 / big(10)^25) Output: Final value of phi : 1.6180327868852458 Number of iterations : 14 Error (approx) : -1.2018646491362972e-6 Final value of phi : 1.618033988749894848204586861593755309455975426621472923229332700794030300052916 Number of iterations : 61 Error (approx) : 2.722811719173566624681571006109388407808876983723400587864054809516456794284321e-26 ## Lua local phi, phi0, expected, iters = 1, 0, (1 + math.sqrt(5)) / 2, 0 repeat phi0, phi = phi, 1 + 1 / phi iters = iters + 1 until math.abs(phi0 - phi) < 1e-5 io.write( "after ", iters, " iterations, phi = ", phi ) io.write( ", expected value: ", expected, ", diff: ", math.abs( expected - phi ), "\n" ) Output: after 14 iterations, phi = 1.6180327868852, expected value: 1.6180339887499, diff: 1.2018646491363e-06 ## M4 This deviates from the task because m4 guarantees only 32-bit signed integer arithmetic, and I did not wish to go to a lot of trouble. So I do a simple scaled-integer calculation and get four decimal places. It takes 11 iterations. I do not compute the error. M4 is a macro-preprocessor, not a general-purpose programming language. That we can do this much without a lot of trouble is interesting. M4 has recursion but not true loops. It is possible to write macros that look like loops, but that is not done here. The "_iterate" macro (called "_$0" within the body of "iterate") is recursive.

divert(-1)

define(iterate',define(iterations',0)'_$0($1')')
define(_iterate',
define(iterations',eval(iterations + 1))'dnl
pushdef(phi1',eval(10000 + ((10000 * 10000) / ($1))))'dnl pushdef(diff',ifelse(eval((phi1 - ($1)) < 0),1,dnl
eval(($1) - phi1),eval(phi1 - ($1))))'dnl
ifelse(eval(diff < 1),1,phi1,_iterate(phi1)')'dnl
popdef(phi1',diff')')

divert'dnl
eval(iterate(10000) / 10000).'eval(iterate(10000) % 10000)
iterations iterations'
Output:
1.6180
11 iterations

## Maxima

(Side note: I notice that Maxima for-loops resemble Algol 60 for-loops. I would think this is not merely accidental.)

iterate(phi) := 1 + (1 / phi)$phi0: 1$
phi1: iterate(phi0)$for n: 1 step 1 while abs(phi1 - phi0) > 1e-5 do block(phi0: phi1, phi1: iterate(phi0), iterations: n + 1)$

display (float(phi1))$display (iterations)$
display (float(phi1 - (0.5 * (1 + sqrt(5)))))$Output:$ maxima -b golden_ratio_convergence.mac
Maxima 5.46.0 https://maxima.sourceforge.io
using Lisp SBCL 2.3.4
Dedicated to the memory of William Schelter.
The function bug_report() provides bug reporting information.
(%i1) batch("golden_ratio_convergence.mac")

(%i2) iterate(phi):=1+1/phi
(%i3) phi0:1
(%i4) phi1:iterate(phi0)
(%i5) for n while abs(phi1-phi0) > 1.0e-5 do
block(phi0:phi1,phi1:iterate(phi0),iterations:n+1)
(%i6) display(float(phi1))
987
float(---) = 1.618032786885246
610

(%i7) display(iterations)
iterations = 14

(%i8) display(float(phi1-0.5*(1+sqrt(5))))
987
float(--- - 0.5 (sqrt(5) + 1)) = - 1.201864648914253e-6
610

(%o9) /long-boring-pathname/golden_ratio_convergence.mac

## Mercury

Translation of: Scheme
%%% -*- mode: mercury; prolog-indent-width: 2; -*-

:- module golden_ratio_convergence_mercury.

:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.

:- implementation.
:- import_module float.
:- import_module int.
:- import_module math.
:- import_module string.

:- pred iterate(float::in, float::out, int::in, int::out) is det.
iterate(!Phi, !N) :-
Phi1 = (1.0 + (1.0 / !.Phi)),
N1 = !.N + 1,
(if (abs(Phi1 - !.Phi) =< 1.0e-5)
then (!:Phi = Phi1, !:N = N1)
else (iterate(Phi1, !:Phi, N1, !:N))).

main(!IO) :-
iterate(1.0, Phi, 0, N),
print("Result: ", !IO),
print(from_float(Phi), !IO),
print(" after ", !IO),
print(from_int(N), !IO),
print(" iterations", !IO),
nl(!IO),
print("The error is approximately ", !IO),
print(from_float(Phi - (0.5 * (1.0 + (sqrt(5.0))))), !IO),
nl(!IO).

:- end_module golden_ratio_convergence_mercury.
Output:
Result: 1.6180327868852458 after 14 iterations
The error is approximately -1.2018646491362972e-06

## Nim

import std/strutils

iterator goldenRatio(): (int, float) =
var phi = 1.0
var idx = 0
while true:
yield (idx, phi)
phi = 1 + 1 / phi
inc idx

const Eps = 1e-5
const Phi = 1.6180339887498948482045868343656381177203091798057628621354486
var prev = 0.0
for (i, phi) in goldenRatio():
if abs(phi - prev) <= Eps:
echo "Final value of φ: ", phi
echo "Number of iterations: ", i
echo "Approximative error: ", formatFloat(phi - Phi, ffDecimal)
break
prev = phi
Output:
Final value of φ: 1.618032786885246
Number of iterations: 14
Approximative error: -0.0000012018646491

## Odin

package golden
import "core:fmt"
import "core:math"
/* main block */
main :: proc() {
iterate()
}
/* definitions */
iterate :: proc() {
count := 0
phi0: f64 = 1.0
difference: f64 = 1.0
phi1: f64
fmt.println("\nGolden ratio/Convergence")
fmt.println("-----------------------------------------")
for 1.0e-5 < difference {
phi1 = 1.0 + (1.0 / phi0)
difference = abs(phi1 - phi0)
phi0 = phi1
count += 1
fmt.printf("Iteration %2d : Estimate : %.8f\n", count, phi1)
}
fmt.println("-----------------------------------------")
fmt.printf("Result: %.8f after %d iterations", phi1, count)
fmt.printf("\nThe error is approximately %.10f\n", (phi1 - (0.5 * (1.0 + math.sqrt_f64(5.0)))))
}
Output:
Golden ratio/Convergence
-----------------------------------------
Iteration 01 : Estimate : 2.00000000
Iteration 02 : Estimate : 1.50000000
Iteration 03 : Estimate : 1.66666667
Iteration 04 : Estimate : 1.60000000
Iteration 05 : Estimate : 1.62500000
Iteration 06 : Estimate : 1.61538462
Iteration 07 : Estimate : 1.61904762
Iteration 08 : Estimate : 1.61764706
Iteration 09 : Estimate : 1.61818182
Iteration 10 : Estimate : 1.61797753
Iteration 11 : Estimate : 1.61805556
Iteration 12 : Estimate : 1.61802575
Iteration 13 : Estimate : 1.61803714
Iteration 14 : Estimate : 1.61803279
-----------------------------------------
Result: 1.61803279 after 14 iterations
The error is approximately -0.0000012019

## ObjectIcon

import io, util

procedure main ()
local phi0, phi1, count

count := 1
phi0 := 1.0
while abs ((phi1 := 1.0 + (1.0 / phi0)) - phi0) > 1.0e-5 do
{
phi0 := phi1
count +:= 1
}
io.write ("Result: ", phi1, " after ", count, " iterations")
io.write ("The error is approximately ",
phi1 - (0.5 * (1.0 + Math.sqrt (5.0))))
end
Output:
Result: 1.618032787 after 14 iterations
The error is approximately -1.201864649e-06

## Ol

This program will run both in ol (Otus Lisp) and in R7RS Scheme (including Chibi). See also Scheme.

(import (scheme base)
(scheme write)
(scheme inexact))

(define (iterate phi n)
(let ((phi1 (+ 1 (/ phi)))
(n1 (+ n 1)))
(if (<= (abs (- phi1 phi)) 1/100000)
(list phi1 n1)
(iterate phi1 n1))))

(let* ((result (iterate 1 0))
(phi (car result))
(display "Result: ")
(display phi)
(display " (")
(display (inexact phi))
(display ") after ")
(display n)
(display " iterations")
(newline)
(display "The error is approximately ")
(display (inexact (- phi (* 0.5 (+ 1.0 (sqrt 5.0))))))
(newline))
Output:

This is how the output looks from ol.

Result: 987/610 (1.618032786) after 14 iterations
The error is approximately -0.000001202

## Onyx (wasm)

package main
use core {*}
use core.math{abs}
use core.intrinsics.wasm{sqrt_f64}
main :: () {
iterate();
}
iterate :: () {
count := 0;
phi0: f64 = 1.0;
difference: f64 = 1.0;
phi1: f64;
println("\nGolden ratio/Convergence");
println("-----------------------------------------");
while 0.00001 < difference {
phi1 = 1.0 + (1.0 / phi0);
difference = abs(phi1 - phi0);
phi0 = phi1;
count += 1;
printf("Iteration {} : Estimate : {.8}\n", count, phi1);
}
println("-----------------------------------------");
printf("Result: {} after {} iterations", phi1, count);
printf("\nThe error is approximately {.8}\n", (phi1 - (0.5 * (1.0 + sqrt_f64(5.0)))));
println("\n");
}
Output:
Golden ratio/Convergence
-----------------------------------------
Iteration 1 : Estimate : 2.00000000
Iteration 2 : Estimate : 1.50000000
Iteration 3 : Estimate : 1.66666666
Iteration 4 : Estimate : 1.60000000
Iteration 5 : Estimate : 1.62500000
Iteration 6 : Estimate : 1.61538461
Iteration 7 : Estimate : 1.61904761
Iteration 8 : Estimate : 1.61764705
Iteration 9 : Estimate : 1.61818181
Iteration 10 : Estimate : 1.61797752
Iteration 11 : Estimate : 1.61805555
Iteration 12 : Estimate : 1.61802575
Iteration 13 : Estimate : 1.61803713
Iteration 14 : Estimate : 1.61803278
-----------------------------------------
Result: 1.6180 after 14 iterations
The error is approximately -0.00000120

## ooRexx

/* REXX
* Compute the Golden Ratio using iteration
* 20230604 Walter Pachl
*/
Numeric Digits 16
Parse Value '1 1 1e-5' With oldPhi phi limit
Do iterations=1 By 1 Until delta<=limit
phi=1+1/oldPhi                      /* next approximation        */
delta=abs(phi-oldPhi)               /* difference to previous    */
If delta>limit Then                 /* not small enough          */
oldPhi=phi                        /* proceed with new value    */
End
actualPhi=(1+rxCalcsqrt(5,16))/2       /* compute the real value    */
Say 'Final value of phi  : ' phi      /* our approximation         */
Say 'Actual value        : ' actualPhi      /* the real value      */
Say 'Error (approx)      :' (phi-actualPhi) /* the difference      */
Say 'Number of iterations:' iterations
Exit
::REQUIRES RXMATH library
Output:
Final value of phi  :  1.618032786885246
Actual value        :  1.618033988749895
Error (approx)      : -0.000001201864649
Number of iterations: 14

## Perl

use strict; use warnings;
use constant phi => (1 + sqrt 5) / 2;

sub GR { my $n = shift;$n == 1 ? 2 : 1 + 1 / GR($n - 1) } my$i;
while (++$i) { my$dev = abs phi - GR($i); (printf "%d iterations: %8.6f vs %8.6f (%8.6f)\n",$i, phi, GR($i),$dev and last) if $dev < 1e-5; } Output: 12 iterations: 1.618034 vs 1.618026 (0.000008) ## Phix with javascript_semantics atom Phi = 1, iter = 0 do atom Pi = Phi Phi = 1+1/Phi iter += 1 until abs(Phi-Pi)<1e-5 printf(1,"Result: %.14f after %d iterations\n",{Phi,iter}) printf(1,"Error: %.14f\n",{Phi-(1+sqrt(5))/2}) Output: Result: 1.61803278688525 after 14 iterations Error: -0.00000120186465 ## Prolog Translation of: Mercury Works with: GNU Prolog version 1.5.0 Works with: SWI-Prolog version 9.1.2 iterate(Phi0, N0, Phi, N) :- Phi1 = (1.0 + (1.0 / Phi0)), N1 is N0 + 1, ((abs(Phi1 - Phi0) =< 1.0e-5) -> (Phi = Phi1, N = N1) ; iterate(Phi1, N1, Phi, N)). main :- iterate(1.0, 0, Phi, N), PhiApprox is Phi, Error is Phi - (0.5 * (1.0 + sqrt(5.0))), write('Final Phi = '), write(Phi), write('\n which is approximately '), write(PhiApprox), write('\n'), write(N), write(' iterations were required.'), write('\nThe error is approximately '), write(Error), write('\n'), halt. :- initialization(main). Output: Final Phi = 1.0+1.0/(1.0+1.0/(1.0+1.0/(1.0+1.0/(1.0+1.0/(1.0+1.0/(1.0+1.0/(1.0+1.0/(1.0+1.0/(1.0+1.0/(1.0+1.0/(1.0+1.0/(1.0+1.0/(1.0+1.0/1.0))))))))))))) which is approximately 1.6180327868852458 14 iterations were required. The error is approximately -1.2018646491362972e-06 ## Python Translation of: Wren import math oldPhi = 1.0 phi = 1.0 iters = 0 limit = 1e-5 while True: phi = 1.0 + 1.0 / oldPhi iters += 1 if math.fabs(phi - oldPhi) <= limit: break oldPhi = phi print(f'Final value of phi : {phi:16.14f}') actualPhi = (1.0 + math.sqrt(5.0)) / 2.0 print(f'Number of iterations : {iters}') print(f'Error (approx) : {phi - actualPhi:16.14f}') Output: Final value of phi : 1.61803278688525 Number of iterations : 14 Error (approx) : -0.00000120186465 ## Raku constant phi = 1.FatRat, 1 + 1/* ... { abs($^a-$^b)≤1e-5 }; say "It took {phi.elems} iterations to reach {phi.tail}"; say "The error is {{ ($^a - $^b)/$^b }(phi.tail, (1+sqrt(5))/2)}"
Output:
It took 15 iterations to reach 1.618033
The error is -7.427932029059675e-07

## RATFOR

program grconv
integer count
real phi0, phi1, diff

count = 0
phi0 = 1.0
diff = 1e+20
while (1e-5 < diff)
{
phi1 = 1.0 + (1.0 / phi0)
diff = abs (phi1 - phi0)
phi0 = phi1
count = count + 1
}

write (*,'("Result:", F9.6, " after", I3, " iterations")') _
phi1, count
write (*,'("The error is approximately ", F9.6)') _
phi1 - (0.5 * (1.0 + sqrt (5.0)))
end
Output:
Result: 1.618033 after 14 iterations
The error is approximately -0.000001

## REXX

/* REXX
* Compute the Golden Ratio using iteration
* 20230604 Walter Pachl
*/
Numeric Digits 16
Parse Value '1 1 1e-5' With oldPhi phi limit
Do iterations=1 By 1 Until delta<=limit
phi=1+1/oldPhi                      /* next approximation        */
delta=abs(phi-oldPhi)               /* difference to previous    */
If delta>limit Then                 /* not small enough          */
oldPhi=phi                        /* proceed with new value    */
End
actualPhi=(1+sqrt(5,16))/2            /* compute the real value    */
Say 'Final value of phi  : ' phi      /* our approximation         */
Say 'Actual value        : ' actualPhi      /* the real value      */
Say 'Error (approx)      :' (phi-actualPhi) /* the difference      */
Say 'Number of iterations:' iterations
Exit

sqrt: Procedure
/* REXX *************************************************************
* Return sqrt(x,precision) -- with the specified precision
********************************************************************/
Parse Arg x,xprec
If x<0 Then                         /* a negative argument       */
Return 'nan'                      /* has no real square root   */
iprec=xprec+10                      /* increase precision        */
Numeric Digits iprec                /* for very safe results     */
r0= x
r = 1                               /* start value               */
Do Until r=r0                       /* loop until no change of r */
r0 = r                            /* previous value            */
r = (r + x/r) / 2                 /* next approximation        */
End
Numeric Digits xprec                /* reset to desired precision*/
Return (r+0)                        /* normalize the result      */
Output:
Final value of phi  :  1.618032786885246
Actual value        :  1.618033988749895
Error (approx)      : -0.000001201864649
Number of iterations: 14

## RPL

### RPL 1986

≪ 0 1 1
DO
ROT 1 +
ROT DROP
SWAP DUP INV 1 +
UNTIL DUP2 - ABS .00001 ≤ END
SWAP DROP SWAP
OVER 1 5 √ + 2 / - ABS
≫ 'PHICONV' STO
Output:
3: 1.61803278688
2: 14
1: .00000120187

### RPL 2003

≪ 0 1 5 √ + 2 / → count phi
≪ 1 1
DO
'count' INCR DROP
NIP DUP INV 1 +
UNTIL DUP2 - →NUM ABS .00001 ≤ END
NIP EVAL count
OVER phi - →NUM ABS
≫ ≫  'PHICONV' STO
Output:
3: 987/610
2: 14
1: .00000120186

## Ruby

φ_convergence = Enumerator.produce(1.0r){|prev| 1 + 1/prev}
(_prev, c), i = φ_convergence.each_cons(2).with_index(1).detect{|(v1, v2), i| (v1-v2).abs <= 1E-5}

puts "Result after #{i} iterations: #{c.to_f}
Error is about #{c - (0.5 * (1 + (5.0**0.5)))}."
Output:
Result after 14 iterations: 1.618032786885246

## Scheme

Translation of: ATS

This will run without modification in R5RS Scheme implementations, among others. See Ol for a version of the program that will run without modification in R7RS implementations.

The iteration is written as a tail recursion, but loops in Scheme are always tail recursions. Constructs that look like ordinary loops are actually syntactic sugar.

The "iterate" procedure returns not one value but two of them. I use "call-with-values", which is Scheme's fundamental procedure for dealing with multiple value returns. (Syntactic sugars usually are used, rather than "call-with-values" directly.)

(define (iterate phi n)
(let ((phi1 (+ 1 (/ phi)))
(n1 (+ n 1)))
(if (<= (abs (- phi1 phi)) 1/100000)
(values phi1 n1)
(iterate phi1 n1))))

(call-with-values (lambda () (iterate 1 0))
(lambda (phi n)
(display "Result: ")
(display phi)
(display " (")
(display (* 1.0 phi))
(display ") after ")
(display n)
(display " iterations")
(newline)
(display "The error is approximately ")
(display (- phi (* 0.5 (+ 1.0 (sqrt 5.0)))))
(newline)))
Output:
Result: 987/610 (1.618032786885246) after 14 iterations
The error is approximately -1.2018646489142526e-6

## Shen

I plugged in a value for ${\displaystyle \phi }$ rather than write a sqrt procedure or see what there might be in the standard library. (Actually I wrote a sqrt procedure, but eventually decided to do this instead.)

(define iterate
PHI N ->
(let PHI1 (+ 1 (/ 1 PHI))
N1   (+ N 1)
DIFF (* 100000 (- PHI1 PHI))
(if (and (<= -1 DIFF) (<= DIFF 1))
[PHI1 N1 (- PHI1 1.618033988749895)]
(iterate PHI1 N1))))

(print (iterate 1 0))
Output:

I ran this with shen-scheme.

[1.6180327868852458 14 -1.2018646493583418e-6]

## Sidef

const phi = (1+sqrt(5))/2
func GR(n) is cached { (n == 1) ? 1 : (1 + 1/__FUNC__(n-1)) }

var n = (1..Inf -> first {|n|
abs(GR(n) - GR(n+1)) <= 1e-5
})

say "#{n} iterations: #{GR(n+1)} (cfrac)\n#{' '*15}#{phi} (actual)"
say "The error is: #{GR(n+1) - phi}"
Output:
14 iterations: 1.6180327868852459016393442622950819672131147541 (cfrac)
1.61803398874989484820458683436563811772030917981 (actual)
The error is: -0.00000120186464894656524257207055615050719442570740221

## V (Vlang)

Translation of: Wren
import math

fn main() {
limit := 1e-5
mut old_phi := 1.0
mut iters := 0
mut phi, mut actual_phi := f64(0), f64(0)
for {
phi = 1 + 1 / old_phi
iters++
if math.abs(phi - old_phi) <= limit {break}
old_phi = phi
}
println("Final value of phi : ${phi:.14f}") actual_phi = (1.0 + math.sqrt(5.0)) / 2.0 println("Number of iterations :${iters}")
println("Error (approx) : ${phi - actual_phi:.14f}") } Output: Final value of phi : 1.61803278688525 Number of iterations : 14 Error (approx) : -0.00000120186465 ## Wren Library: Wren-fmt Wren's only built-in numeric type is a 64 bit float. import "./fmt" for Fmt var oldPhi = 1 var phi var iters = 0 var limit = 1e-5 while (true) { phi = 1 + 1 / oldPhi iters = iters + 1 if ((phi - oldPhi).abs <= limit) break oldPhi = phi } Fmt.print("Final value of phi :$16.14f", phi)
var actualPhi = (1 + 5.sqrt) / 2
Fmt.print("Number of iterations : $d", iters) Fmt.print("Error (approx) :$16.14f", phi - actualPhi)
Output:
Final value of phi : 1.61803278688525
Number of iterations : 14
Error (approx) : -0.00000120186465

## XPL0

Translation of: Go

XPL0's real = float64 = double

include xpllib; \for Print

real OldPhi, Phi, Limit, ActualPhi;
int  Iters;
[OldPhi := 1.0;
Iters := 0;
Limit := 1e-5;
loop    [Phi := 1.0 + 1.0/OldPhi;
Iters := Iters+1;
if abs(Phi-OldPhi) <= Limit then
quit;
OldPhi := Phi;
];
Print("Final value of phi : %2.14f\n", Phi);
ActualPhi := (1.0 + sqrt(5.0)) / 2.0;
Print("Number of iterations : %d\n", Iters);
Print("Error (approx) : %2.14f\n", Phi-ActualPhi);
]
Output:
Final value of phi :  1.61803278688525
Number of iterations : 14
Error (approx) : -0.00000120186465