IRA Withdrawal

Developer(s): Max Schoenfeld
Date: 198x
Type: Program
Platform(s): TS 2068
Tags: Finance

This program calculates the optimal annual withdrawal amount from an IRA (Individual Retirement Account) so that the balance reaches zero after a user-specified number of years, given a starting balance and expected interest rate. It uses an iterative convergence loop: starting with one-tenth of the principal as an initial withdrawal estimate, it repeatedly adjusts the withdrawal amount by half the residual balance divided by the number of years until the ending balance falls within ±1. The DIM statement allocates a numeric array sized to the payout period, storing each year’s balance for final display. After convergence, the program prints a year-by-year balance table and the total cumulative payout.


Program Structure

The program is divided into four logical phases:

  1. Input (lines 20–40): Collects starting balance (a), interest rate (b), and payout years (d).
  2. Iterative convergence loop (lines 110–210): Repeatedly adjusts annual withdrawal c until the ending balance is within ±1 of zero.
  3. Year-by-year output (lines 305–320): Prints the balance remaining at the end of each year.
  4. Summary and save (lines 330–350): Prints the total payout and saves the program.

Convergence Algorithm

The program uses a successive approximation method to find the withdrawal amount that exhausts the account. The initial estimate is one-tenth of the principal (c = a/10). After each simulation pass through the d-year period, line 200 adjusts c upward or downward by adding half the residual balance divided by the number of years: c = c + a(d+1)/(2*d). If the ending balance is positive, withdrawal was too small; if negative, too large. The loop repeats via GO TO 125 until line 205 detects that the residual is within ±1.

Array Usage and Variable Conflict

A notable anomaly exists at line 120: DIM a(d+1) redefines the variable a, which previously held the starting balance entered at line 20. Issuing DIM on an existing variable name replaces the scalar with an array, destroying the original value. Line 130 compensates by assigning a(1)=a — but at this point a on the right-hand side refers to the newly created array element a(1), which is zero, not the original principal. This is a bug: the program should have saved the starting balance in a separate variable before the DIM statement. In practice the code still functions because line 130 is inside the convergence loop body (between FOR and NEXT), so a(1) is always zero after the first iteration — the initial principal is permanently lost.

Key BASIC Idioms

  • PAUSE 50 before the introductory PRINT (line 50) provides a brief delay, giving the user time to read the screen before the table starts scrolling.
  • TAB 12 and TAB 10 are used for columnar alignment in the output tables (lines 160 and 310).
  • GO TO 125 re-enters the FOR…NEXT loop from above the FOR statement, which is the standard ZX81 idiom for restarting a loop without a GOSUB.
  • VAL is not used here; literal line numbers are used in all GO TO targets.

Output and Final Calculation

Line 305 prints the confirmed withdrawal amount as c - a(d+1)/(2*d), which subtracts the last half-step correction to recover the withdrawal value from the previous iteration — the one that actually produced the near-zero balance. Line 330 multiplies this by d to report the total lifetime payout. The result is displayed with a leading dollar sign embedded in the string literal.

Bugs and Anomalies

LineIssueEffect
120DIM a(d+1) destroys the scalar a (starting balance)Principal is lost; a(1) is initialized to 0 instead of the user’s input, making all balance calculations incorrect
130a(1)=a — right-hand a is now array element 1, not the original principalCompounds the bug above; does not restore the intended initial value
15REM misspells “withdrawal” as “withdrawl”Cosmetic only

Source Code

   10 REM "IRA withdrawl"
   15 REM by Max Schoenfeld
   20 INPUT "How much money to start?  $ ";a
   30 INPUT "Expected interest rate? ";b
   40 INPUT "How many years to pay out? ";d
   50 PAUSE 50: PRINT "This table shows how much money remains in the account after ";d;" years, with the amount of annual withdrawal."
  100 PRINT : PRINT 
  110 LET c=a/10
  120 DIM a(d+1)
  125 FOR x=2 TO d+1
  130 LET a(1)=a
  140 LET a(x)=a(x-1)*(b+1)-c
  150 NEXT x
  160 PRINT a(d+1);TAB 12;c
  200 LET c=c+a(d+1)/(2*d)
  205 IF a(d+1)<=1 AND a(d+1)>=-1 THEN GO TO 300
  210 GO TO 125
  305 PRINT : PRINT "Balance by year, after paying   out ";c-(a(d+1))/(2*d);" each year"
  307 FOR x=2 TO d+1
  310 PRINT (x-1);TAB 10;a(x)
  320 NEXT x
  330 PRINT : PRINT "Total pay-out is $ ";d*(c-(a(d+1))/(2*d))
  340 STOP 
  350 SAVE "IRA PAYOUT"

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.