xref: /reactos/base/applications/calc/fun_mpfr.c (revision 295eaf4e)
1*295eaf4eSCarlo-Bramini /*
2*295eaf4eSCarlo-Bramini  * ReactOS Calc (Math functions, GMP/MPFR engine)
3*295eaf4eSCarlo-Bramini  *
4*295eaf4eSCarlo-Bramini  * Copyright 2007-2017, Carlo Bramini
5*295eaf4eSCarlo-Bramini  *
6*295eaf4eSCarlo-Bramini  * This program is free software; you can redistribute it and/or
7*295eaf4eSCarlo-Bramini  * modify it under the terms of the GNU Lesser General Public
8*295eaf4eSCarlo-Bramini  * License as published by the Free Software Foundation; either
9*295eaf4eSCarlo-Bramini  * version 2 of the License, or (at your option) any later version.
10*295eaf4eSCarlo-Bramini  *
11*295eaf4eSCarlo-Bramini  * This library is distributed in the hope that it will be useful,
12*295eaf4eSCarlo-Bramini  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13*295eaf4eSCarlo-Bramini  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14*295eaf4eSCarlo-Bramini  * Lesser General Public License for more details.
15*295eaf4eSCarlo-Bramini  *
16*295eaf4eSCarlo-Bramini  * You should have received a copy of the GNU Lesser General Public
17*295eaf4eSCarlo-Bramini  * License along with this library; if not, write to the Free Software
18*295eaf4eSCarlo-Bramini  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19*295eaf4eSCarlo-Bramini  */
20*295eaf4eSCarlo-Bramini 
21c2c66affSColin Finck #include "calc.h"
22c2c66affSColin Finck 
23*295eaf4eSCarlo-Bramini static void validate_rad2angle(calc_number_t *c);
24*295eaf4eSCarlo-Bramini static void validate_angle2rad(calc_number_t *c);
25*295eaf4eSCarlo-Bramini 
apply_int_mask(calc_number_t * r)26c2c66affSColin Finck void apply_int_mask(calc_number_t *r)
27c2c66affSColin Finck {
28c2c66affSColin Finck     mpz_t a, mask;
29c2c66affSColin Finck 
30c2c66affSColin Finck     switch (calc.size) {
31c2c66affSColin Finck     case IDC_RADIO_QWORD:
32c2c66affSColin Finck         mpz_init_set_str(mask, "FFFFFFFFFFFFFFFF", 16);
33c2c66affSColin Finck         break;
34c2c66affSColin Finck     case IDC_RADIO_DWORD:
35c2c66affSColin Finck         mpz_init_set_str(mask, "00000000FFFFFFFF", 16);
36c2c66affSColin Finck         break;
37c2c66affSColin Finck     case IDC_RADIO_WORD:
38c2c66affSColin Finck         mpz_init_set_str(mask, "000000000000FFFF", 16);
39c2c66affSColin Finck         break;
40c2c66affSColin Finck     case IDC_RADIO_BYTE:
41c2c66affSColin Finck         mpz_init_set_str(mask, "00000000000000FF", 16);
42c2c66affSColin Finck         break;
43c2c66affSColin Finck     default:
44c2c66affSColin Finck         mpz_init_set_si(mask, -1);
45c2c66affSColin Finck     }
46c2c66affSColin Finck     mpz_init(a);
47c2c66affSColin Finck     mpfr_get_z(a, r->mf, MPFR_DEFAULT_RND);
48c2c66affSColin Finck     mpz_and(a, a, mask);
49c2c66affSColin Finck     mpfr_set_z(r->mf, a, MPFR_DEFAULT_RND);
50c2c66affSColin Finck     mpz_clear(a);
51c2c66affSColin Finck     mpz_clear(mask);
52c2c66affSColin Finck }
53c2c66affSColin Finck 
validate_rad2angle(calc_number_t * r)54*295eaf4eSCarlo-Bramini static void validate_rad2angle(calc_number_t *r)
55c2c66affSColin Finck {
56c2c66affSColin Finck     mpfr_t mult, divs;
57c2c66affSColin Finck 
58c2c66affSColin Finck     mpfr_init(mult);
59c2c66affSColin Finck     mpfr_init(divs);
60c2c66affSColin Finck     switch (calc.degr) {
61c2c66affSColin Finck     case IDC_RADIO_DEG:
62c2c66affSColin Finck         mpfr_set_ui(mult, 180, MPFR_DEFAULT_RND);
63c2c66affSColin Finck         mpfr_const_pi(divs, MPFR_DEFAULT_RND);
64c2c66affSColin Finck         break;
65c2c66affSColin Finck     case IDC_RADIO_RAD:
66c2c66affSColin Finck         mpfr_set_ui(mult, 1, MPFR_DEFAULT_RND);
67c2c66affSColin Finck         mpfr_set_ui(divs, 1, MPFR_DEFAULT_RND);
68c2c66affSColin Finck         break;
69c2c66affSColin Finck     case IDC_RADIO_GRAD:
70c2c66affSColin Finck         mpfr_set_ui(mult, 200, MPFR_DEFAULT_RND);
71c2c66affSColin Finck         mpfr_const_pi(divs, MPFR_DEFAULT_RND);
72c2c66affSColin Finck         break;
73c2c66affSColin Finck     }
74c2c66affSColin Finck     mpfr_mul(r->mf, r->mf, mult, MPFR_DEFAULT_RND);
75c2c66affSColin Finck     mpfr_div(r->mf, r->mf, divs, MPFR_DEFAULT_RND);
76c2c66affSColin Finck 
77c2c66affSColin Finck     mpfr_clear(mult);
78c2c66affSColin Finck     mpfr_clear(divs);
79c2c66affSColin Finck }
80c2c66affSColin Finck 
validate_angle2rad(calc_number_t * r)81*295eaf4eSCarlo-Bramini static void validate_angle2rad(calc_number_t *r)
82c2c66affSColin Finck {
83c2c66affSColin Finck     mpfr_t mult, divs;
84c2c66affSColin Finck 
85c2c66affSColin Finck     if (!mpfr_number_p(r->mf)) {
86c2c66affSColin Finck         calc.is_nan = TRUE;
87c2c66affSColin Finck         return;
88c2c66affSColin Finck     }
89c2c66affSColin Finck     mpfr_init(mult);
90c2c66affSColin Finck     mpfr_init(divs);
91c2c66affSColin Finck     switch (calc.degr) {
92c2c66affSColin Finck     case IDC_RADIO_DEG:
93c2c66affSColin Finck         mpfr_const_pi(mult, MPFR_DEFAULT_RND);
94c2c66affSColin Finck         mpfr_set_ui(divs, 180, MPFR_DEFAULT_RND);
95c2c66affSColin Finck         break;
96c2c66affSColin Finck     case IDC_RADIO_RAD:
97c2c66affSColin Finck         mpfr_set_ui(mult, 1, MPFR_DEFAULT_RND);
98c2c66affSColin Finck         mpfr_set_ui(divs, 1, MPFR_DEFAULT_RND);
99c2c66affSColin Finck         break;
100c2c66affSColin Finck     case IDC_RADIO_GRAD:
101c2c66affSColin Finck         mpfr_const_pi(mult, MPFR_DEFAULT_RND);
102c2c66affSColin Finck         mpfr_set_ui(divs, 200, MPFR_DEFAULT_RND);
103c2c66affSColin Finck         break;
104c2c66affSColin Finck     }
105c2c66affSColin Finck     mpfr_mul(r->mf, r->mf, mult, MPFR_DEFAULT_RND);
106c2c66affSColin Finck     mpfr_div(r->mf, r->mf, divs, MPFR_DEFAULT_RND);
107c2c66affSColin Finck 
108c2c66affSColin Finck     mpfr_clear(mult);
109c2c66affSColin Finck     mpfr_clear(divs);
110c2c66affSColin Finck }
111c2c66affSColin Finck 
build_rad_const(mpfr_t * mp_pi,mpfr_t * mp_pi_2,mpfr_t * mp_3_pi_2,mpfr_t * mp_2_pi)112c2c66affSColin Finck static void build_rad_const(
113c2c66affSColin Finck     mpfr_t *mp_pi,
114c2c66affSColin Finck     mpfr_t *mp_pi_2,
115c2c66affSColin Finck     mpfr_t *mp_3_pi_2,
116c2c66affSColin Finck     mpfr_t *mp_2_pi)
117c2c66affSColin Finck {
118c2c66affSColin Finck     mpfr_init(*mp_pi);
119c2c66affSColin Finck     mpfr_init(*mp_pi_2);
120c2c66affSColin Finck     mpfr_init(*mp_3_pi_2);
121c2c66affSColin Finck     mpfr_init(*mp_2_pi);
122c2c66affSColin Finck     mpfr_const_pi(*mp_pi, MPFR_DEFAULT_RND);
123c2c66affSColin Finck     mpfr_div_ui(*mp_pi_2, *mp_pi, 2, MPFR_DEFAULT_RND);
124c2c66affSColin Finck     mpfr_mul_ui(*mp_3_pi_2, *mp_pi, 3, MPFR_DEFAULT_RND);
125c2c66affSColin Finck     mpfr_div_ui(*mp_3_pi_2, *mp_3_pi_2, 2, MPFR_DEFAULT_RND);
126c2c66affSColin Finck     mpfr_mul_ui(*mp_2_pi, *mp_pi, 2, MPFR_DEFAULT_RND);
127c2c66affSColin Finck }
128c2c66affSColin Finck 
rpn_sin(calc_number_t * c)129c2c66affSColin Finck void rpn_sin(calc_number_t *c)
130c2c66affSColin Finck {
131c2c66affSColin Finck     mpfr_t mp_pi, mp_pi_2, mp_3_pi_2, mp_2_pi;
132c2c66affSColin Finck 
133c2c66affSColin Finck     validate_angle2rad(c);
134c2c66affSColin Finck     build_rad_const(&mp_pi, &mp_pi_2, &mp_3_pi_2, &mp_2_pi);
135c2c66affSColin Finck 
136c2c66affSColin Finck     if (rpn_is_zero(c) || !mpfr_cmp(c->mf, mp_pi) || !mpfr_cmp(c->mf, mp_2_pi))
137c2c66affSColin Finck         rpn_zero(c);
138c2c66affSColin Finck     else
139c2c66affSColin Finck     if (!mpfr_cmp(c->mf, mp_3_pi_2))
140c2c66affSColin Finck         mpfr_set_si(c->mf, -1, MPFR_DEFAULT_RND);
141c2c66affSColin Finck     else
142c2c66affSColin Finck     if (!mpfr_cmp(c->mf, mp_pi_2))
143c2c66affSColin Finck         mpfr_set_si(c->mf, 1, MPFR_DEFAULT_RND);
144c2c66affSColin Finck     else {
145c2c66affSColin Finck         mpfr_sin(c->mf, c->mf, MPFR_DEFAULT_RND);
146c2c66affSColin Finck         if (!mpfr_number_p(c->mf)) calc.is_nan = TRUE;
147c2c66affSColin Finck     }
148c2c66affSColin Finck     mpfr_clear(mp_pi);
149c2c66affSColin Finck     mpfr_clear(mp_pi_2);
150c2c66affSColin Finck     mpfr_clear(mp_3_pi_2);
151c2c66affSColin Finck     mpfr_clear(mp_2_pi);
152c2c66affSColin Finck }
rpn_cos(calc_number_t * c)153c2c66affSColin Finck void rpn_cos(calc_number_t *c)
154c2c66affSColin Finck {
155c2c66affSColin Finck     mpfr_t mp_pi, mp_pi_2, mp_3_pi_2, mp_2_pi;
156c2c66affSColin Finck 
157c2c66affSColin Finck     validate_angle2rad(c);
158c2c66affSColin Finck     build_rad_const(&mp_pi, &mp_pi_2, &mp_3_pi_2, &mp_2_pi);
159c2c66affSColin Finck 
160c2c66affSColin Finck     if (!mpfr_cmp(c->mf, mp_pi_2) || !mpfr_cmp(c->mf, mp_3_pi_2))
161c2c66affSColin Finck         rpn_zero(c);
162c2c66affSColin Finck     else
163c2c66affSColin Finck     if (!mpfr_cmp(c->mf, mp_pi))
164c2c66affSColin Finck         mpfr_set_si(c->mf, -1, MPFR_DEFAULT_RND);
165c2c66affSColin Finck     else
166c2c66affSColin Finck     if (!mpfr_cmp(c->mf, mp_2_pi))
167c2c66affSColin Finck         mpfr_set_si(c->mf, 1, MPFR_DEFAULT_RND);
168c2c66affSColin Finck     else {
169c2c66affSColin Finck         mpfr_cos(c->mf, c->mf, MPFR_DEFAULT_RND);
170c2c66affSColin Finck         if (!mpfr_number_p(c->mf)) calc.is_nan = TRUE;
171c2c66affSColin Finck     }
172c2c66affSColin Finck     mpfr_clear(mp_pi);
173c2c66affSColin Finck     mpfr_clear(mp_pi_2);
174c2c66affSColin Finck     mpfr_clear(mp_3_pi_2);
175c2c66affSColin Finck     mpfr_clear(mp_2_pi);
176c2c66affSColin Finck }
rpn_tan(calc_number_t * c)177c2c66affSColin Finck void rpn_tan(calc_number_t *c)
178c2c66affSColin Finck {
179c2c66affSColin Finck     mpfr_t mp_pi, mp_pi_2, mp_3_pi_2, mp_2_pi;
180c2c66affSColin Finck 
181c2c66affSColin Finck     validate_angle2rad(c);
182c2c66affSColin Finck     build_rad_const(&mp_pi, &mp_pi_2, &mp_3_pi_2, &mp_2_pi);
183c2c66affSColin Finck 
184c2c66affSColin Finck     if (!mpfr_cmp(c->mf, mp_pi_2) || !mpfr_cmp(c->mf, mp_3_pi_2))
185c2c66affSColin Finck         calc.is_nan = TRUE;
186c2c66affSColin Finck     else
187c2c66affSColin Finck     if (!mpfr_cmp(c->mf, mp_pi) || !mpfr_cmp(c->mf, mp_2_pi))
188c2c66affSColin Finck         rpn_zero(c);
189c2c66affSColin Finck     else {
190c2c66affSColin Finck         mpfr_tan(c->mf, c->mf, MPFR_DEFAULT_RND);
191c2c66affSColin Finck         if (!mpfr_number_p(c->mf)) calc.is_nan = TRUE;
192c2c66affSColin Finck     }
193c2c66affSColin Finck     mpfr_clear(mp_pi);
194c2c66affSColin Finck     mpfr_clear(mp_pi_2);
195c2c66affSColin Finck     mpfr_clear(mp_3_pi_2);
196c2c66affSColin Finck     mpfr_clear(mp_2_pi);
197c2c66affSColin Finck }
198c2c66affSColin Finck 
rpn_asin(calc_number_t * c)199c2c66affSColin Finck void rpn_asin(calc_number_t *c)
200c2c66affSColin Finck {
201c2c66affSColin Finck     mpfr_asin(c->mf, c->mf, MPFR_DEFAULT_RND);
202c2c66affSColin Finck     validate_rad2angle(c);
203c2c66affSColin Finck }
rpn_acos(calc_number_t * c)204c2c66affSColin Finck void rpn_acos(calc_number_t *c)
205c2c66affSColin Finck {
206c2c66affSColin Finck     mpfr_acos(c->mf, c->mf, MPFR_DEFAULT_RND);
207c2c66affSColin Finck     validate_rad2angle(c);
208c2c66affSColin Finck }
rpn_atan(calc_number_t * c)209c2c66affSColin Finck void rpn_atan(calc_number_t *c)
210c2c66affSColin Finck {
211c2c66affSColin Finck     mpfr_atan(c->mf, c->mf, MPFR_DEFAULT_RND);
212c2c66affSColin Finck     validate_rad2angle(c);
213c2c66affSColin Finck }
214c2c66affSColin Finck 
rpn_sinh(calc_number_t * c)215c2c66affSColin Finck void rpn_sinh(calc_number_t *c)
216c2c66affSColin Finck {
217c2c66affSColin Finck     mpfr_sinh(c->mf, c->mf, MPFR_DEFAULT_RND);
218c2c66affSColin Finck     if (!mpfr_number_p(c->mf)) calc.is_nan = TRUE;
219c2c66affSColin Finck }
rpn_cosh(calc_number_t * c)220c2c66affSColin Finck void rpn_cosh(calc_number_t *c)
221c2c66affSColin Finck {
222c2c66affSColin Finck     mpfr_cosh(c->mf, c->mf, MPFR_DEFAULT_RND);
223c2c66affSColin Finck     if (!mpfr_number_p(c->mf)) calc.is_nan = TRUE;
224c2c66affSColin Finck }
rpn_tanh(calc_number_t * c)225c2c66affSColin Finck void rpn_tanh(calc_number_t *c)
226c2c66affSColin Finck {
227c2c66affSColin Finck     mpfr_tanh(c->mf, c->mf, MPFR_DEFAULT_RND);
228c2c66affSColin Finck     if (!mpfr_number_p(c->mf)) calc.is_nan = TRUE;
229c2c66affSColin Finck }
230c2c66affSColin Finck 
rpn_asinh(calc_number_t * c)231c2c66affSColin Finck void rpn_asinh(calc_number_t *c)
232c2c66affSColin Finck {
233c2c66affSColin Finck     mpfr_asinh(c->mf, c->mf, MPFR_DEFAULT_RND);
234c2c66affSColin Finck     if (!mpfr_number_p(c->mf)) calc.is_nan = TRUE;
235c2c66affSColin Finck }
rpn_acosh(calc_number_t * c)236c2c66affSColin Finck void rpn_acosh(calc_number_t *c)
237c2c66affSColin Finck {
238c2c66affSColin Finck     mpfr_acosh(c->mf, c->mf, MPFR_DEFAULT_RND);
239c2c66affSColin Finck     if (!mpfr_number_p(c->mf)) calc.is_nan = TRUE;
240c2c66affSColin Finck }
rpn_atanh(calc_number_t * c)241c2c66affSColin Finck void rpn_atanh(calc_number_t *c)
242c2c66affSColin Finck {
243c2c66affSColin Finck     mpfr_atanh(c->mf, c->mf, MPFR_DEFAULT_RND);
244c2c66affSColin Finck     if (!mpfr_number_p(c->mf)) calc.is_nan = TRUE;
245c2c66affSColin Finck }
246c2c66affSColin Finck 
rpn_int(calc_number_t * c)247c2c66affSColin Finck void rpn_int(calc_number_t *c)
248c2c66affSColin Finck {
249c2c66affSColin Finck     mpfr_trunc(c->mf, c->mf);
250c2c66affSColin Finck }
251c2c66affSColin Finck 
rpn_frac(calc_number_t * c)252c2c66affSColin Finck void rpn_frac(calc_number_t *c)
253c2c66affSColin Finck {
254c2c66affSColin Finck     mpfr_frac(c->mf, c->mf, MPFR_DEFAULT_RND);
255c2c66affSColin Finck }
256c2c66affSColin Finck 
rpn_reci(calc_number_t * c)257c2c66affSColin Finck void rpn_reci(calc_number_t *c)
258c2c66affSColin Finck {
259c2c66affSColin Finck     if (mpfr_sgn(c->mf) == 0)
260c2c66affSColin Finck         calc.is_nan = TRUE;
261c2c66affSColin Finck     else
262c2c66affSColin Finck         mpfr_ui_div(c->mf, 1, c->mf, MPFR_DEFAULT_RND);
263c2c66affSColin Finck }
264c2c66affSColin Finck 
rpn_fact(calc_number_t * c)265c2c66affSColin Finck void rpn_fact(calc_number_t *c)
266c2c66affSColin Finck {
267c2c66affSColin Finck     if (mpfr_sgn(c->mf) < 0) {
268c2c66affSColin Finck         calc.is_nan = TRUE;
269c2c66affSColin Finck         return;
270c2c66affSColin Finck     }
271c2c66affSColin Finck 
272c2c66affSColin Finck     mpfr_trunc(c->mf, c->mf);
273c2c66affSColin Finck     if (mpfr_fits_ulong_p(c->mf, MPFR_DEFAULT_RND) == 0)
274c2c66affSColin Finck         calc.is_nan = TRUE;
275c2c66affSColin Finck     else {
276c2c66affSColin Finck         mpfr_fac_ui(c->mf, mpfr_get_ui(c->mf, MPFR_DEFAULT_RND), MPFR_DEFAULT_RND);
277c2c66affSColin Finck         if (!mpfr_number_p(c->mf)) calc.is_nan = TRUE;
278c2c66affSColin Finck     }
279c2c66affSColin Finck }
280c2c66affSColin Finck 
rpn_not(calc_number_t * c)281c2c66affSColin Finck void rpn_not(calc_number_t *c)
282c2c66affSColin Finck {
283c2c66affSColin Finck     mpz_t a;
284c2c66affSColin Finck 
285c2c66affSColin Finck     mpz_init(a);
286c2c66affSColin Finck     mpfr_get_z(a, c->mf, MPFR_DEFAULT_RND);
287c2c66affSColin Finck     mpz_com(a, a);
288c2c66affSColin Finck     mpfr_set_z(c->mf, a, MPFR_DEFAULT_RND);
289c2c66affSColin Finck     mpz_clear(a);
290c2c66affSColin Finck }
291c2c66affSColin Finck 
rpn_pi(calc_number_t * c)292c2c66affSColin Finck void rpn_pi(calc_number_t *c)
293c2c66affSColin Finck {
294c2c66affSColin Finck     mpfr_const_pi(c->mf, MPFR_DEFAULT_RND);
295c2c66affSColin Finck }
296c2c66affSColin Finck 
rpn_2pi(calc_number_t * c)297c2c66affSColin Finck void rpn_2pi(calc_number_t *c)
298c2c66affSColin Finck {
299c2c66affSColin Finck     mpfr_const_pi(c->mf, MPFR_DEFAULT_RND);
300c2c66affSColin Finck     mpfr_mul_ui(c->mf, c->mf, 2, MPFR_DEFAULT_RND);
301c2c66affSColin Finck }
302c2c66affSColin Finck 
rpn_sign(calc_number_t * c)303c2c66affSColin Finck void rpn_sign(calc_number_t *c)
304c2c66affSColin Finck {
305c2c66affSColin Finck     mpfr_mul_si(c->mf, c->mf, -1, MPFR_DEFAULT_RND);
306c2c66affSColin Finck }
307c2c66affSColin Finck 
rpn_exp2(calc_number_t * c)308c2c66affSColin Finck void rpn_exp2(calc_number_t *c)
309c2c66affSColin Finck {
310c2c66affSColin Finck     mpfr_sqr(c->mf, c->mf, MPFR_DEFAULT_RND);
311c2c66affSColin Finck     if (!mpfr_number_p(c->mf)) calc.is_nan = TRUE;
312c2c66affSColin Finck }
313c2c66affSColin Finck 
rpn_exp3(calc_number_t * c)314c2c66affSColin Finck void rpn_exp3(calc_number_t *c)
315c2c66affSColin Finck {
316c2c66affSColin Finck     mpfr_pow_ui(c->mf, c->mf, 3, MPFR_DEFAULT_RND);
317c2c66affSColin Finck     if (!mpfr_number_p(c->mf)) calc.is_nan = TRUE;
318c2c66affSColin Finck }
319c2c66affSColin Finck 
rpn_sqrt(calc_number_t * c)320c2c66affSColin Finck void rpn_sqrt(calc_number_t *c)
321c2c66affSColin Finck {
322c2c66affSColin Finck     mpfr_sqrt(c->mf, c->mf, MPFR_DEFAULT_RND);
323c2c66affSColin Finck     if (!mpfr_number_p(c->mf)) calc.is_nan = TRUE;
324c2c66affSColin Finck }
325c2c66affSColin Finck 
rpn_cbrt(calc_number_t * c)326c2c66affSColin Finck void rpn_cbrt(calc_number_t *c)
327c2c66affSColin Finck {
328c2c66affSColin Finck     mpfr_cbrt(c->mf, c->mf, MPFR_DEFAULT_RND);
329c2c66affSColin Finck     if (!mpfr_number_p(c->mf)) calc.is_nan = TRUE;
330c2c66affSColin Finck }
331c2c66affSColin Finck 
rpn_exp(calc_number_t * c)332c2c66affSColin Finck void rpn_exp(calc_number_t *c)
333c2c66affSColin Finck {
334c2c66affSColin Finck     mpfr_exp(c->mf, c->mf, MPFR_DEFAULT_RND);
335c2c66affSColin Finck     if (!mpfr_number_p(c->mf)) calc.is_nan = TRUE;
336c2c66affSColin Finck }
337c2c66affSColin Finck 
rpn_exp10(calc_number_t * c)338c2c66affSColin Finck void rpn_exp10(calc_number_t *c)
339c2c66affSColin Finck {
340c2c66affSColin Finck     mpfr_exp10(c->mf, c->mf, MPFR_DEFAULT_RND);
341c2c66affSColin Finck     if (!mpfr_number_p(c->mf)) calc.is_nan = TRUE;
342c2c66affSColin Finck }
343c2c66affSColin Finck 
rpn_ln(calc_number_t * c)344c2c66affSColin Finck void rpn_ln(calc_number_t *c)
345c2c66affSColin Finck {
346c2c66affSColin Finck     mpfr_log(c->mf, c->mf, MPFR_DEFAULT_RND);
347c2c66affSColin Finck     if (!mpfr_number_p(c->mf)) calc.is_nan = TRUE;
348c2c66affSColin Finck }
349c2c66affSColin Finck 
rpn_log(calc_number_t * c)350c2c66affSColin Finck void rpn_log(calc_number_t *c)
351c2c66affSColin Finck {
352c2c66affSColin Finck     mpfr_log10(c->mf, c->mf, MPFR_DEFAULT_RND);
353c2c66affSColin Finck     if (!mpfr_number_p(c->mf)) calc.is_nan = TRUE;
354c2c66affSColin Finck }
355c2c66affSColin Finck 
stat_sum(mpfr_t sum)356c2c66affSColin Finck static void stat_sum(mpfr_t sum)
357c2c66affSColin Finck {
358c2c66affSColin Finck     statistic_t *p = calc.stat;
359c2c66affSColin Finck 
360c2c66affSColin Finck     mpfr_set_ui(sum, 0, MPFR_DEFAULT_RND);
361c2c66affSColin Finck     while (p != NULL) {
362c2c66affSColin Finck         mpfr_add(sum, sum, p->num.mf, MPFR_DEFAULT_RND);
363c2c66affSColin Finck         p = (statistic_t *)(p->next);
364c2c66affSColin Finck     }
365c2c66affSColin Finck }
366c2c66affSColin Finck 
stat_sum2(mpfr_t sum)367*295eaf4eSCarlo-Bramini static void stat_sum2(mpfr_t sum)
368*295eaf4eSCarlo-Bramini {
369*295eaf4eSCarlo-Bramini     statistic_t *p = calc.stat;
370*295eaf4eSCarlo-Bramini     mpfr_t       sqr;
371*295eaf4eSCarlo-Bramini 
372*295eaf4eSCarlo-Bramini     mpfr_init(sqr);
373*295eaf4eSCarlo-Bramini     mpfr_set_ui(sum, 0, MPFR_DEFAULT_RND);
374*295eaf4eSCarlo-Bramini     while (p != NULL) {
375*295eaf4eSCarlo-Bramini         mpfr_mul(sqr, p->num.mf, p->num.mf, MPFR_DEFAULT_RND);
376*295eaf4eSCarlo-Bramini         mpfr_add(sum, sum, sqr, MPFR_DEFAULT_RND);
377*295eaf4eSCarlo-Bramini         p = (statistic_t *)(p->next);
378*295eaf4eSCarlo-Bramini     }
379*295eaf4eSCarlo-Bramini     mpfr_clear(sqr);
380*295eaf4eSCarlo-Bramini }
381*295eaf4eSCarlo-Bramini 
rpn_ave(calc_number_t * c)382c2c66affSColin Finck void rpn_ave(calc_number_t *c)
383c2c66affSColin Finck {
384c2c66affSColin Finck     int     n;
385c2c66affSColin Finck 
386c2c66affSColin Finck     stat_sum(c->mf);
387c2c66affSColin Finck     n = SendDlgItemMessage(calc.hStatWnd, IDC_LIST_STAT, LB_GETCOUNT, 0, 0);
388c2c66affSColin Finck 
389c2c66affSColin Finck     if (n)
390c2c66affSColin Finck         mpfr_div_ui(c->mf, c->mf, n, MPFR_DEFAULT_RND);
391c2c66affSColin Finck 
392c2c66affSColin Finck     if (calc.base != IDC_RADIO_DEC)
393c2c66affSColin Finck         mpfr_trunc(c->mf, c->mf);
394c2c66affSColin Finck }
395c2c66affSColin Finck 
rpn_ave2(calc_number_t * c)396*295eaf4eSCarlo-Bramini void rpn_ave2(calc_number_t *c)
397*295eaf4eSCarlo-Bramini {
398*295eaf4eSCarlo-Bramini     int     n;
399*295eaf4eSCarlo-Bramini 
400*295eaf4eSCarlo-Bramini     stat_sum2(c->mf);
401*295eaf4eSCarlo-Bramini     n = SendDlgItemMessage(calc.hStatWnd, IDC_LIST_STAT, LB_GETCOUNT, 0, 0);
402*295eaf4eSCarlo-Bramini 
403*295eaf4eSCarlo-Bramini     if (n)
404*295eaf4eSCarlo-Bramini         mpfr_div_ui(c->mf, c->mf, n, MPFR_DEFAULT_RND);
405*295eaf4eSCarlo-Bramini 
406*295eaf4eSCarlo-Bramini     if (calc.base != IDC_RADIO_DEC)
407*295eaf4eSCarlo-Bramini         mpfr_trunc(c->mf, c->mf);
408*295eaf4eSCarlo-Bramini }
409*295eaf4eSCarlo-Bramini 
rpn_sum(calc_number_t * c)410c2c66affSColin Finck void rpn_sum(calc_number_t *c)
411c2c66affSColin Finck {
412c2c66affSColin Finck     stat_sum(c->mf);
413c2c66affSColin Finck 
414c2c66affSColin Finck     if (calc.base != IDC_RADIO_DEC)
415c2c66affSColin Finck         mpfr_trunc(c->mf, c->mf);
416c2c66affSColin Finck }
417c2c66affSColin Finck 
rpn_sum2(calc_number_t * c)418*295eaf4eSCarlo-Bramini void rpn_sum2(calc_number_t *c)
419*295eaf4eSCarlo-Bramini {
420*295eaf4eSCarlo-Bramini     stat_sum2(c->mf);
421*295eaf4eSCarlo-Bramini 
422*295eaf4eSCarlo-Bramini     if (calc.base != IDC_RADIO_DEC)
423*295eaf4eSCarlo-Bramini         mpfr_trunc(c->mf, c->mf);
424*295eaf4eSCarlo-Bramini }
425*295eaf4eSCarlo-Bramini 
rpn_s_ex(calc_number_t * c,int pop_type)426c2c66affSColin Finck static void rpn_s_ex(calc_number_t *c, int pop_type)
427c2c66affSColin Finck {
428c2c66affSColin Finck     mpfr_t        dev;
429c2c66affSColin Finck     mpfr_t        num;
430c2c66affSColin Finck     unsigned long n = 0;
431c2c66affSColin Finck     statistic_t  *p = calc.stat;
432c2c66affSColin Finck 
433c2c66affSColin Finck     n = SendDlgItemMessage(calc.hStatWnd, IDC_LIST_STAT, LB_GETCOUNT, 0, 0);
434c2c66affSColin Finck     if (n < 2) {
435c2c66affSColin Finck         mpfr_set_ui(c->mf, 0, MPFR_DEFAULT_RND);
436c2c66affSColin Finck         return;
437c2c66affSColin Finck     }
438c2c66affSColin Finck 
439c2c66affSColin Finck     stat_sum(c->mf);
440c2c66affSColin Finck     mpfr_div_ui(c->mf, c->mf, n, MPFR_DEFAULT_RND);
441c2c66affSColin Finck 
442c2c66affSColin Finck     mpfr_init(dev);
443c2c66affSColin Finck     mpfr_init(num);
444c2c66affSColin Finck 
445c2c66affSColin Finck     mpfr_set_ui(dev, 0, MPFR_DEFAULT_RND);
446c2c66affSColin Finck     p = calc.stat;
447c2c66affSColin Finck     while (p != NULL) {
448c2c66affSColin Finck         mpfr_sub(num, p->num.mf, c->mf, MPFR_DEFAULT_RND);
449c2c66affSColin Finck         mpfr_sqr(num, num, MPFR_DEFAULT_RND);
450c2c66affSColin Finck         mpfr_add(dev, dev, num, MPFR_DEFAULT_RND);
451c2c66affSColin Finck         p = (statistic_t *)(p->next);
452c2c66affSColin Finck     }
453c2c66affSColin Finck     mpfr_div_ui(c->mf, dev, pop_type ? n-1 : n, MPFR_DEFAULT_RND);
454c2c66affSColin Finck     mpfr_sqrt(c->mf, c->mf, MPFR_DEFAULT_RND);
455c2c66affSColin Finck 
456c2c66affSColin Finck     if (calc.base != IDC_RADIO_DEC)
457c2c66affSColin Finck         mpfr_trunc(c->mf, c->mf);
458c2c66affSColin Finck 
459c2c66affSColin Finck     mpfr_clear(dev);
460c2c66affSColin Finck     mpfr_clear(num);
461c2c66affSColin Finck }
462c2c66affSColin Finck 
rpn_s(calc_number_t * c)463c2c66affSColin Finck void rpn_s(calc_number_t *c)
464c2c66affSColin Finck {
465c2c66affSColin Finck     rpn_s_ex(c, 0);
466c2c66affSColin Finck }
467c2c66affSColin Finck 
rpn_s_m1(calc_number_t * c)468c2c66affSColin Finck void rpn_s_m1(calc_number_t *c)
469c2c66affSColin Finck {
470c2c66affSColin Finck     rpn_s_ex(c, 1);
471c2c66affSColin Finck }
472c2c66affSColin Finck 
rpn_dms2dec(calc_number_t * c)473c2c66affSColin Finck void rpn_dms2dec(calc_number_t *c)
474c2c66affSColin Finck {
475c2c66affSColin Finck     mpfr_t d, m, s;
476c2c66affSColin Finck 
477c2c66affSColin Finck     mpfr_init(d);
478c2c66affSColin Finck     mpfr_init(m);
479c2c66affSColin Finck     mpfr_init(s);
480c2c66affSColin Finck 
481c2c66affSColin Finck     mpfr_trunc(d, c->mf);
482c2c66affSColin Finck     mpfr_frac(m, c->mf, MPFR_DEFAULT_RND);
483c2c66affSColin Finck     mpfr_mul_ui(m, m, 100, MPFR_DEFAULT_RND);
484c2c66affSColin Finck 
485c2c66affSColin Finck     mpfr_frac(s, m, MPFR_DEFAULT_RND);
486c2c66affSColin Finck     mpfr_trunc(m, m);
487c2c66affSColin Finck     mpfr_mul_ui(s, s, 100, MPFR_DEFAULT_RND);
488c2c66affSColin Finck     mpfr_ceil(s, s);
489c2c66affSColin Finck 
490c2c66affSColin Finck     mpfr_div_ui(m, m, 60, MPFR_DEFAULT_RND);
491c2c66affSColin Finck     mpfr_div_ui(s, s, 3600, MPFR_DEFAULT_RND);
492c2c66affSColin Finck     mpfr_add(c->mf, d, m, MPFR_DEFAULT_RND);
493c2c66affSColin Finck     mpfr_add(c->mf, c->mf, s, MPFR_DEFAULT_RND);
494c2c66affSColin Finck 
495c2c66affSColin Finck     mpfr_clear(d);
496c2c66affSColin Finck     mpfr_clear(m);
497c2c66affSColin Finck     mpfr_clear(s);
498c2c66affSColin Finck }
499c2c66affSColin Finck 
rpn_dec2dms(calc_number_t * c)500c2c66affSColin Finck void rpn_dec2dms(calc_number_t *c)
501c2c66affSColin Finck {
502c2c66affSColin Finck     mpfr_t d, m, s;
503c2c66affSColin Finck 
504c2c66affSColin Finck     mpfr_init(d);
505c2c66affSColin Finck     mpfr_init(m);
506c2c66affSColin Finck     mpfr_init(s);
507c2c66affSColin Finck 
508c2c66affSColin Finck     mpfr_trunc(d, c->mf);
509c2c66affSColin Finck     mpfr_frac(m, c->mf, MPFR_DEFAULT_RND);
510c2c66affSColin Finck     mpfr_mul_ui(m, m, 60, MPFR_DEFAULT_RND);
511c2c66affSColin Finck 
512c2c66affSColin Finck     mpfr_frac(s, m, MPFR_DEFAULT_RND);
513c2c66affSColin Finck     mpfr_trunc(m, m);
514c2c66affSColin Finck     mpfr_mul_ui(s, s, 60, MPFR_DEFAULT_RND);
515c2c66affSColin Finck     mpfr_ceil(s, s);
516c2c66affSColin Finck 
517c2c66affSColin Finck     mpfr_div_ui(m, m, 100, MPFR_DEFAULT_RND);
518c2c66affSColin Finck     mpfr_div_ui(s, s, 10000, MPFR_DEFAULT_RND);
519c2c66affSColin Finck     mpfr_add(c->mf, d, m, MPFR_DEFAULT_RND);
520c2c66affSColin Finck     mpfr_add(c->mf, c->mf, s, MPFR_DEFAULT_RND);
521c2c66affSColin Finck 
522c2c66affSColin Finck     mpfr_clear(d);
523c2c66affSColin Finck     mpfr_clear(m);
524c2c66affSColin Finck     mpfr_clear(s);
525c2c66affSColin Finck }
526c2c66affSColin Finck 
rpn_zero(calc_number_t * c)527c2c66affSColin Finck void rpn_zero(calc_number_t *c)
528c2c66affSColin Finck {
529c2c66affSColin Finck     mpfr_set_ui(c->mf, 0, MPFR_DEFAULT_RND);
530c2c66affSColin Finck }
531c2c66affSColin Finck 
rpn_copy(calc_number_t * dst,calc_number_t * src)532c2c66affSColin Finck void rpn_copy(calc_number_t *dst, calc_number_t *src)
533c2c66affSColin Finck {
534c2c66affSColin Finck     mpfr_set(dst->mf, src->mf, MPFR_DEFAULT_RND);
535c2c66affSColin Finck }
536c2c66affSColin Finck 
rpn_is_zero(calc_number_t * c)537c2c66affSColin Finck int rpn_is_zero(calc_number_t *c)
538c2c66affSColin Finck {
539c2c66affSColin Finck     return (mpfr_sgn(c->mf) == 0);
540c2c66affSColin Finck }
541c2c66affSColin Finck 
rpn_alloc(calc_number_t * c)542c2c66affSColin Finck void rpn_alloc(calc_number_t *c)
543c2c66affSColin Finck {
544c2c66affSColin Finck     mpfr_init(c->mf);
545c2c66affSColin Finck }
546c2c66affSColin Finck 
rpn_free(calc_number_t * c)547c2c66affSColin Finck void rpn_free(calc_number_t *c)
548c2c66affSColin Finck {
549c2c66affSColin Finck     mpfr_clear(c->mf);
550c2c66affSColin Finck }
551