Skip to main content
9 of 16
added 662 characters in body
supinf
  • 2.2k
  • 1
  • 9
  • 7

Since the Apollo 11 Code is on Github, i was able to find the code that looks like an implementation of sine and cosine functions: see here for the command module and here for the lunar lander (it looks like it is the same code).

For convenience, here is a copy of the code:

 # Page 1102
            BLOCK   02

# SINGLE PRECISION SINE AND COSINE

            COUNT*  $$/INTER
SPCOS       AD      HALF            # ARGUMENTS SCALED AT PI
SPSIN       TS      TEMK
            TCF     SPT
            CS      TEMK
SPT         DOUBLE
            TS      TEMK
            TCF     POLLEY
            XCH     TEMK
            INDEX   TEMK
            AD      LIMITS
            COM
            AD      TEMK
            TS      TEMK
            TCF     POLLEY
            TCF     ARG90
POLLEY      EXTEND
            MP      TEMK
            TS      SQ
            EXTEND
            MP      C5/2
            AD      C3/2
            EXTEND
            MP      SQ
            AD      C1/2
            EXTEND
            MP      TEMK
            DDOUBL
            TS      TEMK
            TC      Q
ARG90       INDEX   A
            CS      LIMITS
            TC      Q       # RESULT SCALED AT 1.
 

The comment

# SINGLE PRECISION SINE AND COSINE

indicates, that the following is indeed an implementation of the sine and cosine functions. Information about the type of assembler used, can be found on Wikipedia

Partial explanation of the code:

The subroutine SPSIN actually calculates $\sin(\pi x)$, and SPCOS calculates $\cos(\pi x)$. The subroutine SPCOS first adds one half to the input, and then proceeds to calculate the sine (this is valid because of $\cos(\pi x) = \sin(\pi (x+\tfrac12))$). The argument is doubled at the begin of the SPT subroutine. That is why we now have to calculate $\sin(\tfrac\pi2 y)$ for $y=2x$.

The subroutine POLLEY calculates a taylor polynomial approximation of $\sin(\tfrac\pi2 x)$. First, we store $x^2$ in the register SQ (where $x$ denotes the input). This is used to calculate the polynomial $$ ((( C_{5/2} x^2 ) + C_{3/2} ) x^2 + C_{1/2}) x. $$ The values for the constants can be found in the same github repository and are

$$ C_{5/2}= .0363551 \approx \big(\frac\pi2\big)^5 \cdot \frac1{2\cdot 5!}\\ C_{3/2}= -.3216147 \approx -\big(\frac\pi2\big)^3 \cdot \frac1{2\cdot 3!}\\ C_{1/2}= .7853134 \approx \frac\pi2 \cdot \frac12\\ $$

which look like the first taylor coefficients for the function $\frac12 \sin(\tfrac\pi2 x)$. These values are not exact, but I suspect that the error comes from the low bit resolution.

Finally, the result is doubled with the DDOUBL command, and the subroutine POLLEY returns an approximation to $\sin(\tfrac\pi2 x)$.

As for the scaling (first halve, then double, ...), @Christopher mentioned in the comments, that the 16-Bit Fixed-Point number could only store values from -1 to +1. Therefore, scaling is necessary. See here for a source and further details on the data representation.

How accurate is this taylor approximation? Here you can see a plot on WolframAlpha for the sine, and it looks like a good approximation for $x$ from $-0.6$ to $+.6$. The cosine function and its approximation is plotted here. I hope they never had to calculate the cosine for a value $\geq \tfrac\pi2$, because then the error would be unpleasantly large.

Note that for the taylor approximation you only need four multiplications and two additions (MP and AD in the code).

There are some ways to increase accuracy and input range, which would have been available for them, but would result in more code and more computation time. For example, exploiting symmetry and periodicity of sine and cosine, using the taylor expansion for cosine, or simply adding more terms of the taylor expansion would have improved the accuracy and would also allow for arbitrary large input values.

supinf
  • 2.2k
  • 1
  • 9
  • 7