5 * Copyright (C) 1999 - 2007 Michael C. Ring
7 * Permission to use, copy, and distribute this software and its
8 * documentation for any purpose with or without fee is hereby granted,
9 * provided that the above copyright notice appear in all copies and
10 * that both that copyright notice and this permission notice appear
11 * in supporting documentation.
13 * Permission to modify the software is granted. Permission to distribute
14 * the modified code is granted. Modifications are to be distributed by
15 * using the file 'license.txt' as a template to modify the file header.
16 * 'license.txt' is available in the official MAPM distribution.
18 * This software is provided "as is" without express or implied warranty.
22 * $Id: mapmrsin.c,v 1.8 2007/12/03 01:57:00 mike Exp $
24 * This file contains the basic series expansion functions for
25 * the SIN / COS functions.
27 * $Log: mapmrsin.c,v $
28 * Revision 1.8 2007/12/03 01:57:00 mike
31 * Revision 1.7 2003/06/08 18:22:09 mike
32 * optimize the raw sin algorithm
34 * Revision 1.6 2002/11/03 21:58:27 mike
35 * Updated function parameters to use the modern style
37 * Revision 1.5 2001/07/10 22:14:43 mike
38 * optimize raw_sin & cos by using fewer digits
39 * as subsequent terms get smaller
41 * Revision 1.4 2000/03/30 21:53:48 mike
42 * change compare to terminate series expansion using ints instead
45 * Revision 1.3 1999/06/20 16:23:10 mike
46 * changed local static variables to MAPM stack variables
48 * Revision 1.2 1999/05/12 21:06:36 mike
49 * changed global var names
51 * Revision 1.1 1999/05/10 20:56:31 mike
57 /****************************************************************************/
60 sin(x) = x - --- + --- - --- + --- ...
63 void M_raw_sin(M_APM rr
, int places
, M_APM xx
)
65 M_APM sum
, term
, tmp2
, tmp7
, tmp8
;
66 int tolerance
, flag
, local_precision
, dplaces
;
69 sum
= M_get_stack_var();
70 term
= M_get_stack_var();
71 tmp2
= M_get_stack_var();
72 tmp7
= M_get_stack_var();
73 tmp8
= M_get_stack_var();
77 m_apm_multiply(tmp8
, xx
, xx
);
78 m_apm_round(tmp2
, (places
+ 6), tmp8
);
80 dplaces
= (places
+ 8) - xx
->m_apm_exponent
;
81 tolerance
= xx
->m_apm_exponent
- (places
+ 4);
88 m_apm_multiply(tmp8
, term
, tmp2
);
90 if ((tmp8
->m_apm_exponent
< tolerance
) || (tmp8
->m_apm_sign
== 0))
93 local_precision
= dplaces
+ term
->m_apm_exponent
;
95 if (local_precision
< 20)
99 m_apm_set_long(tmp7
, m2
);
101 m_apm_divide(term
, local_precision
, tmp8
, tmp7
);
105 m_apm_subtract(tmp7
, sum
, term
);
106 m_apm_copy(sum
, tmp7
);
110 m_apm_add(tmp7
, sum
, term
);
111 m_apm_copy(sum
, tmp7
);
118 m_apm_round(rr
, places
, sum
);
121 /****************************************************************************/
124 cos(x) = 1 - --- + --- - --- + --- ...
127 void M_raw_cos(M_APM rr
, int places
, M_APM xx
)
129 M_APM sum
, term
, tmp7
, tmp8
, tmp9
;
130 int tolerance
, flag
, local_precision
, prev_exp
;
133 sum
= M_get_stack_var();
134 term
= M_get_stack_var();
135 tmp7
= M_get_stack_var();
136 tmp8
= M_get_stack_var();
137 tmp9
= M_get_stack_var();
139 m_apm_copy(sum
, MM_One
);
140 m_apm_copy(term
, MM_One
);
142 m_apm_multiply(tmp8
, xx
, xx
);
143 m_apm_round(tmp9
, (places
+ 6), tmp8
);
145 local_precision
= places
+ 8;
146 tolerance
= -(places
+ 4);
155 m_apm_set_long(tmp7
, m2
);
157 m_apm_multiply(tmp8
, term
, tmp9
);
158 m_apm_divide(term
, local_precision
, tmp8
, tmp7
);
162 m_apm_subtract(tmp7
, sum
, term
);
163 m_apm_copy(sum
, tmp7
);
167 m_apm_add(tmp7
, sum
, term
);
168 m_apm_copy(sum
, tmp7
);
171 if ((term
->m_apm_exponent
< tolerance
) || (term
->m_apm_sign
== 0))
176 local_precision
= local_precision
+ term
->m_apm_exponent
- prev_exp
;
178 if (local_precision
< 20)
179 local_precision
= 20;
182 prev_exp
= term
->m_apm_exponent
;
188 m_apm_round(rr
, places
, sum
);
191 /****************************************************************************/