|HP-33s/35s trigonometric bug tabulated|
Message #27 Posted by Karl Schneider on 1 Sept 2007, 1:58 a.m.,
in response to message #1 by Lyuka
As you correctly point out in a subsequent post in this thread,
cosine of 1.57079632000 radians is 6.79489661923e-9 with 12 digits of accuracy.
This is easy to show:
cos (y - x) = cos(y)*cos(x) + sin(y)*sin(x)
cos (pi/2 - x) = cos(pi/2)*cos(x) + sin(pi/2)*sin(x)
= 0 * cos(x) + 1 * sin(x)
Let x represent the "missing" digits of pi/2. The calculation of cosine (pi/2 - x) in radians will yield sine (x), which will be extremely close to x for very small values of x. Hence, cosine "fills in" the missing digits of pi/2.
This calculation is very similar to sin (pi - x) for small x, where sine "fills in" the missing digits of pi. I've discussed that one a few times as a good example of the algorithmic accuracy introduced with the Saturn processor for 1984 in the HP-71B.
Here's a discussion of the "cosine bug" in the HP-33s and HP-35s, in which the accuracy of cosine for arguments near 90 degrees is erratic -- losing significant digits one by one as the input gets closer to 90 (e.g., 89.9999), then suddenly becoming more accurate as x gets to almost 90 degrees:
(See Bill Platt's post -- message #14 in that thread.)
Given those findings, it's reasonable that the calculation of cosine in radians mode also loses significant digits on these models as the argument nears zero, because an argument in degrees must be converted to radians. There's definitely a flaw in the algorithm; it seems to be terminating prematurely in some cases.
HP calculators with pre-Saturn microprocessors (e.g., HP-15C) and many modern calculators from other manufacturers (e.g, TI-82) sometimes give only two significant digits for the sine and cosine calculations described. I suspect that they calculate out to their internal precision of three guard digits, round the answer to the second guard digit and "call it good", without recognizing that even more digits could be calculated due to the small magnitude of the result. Example:
input |guard| extra
On any Pioneer-series model and some descendants, you get 9.79323846264e-12 as the result. On some newer 12-digit non-HP's, you might get 9.8e-12 as the result.
Here's a table of results for sin(pi - x) and cos(pi/2 - x) in radians:
pi - x sin(pi - x) ~= x
HP-32SII HP-33s/HP-35s ULP error
3.1 4.15806624333E-02 4.15806624333E-02 0
3.14 1.59265291649E-03 1.59265291648E-03 1
3.141 5.92653555099E-04 5.92653555096E-04 3
3.1415 9.26535896607E-05 9.26535896582E-05 25
3.14159 2.65358979324E-06 2.65358979000E-06 324
3.141592 6.53589793238E-07 6.53589790000E-07 3238
3.1415926 5.35897932384E-08 5.35897900000E-08 32384
3.14159265 3.58979323846E-09 3.58979000000E-09 323846
3.141592653 5.89793238463E-10 5.89793238463E-10 0
3.1415926535 8.97932384626E-11 8.97932384626E-11 0
3.14159265358 9.79323846264E-12 9.79323846264E-12 0
pi/2 - x cos(pi/2 - x) ~= x
HP-32SII HP-33s/HP-35s ULP error
1.5 7.07372016677E-02 7.07372016677E-02 0
1.57 7.96326710733E-04 7.96326710728E-04 5
1.570 7.96326710733E-04 7.96326710728E-04 5
1.5707 9.63267947477E-05 9.63267947464E-05 13
1.57079 6.32679489658E-06 6.32679488998E-06 660
1.570796 3.26794896619E-07 3.26794890000E-07 6619
1.5707963 2.67948966192E-08 2.67948900000E-08 66192
1.57079632 6.79489661923E-09 6.79489000000E-09 661923
1.570796326 7.94896619231E-10 7.94896619231E-10 0
1.5707963267 9.48966192313E-11 9.48966192313E-11 0
1.57079632679 4.89661923132E-12 4.89661923132E-12 0
The patterns are remarkably similar: As the number of digits in the input increases, small errors in the lowest-order digits of the results occur and grow, then significant digits are lost, then finally the answers become correct.
Note that, for each result of less than 12 significant digits, the input and result combine for 15 digits that are not trailing zeroes. This probably stems from the 12 digits of the returned result and the three guard digits.
Edited: 7 Sept 2007, 12:54 a.m. after one or more responses were posted