12c_TrigonometryFunctions
12c_TrigonometryFunctions
Our mighty goal: Trim & Trusty Trigonometrics for the 12C
Yes. Exactly that. To begin with, let's enumerate the 5 required specifications that
our own trigonometrics implementation on the 12C (or any other allegedly decent
implementation) must inexcusably meet to be worth its salt. In strict order of
relevance:
1) All six trigonometric functions in a single program. This is the first and
foremost requirement: all six principal trigonometric functions, namely sine,
cosine, tangent, arc sine, arc cosine, and arc tangent, must be conveniently
computed using a single program (99 steps or less).
Else, we simply haven't achieved our goal. It's all very well to implement a sine
function as a single program, then write another for the arc sine and so on. But
that's neither practical nor useable. The 12C has no mag cards to quickly load the
required program, and keying in the different programs while computing a
complicated, mixed trig expression is out of the question. It's all six functions
computable using a single program or else we should acknowledge defeat.
2) Full accuracy for all functions. No trade-offs between speed and accuracy will
be tolerated. All functions will be computed to the maximum possible accuracy.
Else, if we allow reduced accuracy, we can never really trust the results we get,
specially in a long chain of trig calculations. Would you trust your HP-xx when
computing a sine or arc sine if the manual said the accuracy was "reduced" to save
time or memory? Come on! We want 9-10 digits accuracy and we want them now!
We need to trust the results we get.
As for the input ranges, you must be able to compute an arc tangent for any input
value, not being restricted to -1..+1. Real men compute their arc tangents from
-Infinity to +Infinity, so our program must allow you to compute arc tangent of,
say, 10^10 as easily as arc tangent of 0.1
3) Maximum speed and fast computation times for all functions and all inputs.
Yes, we want all 6 functions, we want full accuracy, and we want it all fast. Real
fast. We want bounded, maximum guaranteed times for any inputs within the
allowed range for every function.
Else you will have the pitfall that many other trig implementations don't tell you at
first: slow convergence, if at all. Some programmers simply use the usual Taylor
Series Expansion for, say, the arc tangent or arc sine in a straightforward manner.
Program listing
• SQRT is the square root function
• X<>Y is the "X exchange Y" stack operation
01 STO 5 26 * 51 STO 5 76 +
02 1 27 - 52 g SQRT 77 -
03 STO 6 28 g SQRT 53 X<>Y 78 g X=0?
04 RCL 5 29 g GTO 00 54 1 79 g GTO 82
05 RCL 5 30 ENTER 55 - 80 g LSTX
06 CHS 31 ENTER 56 g X=0? 81 g GTO 66
07 STO 5 32 * 57 g GTO 59 82 RCL 4
08 RCL 6 33 1 58 g GTO 39 83 g X<=Y?
09 2 34 + 59 g n! 84 g GTO 89
10 + 35 g SQRT 60 STO 6 85 g LSTX
11 STO 6 36 / 61 RCL 5 86 8
12 Y^X 37 STO 4 62 - 87 *
13 g LSTX 38 3 63 g SQRT 88 g GTO 00
14 g n! 39 X<>Y 64 / 89 g LST X
15 / 40 ENTER 65 STO 5 90 CHS
16 + 41 * 66 RCL 5 91 g GTO 86
17 - 42 CHS 67 CHS 92 CLX
18 g X=0? 43 1 68 STO 5 93 ENTER
19 g GTO 22 44 + 69 RCL 6 94 *
20 g LSTX 45 g SQRT 70 2 95 CHS
21 g GTO 05 46 CHS 71 + 96 1
22 g LSTX 47 1 72 STO 6 97 +
23 1 48 + 73 Y^X 98 g SQRT
24 g LSTX 49 2 74 g LSTX 99 g GTO 37
25 g LSTX 50 / 75 /
Implementation details
• steps 01-22 compute Sin(x) by using its Taylor Series Expansion:
Sin(x) = x - x^3/3! + x^5/5! - x^7/7! + ...
the stopping criterium being that the contribution of a new term to the running
sum does not change its value at all. This ensures maximum accuracy and
fastest running time because only as many terms as needed for full accuracy are
used. This approach allows also a wide valid input range from –5*Pi to +5*Pi.
DATAFILE V21 N1 Page 15
• steps 23-28 compute Cos(x) by using the formula: Cos(x) = Sqrt(1-Sin(x)^2)
As the square root is always taken in its positive value, this restricts the input
range for Cos(x) to the usual range from –Pi/2 to +Pi/2. If you need to compute
a cosine for values outside that range, either perform previously a range
reduction or else compute it using the formula:
Cos(x) = Sin(x + Pi/2)
The reason for not using this formula instead of the one used in the program is
that this requires having Pi/2 available, which means either recomputing it each
time, doubling processing time, or else requires some initialization and using a
dedicated register to hold it.
• steps 30-36 compute ArcTan(x) by using the formula:
ArcTan(x) = ArcSin(x/Sqrt(1+x^2))
this ensures that the full range -Infinity to +Infinity can be used for the
argument.
• steps 37-91 compute ArcSin(x). To guarantee fast convergence for all x, a
suitable scaling of the input value is previously performed, followed by a
change of variable, and finally a Taylor Series Expansion is used to generate an
intermediate result, which is then scaled back to give the final result.
• steps 37, 82-84 and 89-91 make sure the result has the correct sign in all cases.
• steps 92 computes Pi/2 using the formula: Pi/2 = ArcCos(0)
• steps 93-99 compute ArcCos(x) using the formula
ArcCos(x) = ArcSin(Sqrt(1-x^2))
As the square root is always taken in its positive value, this restricts the input range
to values of x from 0 to 1, both included. Should you need to compute the arc
cosine of a negative x value, you can use the formula:
As before, this formula was not used because it does require having Pi/2 available,
which means either recomputing it each time, doubling processing time, or else it
requires initialization and using a dedicated register to hold it and there's always
the risk of the value being lost if its dedicated register is cleared or overwritten
inadvertently.
You can test that the program is loaded correctly, and its accuracy by checking
these results, shown as they are displayed in FIX 9 (f 9 in the 12C):
Usage instructions
As the 12C doesn't have user labels, these are the entry points to compute the
functions, with the argument X assumed to be in the display (X-register):
Example 1
Find all 5 real roots of the quintic: 16 x^5 - 180 x^3 + 405 x -136 = 0
Though 5th-degree equations (a.k.a. quintics) are not in general soluble by
algebraic means, after some fruitful and enjoyable labour of mathematical creation
I came to this neat expression for its 5 real roots:
Note that we'll need to compute the sine of arguments exceeding Pi/2, but this is no
problem for our program, so let's compute all roots on our 12C easily by following
these steps:
1. As we will need Pi frequently, first we'll store a copy of it in R0:
4. Encouraged by the success, we go now after the second root, which is:
x2 = 3 * Sin[ (u + 2*Pi) / 5 ]:
5. The remaining roots are computed likewise, and their values are:
6. Finally, we test the correctness of the roots and their accuracy by computing
their sum and their product. The results for our computed roots are:
So you see, after a long chain of trigonometric calculations (21 in all) and for quite
sizable arguments (>2.63), we've got excellent accuracy throughout (9-10 correct
digits for the roots).
Example 2
Check the equality: Tan 50º + Tan 60 º + Tan 70 º = Tan 50º * Tan 60º * Tan 70º
i.e: the sum of their tangents is the same as the product of their tangents. As the angles
are expressed in degrees, we'll have to convert them to radians on the fly. Let's follow
these steps:
1. We'll need the conversion factor Pi/180 = (Pi/2)/90, which we'll store in R0:
and we see that the results agree to 1 unit in the 8th position, so we may say
confident that the equality holds.
[Valentin wrote this article in time for the HP-12C anniversary issue (V20N5) but
there was insufficient space to include it and I preferred to publish his excellent
HP-11C article instead, since it was its anniversary as well. Needless to say, he
was mortified to discover, upon reading the issue, that Wlodek planned to write a
follow-up article on providing scientific functions, including trig, for the HP-12C.
In a similar vein, Wlodek wrote his article in time for the V20N6 which was the
Newton-themed, November – December 2000 issue, hence the reference to the
theme in the article and, once again, I was unable to include it due to pressure of
space.
I therefore wish to take pains to point out that neither Wlodek nor Valentin have
seen each others’ articles. Any similarities are a consequence of chance or a result
of the constraints imposed by the limitations of the HP-12C.
Thus, while there may be some overlap in material, I trust that your enjoyment of
either article – Wlodek’s follows – will not be spoilt. Ed.]