hp41programs

KFibonacci

K-Fibonacci Numbers for the HP-41


Overview
 

 1°)  Fibonacci Numbers ( k = 2 )
 2°)  Tribonacci Numbers ( k = 3 )
 3°)  Tetranacci Numbers ( k = 4 )
 4°)  General Case
 5°)  Multiprecision

   a)  Fibonacci Numbers
   b)  Tribonacci Numbers
   c)  General Case
 

-The programs listed in paragraph 1°) are also listed in "Difference Equations for the HP41"
 
 

1°)  Fibonacci Numbers ( k = 2 )
 

-This sequence is defined by

  u0 = 0  ,   u1 = 1  &   un+1 = un + un-1
 

Data Registers: /
Flags: /
Subroutines: /
 
 

 01  LBL "FIB"
 02  ENTER^
 03  SIGN
 04  ENTER^
 05  CHS
 06  X<>Y
 07  ST+ Z
 08  LBL 01
 09  ST+ Y
 10  X<>Y
 11  DSE Z
 12  GTO 01
 13  END

 
( 25 bytes / SIZE 000 )
 
 

      STACK        INPUTS      OUTPUTS
           Y             /           un-1
           X             n            un
           L             /            n

  where n is a non-negative integer

Examples:

  49  XEQ "FIB"  >>>>   u49  = 7778742049           X<>Y   u48  = 4807526976
 480      R/S        >>>>   u480 = 9.216845715 E99   X<>Y   u479 = 5.696323921 E99

Notes:

-This routine uses a dummy  u -1 = 1
-The difference equation  un+1 = un + un-1  which may be re-written  un+1 - un - un-1 = 0   has a characteristic equation

    r2 - r - 1 = 0   which has 2 real roots  r1 = ( 1 + sqrt(5) ) / 2  and  r2 = ( 1 - sqrt(5) ) / 2

-So, the solution may be written   un = c1 r1n + c2 r2n       u0 = 0  &  u1 = 1 lead to   c1 = 1/sqrt(5)  &  c2 = -1/sqrt(5)
-And we could write the program
 

Data Registers:  R00 = n , R01 = sqrt(5)
Flags: /
Subroutines: /
 
 

 01  LBL "FIB"
 02  STO 00
 03  5
 04  SQRT
 05  STO 01
 06  1
 07  +
 08  2
 09  /
 10  X<>Y
 11  Y^X
 12  1
 13  RCL 01
 14  -
 15  2
 16  /
 17  RCL 00
 18  Y^X
 19  -
 20  RCL 01
 21  /
 22  END

 
( 30 bytes / SIZE 002 )
 
 

      STACK        INPUTS      OUTPUTS
           X             n            un

  where n is a non-negative integer

Examples:

 49  XEQ "FIB"  >>>>   u49 = 7778742108
 480      R/S        >>>>   OUT OF RANGE

Remarks:

-Though the second version is faster, there are also larger roundoff-errors.
-Moreover, an OUT OF RANGE occurs before un overflows !
 

2°)  Tribonacci Numbers ( k = 3 )
 

-Tribonacci numbers are defined by     u0 = 0  ,   u1 = 0  ,   u2 = 1    &   un+1 = un + un-1 + un-2
 

Data Registers: /
Flags: /
Subroutines: /
 
 

 01 LBL "TRIB"
 02 ENTER
 03 SIGN
 04 ENTER
 05 CHS
 06 X<>Y
 07 0
 08 LBL 01
 09 ST+ Z
 10 X<>Y
 11 ST+ Z
 12 X<> Z
 13 DSE T
 14 GTO 01
 15 END

 
( 29 bytes / SIZE 000 )
 
 

      STACK        INPUTS      OUTPUTS
           Z             /           un-2
           Y             /           un-1
           X             n            un

  where n is a non-negative integer

Examples:

    7  XEQ "TRIB"  >>>>   u7 =  13
   40       R/S          >>>>  u40 =  7046319384                     ---Execution time =  8s---
  380      R/S          >>>> u380 ~  6.741757257 E99            ---Execution time = 74s---
 

Notes:

-The difference equation  un+1 = un + un-1 + un-2    which may be re-written  un+1 - un - un-1 - un-2  = 0   has a characteristic equation

    r3 - r2 - r - 1 = 0   which has 2 real roots  r1 ~ 1.839286755  ,  r2 ~  -0.4196433776 + 0.6062907292 i  ,  r3 ~  -0.4196433776 - 0.6062907292 i

-So, the solution may be written   un = c1 r1n + c2 r2n + c3 r3n

    with   c1 ~ 0.1828035330  ,   c2 ~ -0.01940176648 + 0.3405465308 i   ,   c3 ~ -0.01940176648 - 0.3405465308 i

-This leads to the following program:
 

Data Registers: /
Flags: /
Subroutines: /
 
 

 01 LBL "TRIB"
 02 DEG
 03 STO Y
 04 124.6889974
 05 *
 06 105.0239517
 07 +
 08 COS
 09 .7051984758
 10 *
 11 .7373527058
 12 RCL Z
 13 Y^X
 14 *
 15 1.839286755
 16 R^
 17 Y^X
 18 .182803533
 19 *
 20 +
 21 END

 
( 91 bytes / SIZE 000 )
 
 

      STACK        INPUT      OUTPUT
           X             n            un

  where n is a non-negative integer

Examples:

    7  XEQ "TRIB"  >>>>   u7 ~  12.99999999
   40       R/S          >>>>  u40 ~   7046319352
  377      R/S          >>>> u377 ~  1.083489631 E99
 

Notes:

-Roundoff-errors are larger than with the 1st version
-But the routine is much faster for large numbers
-If n > 377 , we get OUT OF RANGE

-A simpler formula may be used ( cf reference [1] ):

   un = RND0 [ 3.b ( a + c + 1 )n-1 / ( b2 - 2.b + 4 ) ]

  where  a = ( 19 + 3 sqrt(33) )1/3  ,  c = ( 19 - 3 sqrt(33) )1/3  ,  b = ( 589 + 102 sqrt(33) )1/3
 

Data Registers: /
Flags: /
Subroutines: /
 
 

 01 LBL "TRIB"
 02 1.839286755
 03 X<>Y
 04 1
 05 -
 06 Y^X
 07 .336228117
 08 *
 09 FIX 0
 10 RND
 11 FIX 9
 12 END

 
( 42 bytes / SIZE 000 )
 
 

      STACK        INPUT      OUTPUT
           X             n            un

  where n is a non-negative integer

Examples:

    7  XEQ "TRIB"  >>>>   u7 =    13
   40       R/S          >>>>  u40 ~   7046319354
  378      R/S          >>>> u378 ~  1.992848127 E99
 

Note:

-If n > 378 , we get an OUT OF RANGE message
 

3°)  Tetranacci Numbers ( k = 4 )
 

-Similarly, tetranacci numbers are defined by  u0 = 0  ,   u1 = 0  ,   u2 = 0  ,   u3 = 1     &   un+1 = un + un-1 + un-2 + un-3
 

Data Register:  R00: temp
Flags: /
Subroutines: /
 
 

 01 LBL "TETRN"
 02 STO 00
 03 CLST
 04 SIGN
 05 ENTER
 06 CHS
 07 X<>Y
 08 R^
 09 LBL 01
 10 R^
 11 R^
 12 ST+ Y
 13 R^
 14 ST+ Z
 15 R^
 16 ST+ T
 17 R^
 18 DSE 00
 19 GTO 01
 20 END

 
( 35 bytes / SIZE 001 )
 
 

      STACK        INPUTS      OUTPUTS
           T             /           un-3
           Z             /           un-2
           Y             /           un-1
           X             n            un

  where n is a non-negative integer

Examples:

    7  XEQ "TETRN"  >>>>  u12 =  208
   38       R/S              >>>>  u38 =   5350220959                     ---Execution time = 10s---
  354      R/S              >>>> u354 ~  6.180313110 E99             ---Execution time = 94s---
 

Note:

-There is an OUT OF RANGE if n > 354
 

4°)  General Case
 

-We could write several programs for k = 5 , 6 , 7 , ....  but it's simpler to create a general program for all k > 1
 

Data Registers:      R00 = n   R01 = u(k)n-k+1  R02 = u(k)n-k+2  .........  Rkk = u(k)n
Flags: /
Subroutines: /
 
 

 01 LBL "KFIB" 
 02 STO 00
 03 X<>Y
 04 STO M
 05 .1
 06 %
 07 ISG X
 08 CLRGX
 09 SIGN
 10 STO IND M
 11 RCL 00
 12 +
 13 RCL M
 14 -
 15 STO N
 16 X>0?
 17 GTO 01
 18 LASTX
 19 +
 20 RCL IND X
 21 GTO 10
 22 LBL 01
 23 RCL M
 24 STO O
 25 RCL IND X 
 26 ENTER
 27 DSE O
 28 LBL 02
 29 X<> IND O
 30 ST+ Y
 31 DSE O
 32 GTO 02
 33 X<>Y
 34 STO IND M
 35 DSE N
 36 GTO 01
 37 LBL 10
 38 RCL 00       
 39 SIGN
 40 X<> M
 41 X<>Y
 42 CLA
 43 END

 
     ( 74 bytes / SIZE kkk+1 )
 
 

      STACK        INPUTS      OUTPUTS
           Y           k > 1            k
           X             n           u(k)n
           L             /            n

  where n is a non-negative integer

Examples:

     4  ENTER^  12   XEQ "KFIB"  >>>>    u(4)12 =  208                                   ---Execution time =  7s---
          CLX        38         R/S          >>>>    u(4)38 =   5350220959                     ---Execution time = 27s---
          CLX       354        R/S          >>>>   u(4)354 ~   6.180313114 E99            ---Execution time = 4m25s---
 

Notes:

-This program is of course slower than the corresponding  "FIB"  "TRIB"  "TETRN"  ...
-But it gives the same results
-The alpha "register" is cleared at the end.

-A simpler and faster method may be used ( cf reference [2] ):

   u(k)n = RND0 [ ( r-1 ) rn-k+1 / { 2 + (k+1).(r-2) }    where  r is the positive root of the characteristic equation

-The following variant employs Newton's method to find the real root of the characteristic equation.
-After finding this root, simply press R/S for another u(k)n with the same k-value.
 

Data Registers:      R00 to R03: temp  ( R01 = root )
Flags: /
Subroutines: /
 
 
 

 01 LBL "KFIB"
 02 STO 00
 03 X<>Y
 04 STO 03
 05 2
 06 STO 01
 07 LBL 00
 08 RCL 01
 09 RCL 01
 10 RCL 03
 11 Y^X
 12 STO 02
 13 LASTX
 14 1
 15 +
 16 *
 17 RCL 01      
 18 RCL 03
 19 DSE X
 20 Y^X
 21 RCL 03
 22 ST+ X
 23 *
 24 -
 25 X<> 02
 26 ST* Y
 27 ST+ X
 28 -
 29 1
 30 +
 31 RCL 02      
 32 /
 33 ST- 01
 34 ABS
 35  E-7
 36 X<Y?
 37 GTO 00
 38 RCL 00
 39 LBL 10
 40 STO 00
 41 RCL 01
 42 X<>Y
 43 RCL 03      
 44 DSE X
 45 -
 46 Y^X
 47 RCL 01
 48 1
 49 -
 50 ST* Y
 51 LASTX
 52 -
 53 RCL 03       
 54 1
 55 +
 56 *
 57 2
 58 +
 59 /
 60 FIX 0
 61 RND
 62 FIX 9
 63 RTN
 64 GTO 10
 65 END

 
    ( 88 bytes / SIZE 004 )
 
 

    STACK     INPUT1   OUTPUT1     INPUT2   OUTPUT2
        Y       k > 1          /           /          /
        X         n        u(k)n          m        u(k)m

  where n , m are non-negative integers

Examples:

    4   ENTER^   12    XEQ "KFIB"    >>>>   u(4)12 =  208
             38                        R/S            >>>>   u(4)38 ~  5350221004
            353                       R/S            >>>>  u(4)353 ~  3.206285314 E99

Notes:

-The method is quite good, but since the HP41 only works with 10 digits,
  roundoff-errors may be much larger than with the 1st version.
-It's also much faster, especially for large n-values

-Instead of solving the characteristic equation  f(r) =  rk - rk-1 - ..... - r - 1 = 0  ,  the HP41 solves  ( r - 1 ) f(r) = 0 = rk+1 - 2.rk + 1 = 0
-The root is always close to 2, so the 1st estimation is 2 ( line 05 )
 

5°)  Multiprecision
 

     a)  Fibonacci Numbers
 
 
 
 

Data Registers:      R00 = n , n-1 , .... , 0

                                   R01-R02-............-Rmm = un
                                   Rm+1-................-R2m = un-1
Flags: /
Subroutines: /
 
 
 

 01 LBL "FIBM"
 02 STO 00
 03  E9
 04 STO O
 05 CLX
 06 STO 02
 07 SIGN
 08 ST- 00
 09 STO 01
 10 STO N
 11 LBL 01
 12 RCL N
 13 STO M
 14 ST+ X
 15 ENTER
 16 CLX
 17 LBL 02
 18 RCL IND Y
 19 +
 20 RCL IND M
 21 STO IND Z
 22 +
 23 RCL X
 24 RCL O
 25 MOD
 26 STO IND M
 27 -
 28 RCL O
 29 /
 30 DSE Y
 31 DSE M
 32 GTO 02
 33 X=0?
 34 GTO 00      
 35 X<>Y
 36  E3
 37 /
 38 RCL N
 39 +
 40 3
 41 +
 42  E3
 43 /
 44 RCL N
 45 1
 46 +
 47 STO N
 48 +
 49 REGMOVE
 50 LASTX
 51 .1
 52 %
 53 +
 54 -
 55 1
 56 +
 57 REGMOVE
 58 RCL N
 59 LASTX
 60 +
 61 0
 62 STO IND Y
 63 R^
 64 STO 01
 65 LBL 00
 66 DSE 00
 67 GTO 01
 68 RCL N
 69 .1
 70 %
 71 1
 72 +
 73 CLA
 74 END

 
    ( 115 bytes / SIZE 2m+1 )
 
 

      STACK        INPUT      OUTPUT
           X          n > 1        1.mmm

  And  un  is stored in registers  R01 R02 .... Rmm

Examples:

    49  XEQ "FIBM"   >>>>   1.002                               ---Execution time = 38s---

    R01 = 7
    R02 = 778742049

-So,    u49 = 7778742049

-Likewise, u48 = 4807526976   is in registers R03-R04

   100   R/S   >>>>   1.003                               ---Execution time = 1m46s---

   R01 = 354
   R02 = 224848179
   R03 = 261915075

-So,    u100 = 354224848179261915075

-Likewise, u99 = 218922995834555169026  is in registers R04-R05-R06

   1000  R/S  >>>>  1.024                                 ---Execution time = 10s---                        with V41 in turbo mode

    R01 = 43                   R07 = 371780402    R13 = 295922593    R19 = 906533187
    R02 = 466557686     R08 = 481729089    R14 = 080322634    R20 = 938298969
    R03 = 937456435     R09 = 536555417    R15 = 775209689    R21 = 649928516
    R04 = 688527675     R10 = 949051890    R16 = 623239873    R22 = 003704476
    R05 = 040625802     R11 = 403879840    R17 = 322471161    R23 = 137795166
    R06 = 564660517     R12 = 079255169    R18 = 642996440    R24 = 849228875

-So,  u1000 = 43466557686937456435688527675040625802564660517371780402481729089536555417949051890403879840079255169
                  295922593080322634775209689623239873322471161642996440906533187938298969649928516003704476137795166849228875

and  u999  is in R25 to R48
 

Notes:

-Add zeros on the left if there are less than 9 digits in R02 ... Rmm
-For example, if  R02 = 123 , read  R02 = 000000123
 

     b)  Tribonacci Numbers
 
 

Data Registers:      R00 = n , n-1 , .... , 0

                                   R01 R02 ............ Rmm = un
                                   Rm+1 ................. R2m = un-1
                                   R2m+1 ............... R3m = un-2
Flags: /
Subroutines: /
 
 

 01 LBL "TRIBM"
 02 STO 00
 03 CLX
 04 STO 02
 05 STO 03
 06 SIGN
 07 STO 01
 08 STO N
 09 2
 10 ST- 00
 11 LBL 01
 12 RCL N
 13 ENTER
 14 STO M
 15 ST+ X
 16 STO O
 17 +
 18 ENTER
 19 CLX
 20 LBL 02
 21 RCL IND Y 
 22 +
 23 RCL IND O
 24 STO IND Z
 25 +
 26 RCL IND M
 27 STO IND O
 28 +
 29 RCL X
 30  E9
 31 MOD
 32 STO IND M
 33 -
 34  E9
 35 /
 36 DSE Y
 37 DSE O
 38 DSE M
 39 GTO 02
 40 X=0?
 41 GTO 00       
 42 X<>Y
 43 .1
 44 %
 45 +
 46 1.004
 47 +
 48 RCL N
 49  E6
 50 /
 51 +
 52 REGMOVE
 53 RCL N
 54 .1
 55 %
 56 +
 57  E-3
 58 +
 59 -
 60 REGMOVE 
 61 LASTX
 62 -
 63 REGMOVE
 64 X<>Y
 65 STO 01
 66 RCL N
 67 1
 68 +
 69 STO N
 70 ENTER
 71 ST+ X
 72 1
 73 ST+ Y
 74 ST+ Z
 75 CLX
 76 STO IND Y 
 77 STO IND Z
 78 LBL 00
 79 DSE 00
 80 GTO 01
 81 RCL N
 82 .1
 83 %
 84 ISG X
 85 CLA
 86 END

 
    ( 142 bytes / SIZE 3m+1 )
 
 

      STACK        INPUT      OUTPUT
           X          n > 2        1.mmm

  And  un  is stored in registers  R01 R02 .... Rmm

Examples:

•  40  XEQ "TRIBM"   >>>>  1.002                                 ---Execution time = 44s---

    R01 = 7
    R02 = 46319384      whence   u40 = 7046319384

    R03 = 3
    R04 = 831006429    whence   u39 = 3831006429

    R05 = 2
    R06 = 82876103     whence   u38 = 2082876103

•  100   R/S   >>>>   1.003                                 ---Execution time = 2m58s---

    R01 = 53324762
    R02 = 928098149
    R03 = 64722658     whence   u100 = 53324762928098149064722658

>>>  u99 & u98 are in R04-R05-R06 & R07-R08-R09  respectively.

    u99 = 28992087708416717612934417  &  u98 = 15762679542071167858843489
 

Note:

-Add zeros on the left if there are less than 9 digits in R02 ...
 

     c)  General Case
 
 

Data Registers:      R00 = n-k , n-k-1 , .... , 0

                                   R01 R02 ............ Rmm = un
                                   Rm+1 ................. R2m = un-1
                                   R2m+1 ............... R3m = un-2
Flags: /
Subroutines: /

-Line 105 is a three-byte GTO 01
 
 

 01 LBL "KFIBM"
 02 STO 00
 03 STO a
 04 X<>Y
 05 ST- 00
 06 STO M
 07 .1
 08 %
 09 ISG X
 10 CLRGX
 11 SIGN
 12 STO 01
 13 STO N
 14 ISG 00
 15 LBL 01
 16 RCL M
 17 RCL N
 18 ST* Y
 19 STO O
 20  E5
 21 /
 22 +
 23 STO Q
 24 CLX
 25 LBL 02
 26 RCL Q
 27 STO P
 28 X<>Y
 29 RCL IND Y  
 30 +
 31 DSE Y
 32 LBL 03
 33 RCL IND Y
 34 STO IND P
 35 +
 36 DSE P
 37 DSE Y
 38 GTO 03
 39 RCL X
 40 PI
 41 X^2
 42 INT
 43 10^X
 44 MOD
 45 STO IND P
 46 ST- Y
 47 X<> L
 48 /
 49 PI
 50 SIGN
 51 ST- Q
 52 X<>Y
 53 DSE O
 54 GTO 02        
 55 X=0?
 56 GTO 00
 57 RCL N
 58 RCL M
 59 STO O
 60 DSE X
 61 *
 62 1
 63 +
 64 .1
 65 %
 66 +
 67 RCL M
 68  E3
 69 /
 70 +
 71 RCL N
 72  E6
 73 /
 74 +
 75 LBL 04
 76 REGMOVE  
 77 RCL N
 78 .1
 79 %
 80 +
 81 -
 82  E-3
 83 -
 84 DSE O
 85 GTO 04
 86 ISG N
 87 CLX
 88 CLX
 89 RCL N
 90  E5
 91 /
 92 RCL M
 93 RCL N
 94 *
 95  E3
 96 /
 97 +
 98 1
 99 +
100 CLRGX
101 X<>Y
102 STO 01        
103 LBL 00
104 DSE 00
105 GTO 01
106 RCL M
107 RCL N
108  E3
109 /
110 ISG X
111 RCL a
112 SIGN
113 RDN
114 CLA
115 END

 
    ( 187 bytes / SIZE k.m+1 )
 
 

      STACK        INPUTS      OUTPUTS
           Y      1<  k < 11             k
           X        n > k-1        1.mmm
           L             /             n

  And  u(k)n  is stored in registers  R01 R02 .... Rmm

Example1:

     3     ENTER^
   100   XEQ "KFIBM"   >>>>   1.003                                 ---Execution time = 4m37s---

   R01 = 53324762
   R02 = 928098149
   R03 = 64722658     whence   u(3)100 = 53324762928098149064722658

>>>  u(3)99 & u(3)98 are stored in R04-R05-R06 & R07-R08-R09  respectively:

    u(3)99 = 28992087708416717612934417  &  u(3)98 = 15762679542071167858843489

Example2:

    4     ENTER^
  100       R/S       >>>>   1.004                                 ---Execution time = 5m33s---

  R01 = 2
  R02 = 505471397
  R03 = 838180985
  R04 = 96739296   whence   u(4)100 = 2505471397838180985096739296

>>>  u(4)99 , u(4)98 & u(4)97  are stored in R05-R06-R07-R08 , R09-R10-R11-R12 & R13-R14-R15-R16  respectively:

   u(4)99 = 1299813666022576563302979257
   u(4)98 =   674330414562637002982620399
   u(4)97 =   349835918709535855778683552
 

Notes:

-Add zeros on the left if there are less than 9 digits in R02 ...

-Synthetic registers P & Q are used, so don't stop this routine ( no risk of crash, however ).
-Synthetic register a is also employed, so "KFIBM" must not be called as more than a first level subroutine.
-Register "a" is only used to save n in L-register. Otherwise, simply delete lines 111-112-113 and line 03.

-There is a risk of roundoff-error if k > 10
 

References:

[1]  https://en.wikipedia.org/w/index.php?title=Generalizations_of_Fibonacci_numbers&oldid=933134595
[2]  Gregory P. B. Dresden & Zhaohui Du - "A Simplified Binet Formula for k-Generalized Fibonacci Numbers"