Golden ratio/Convergence

From Rosetta Code
Revision as of 15:54, 3 June 2023 by Chemoelectric (talk | contribs) (Added Arizona Icon.)
Task
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

Thus . Multiplying both sides by and solving the resulting quadratic equation for its positive solution, one gets .

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 , , and see how long it takes to get an answer.

Task

Iterate , , until . Report the final value of , the number of iterations required, and the error with respect to .

See also

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 iteratoioins 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 iteratoioins 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 "share/atspre_staload.hats"

%{^
#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

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

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

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: 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
           ADD 1 TO ITER
           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

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

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 .

(To come up with a value of "one" I simply typed "1" and then typed a bunch of "0" without counting them.)

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

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

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

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

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))
       (n (cadr 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

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

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

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

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

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