8 typedef void (*operator_call
)(calc_number_t
*, calc_number_t
*, calc_number_t
*);
17 static stack_node_t
*stack
;
18 static stack_node_t temp
;
19 static BOOL percent_mode
;
21 static void rpn_add_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
22 static void rpn_sub_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
23 static void rpn_mul_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
24 static void rpn_div_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
25 static void rpn_pow_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
26 static void rpn_sqr_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
27 static void rpn_and_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
28 static void rpn_or_f (calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
29 static void rpn_xor_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
30 static void rpn_shl_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
31 static void rpn_shr_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
33 /* Integer mode calculations */
34 static void rpn_add_i(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
35 static void rpn_sub_i(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
36 static void rpn_mul_i(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
37 static void rpn_div_i(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
38 static void rpn_mod_i(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
40 /* Percentage mode calculations */
41 static void rpn_add_p(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
42 static void rpn_sub_p(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
43 static void rpn_mul_p(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
44 static void rpn_div_p(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
);
46 static const calc_operator_t operator_list
[] = {
47 { 0, NULL
, NULL
, NULL
, }, // RPN_OPERATOR_PARENT
48 { 0, NULL
, NULL
, NULL
, }, // RPN_OPERATOR_PERCENT
49 { 0, NULL
, NULL
, NULL
, }, // RPN_OPERATOR_EQUAL
50 { 1, rpn_or_f
, rpn_or_f
, NULL
, }, // RPN_OPERATOR_OR
51 { 2, rpn_xor_f
, rpn_xor_f
, NULL
, }, // RPN_OPERATOR_XOR
52 { 3, rpn_and_f
, rpn_and_f
, NULL
, }, // RPN_OPERATOR_AND
53 { 4, rpn_shl_f
, rpn_shl_f
, NULL
, }, // RPN_OPERATOR_LSH
54 { 4, rpn_shr_f
, rpn_shr_f
, NULL
, }, // RPN_OPERATOR_RSH
55 { 5, rpn_add_f
, rpn_add_i
, rpn_add_p
, }, // RPN_OPERATOR_ADD
56 { 5, rpn_sub_f
, rpn_sub_i
, rpn_sub_p
, }, // RPN_OPERATOR_SUB
57 { 6, rpn_mul_f
, rpn_mul_i
, rpn_mul_p
, }, // RPN_OPERATOR_MULT
58 { 6, rpn_div_f
, rpn_div_i
, rpn_div_p
, }, // RPN_OPERATOR_DIV
59 { 6, rpn_mod_i
, rpn_mod_i
, NULL
, }, // RPN_OPERATOR_MOD
60 { 7, rpn_pow_f
, NULL
, NULL
, }, // RPN_OPERATOR_POW
61 { 7, rpn_sqr_f
, NULL
, NULL
, }, // RPN_OPERATOR_SQR
64 static void node_copy(stack_node_t
*dst
, stack_node_t
*src
)
66 mpfr_set(dst
->node
.number
.mf
,src
->node
.number
.mf
,MPFR_DEFAULT_RND
);
67 dst
->node
.operation
= src
->node
.operation
;
68 dst
->next
= src
->next
;
71 static stack_node_t
*pop()
77 node_copy(&temp
, stack
);
80 mpfr_clear(stack
->node
.number
.mf
);
87 static int is_stack_empty(void)
89 return (stack
== NULL
);
92 static void push(stack_node_t
*op
)
94 stack_node_t
*z
= (stack_node_t
*)malloc(sizeof(stack_node_t
));
96 mpfr_init_set(z
->node
.number
.mf
,op
->node
.number
.mf
,MPFR_DEFAULT_RND
);
97 z
->node
.operation
= op
->node
.operation
;
102 static unsigned int get_prec(unsigned int opc)
106 for (x=0; x<SIZEOF(operator_list); x++)
107 if (operator_list[x].opc == opc) break;
108 return operator_list[x].prec;
113 __GMP_DECLSPEC
void (*exec_call_t
)
114 __GMP_PROTO ((mpz_ptr
, mpz_srcptr
, mpz_srcptr
));
116 static void rpn_exec_int(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
, exec_call_t cb
)
122 mpfr_get_z(ai
, a
->mf
, MPFR_DEFAULT_RND
);
123 mpfr_get_z(bi
, b
->mf
, MPFR_DEFAULT_RND
);
125 mpfr_set_z(r
->mf
, ai
, MPFR_DEFAULT_RND
);
131 /* Real mode calculations */
132 static void rpn_add_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
134 mpfr_add(r
->mf
, a
->mf
, b
->mf
, MPFR_DEFAULT_RND
);
137 static void rpn_sub_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
139 mpfr_sub(r
->mf
, a
->mf
, b
->mf
, MPFR_DEFAULT_RND
);
142 static void rpn_mul_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
144 mpfr_mul(r
->mf
, a
->mf
, b
->mf
, MPFR_DEFAULT_RND
);
147 static void rpn_div_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
149 if (mpfr_sgn(b
->mf
) == 0)
152 mpfr_div(r
->mf
, a
->mf
, b
->mf
, MPFR_DEFAULT_RND
);
155 static void rpn_and_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
157 rpn_exec_int(r
, a
, b
, mpz_and
);
160 static void rpn_or_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
162 rpn_exec_int(r
, a
, b
, mpz_ior
);
165 static void rpn_xor_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
167 rpn_exec_int(r
, a
, b
, mpz_xor
);
170 static void rpn_shl_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
174 mpfr_trunc(r
->mf
, b
->mf
);
175 if (mpfr_fits_ulong_p(r
->mf
, MPFR_DEFAULT_RND
) == 0)
178 e
= mpfr_get_ui(r
->mf
, MPFR_DEFAULT_RND
);
179 mpfr_mul_2exp(r
->mf
, a
->mf
, e
, MPFR_DEFAULT_RND
);
183 static void rpn_shr_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
187 mpfr_trunc(r
->mf
, b
->mf
);
188 if (mpfr_fits_ulong_p(r
->mf
, MPFR_DEFAULT_RND
) == 0)
191 e
= mpfr_get_ui(r
->mf
, MPFR_DEFAULT_RND
);
192 mpfr_div_2exp(r
->mf
, a
->mf
, e
, MPFR_DEFAULT_RND
);
196 static void rpn_pow_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
198 mpfr_pow(r
->mf
, a
->mf
, b
->mf
, MPFR_DEFAULT_RND
);
201 static void rpn_sqr_f(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
203 if (mpfr_sgn(b
->mf
) == 0)
209 mpfr_set(tmp
, b
->mf
, MPFR_DEFAULT_RND
);
210 mpfr_ui_div(tmp
, 1, tmp
, MPFR_DEFAULT_RND
);
211 mpfr_pow(r
->mf
, a
->mf
, tmp
, MPFR_DEFAULT_RND
);
216 /* Integer mode calculations */
217 static void rpn_add_i(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
219 rpn_exec_int(r
, a
, b
, mpz_add
);
222 static void rpn_sub_i(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
224 rpn_exec_int(r
, a
, b
, mpz_sub
);
227 static void rpn_mul_i(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
229 rpn_exec_int(r
, a
, b
, mpz_mul
);
232 static void rpn_div_i(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
234 if (mpfr_sgn(b
->mf
) == 0)
237 rpn_exec_int(r
, a
, b
, mpz_tdiv_q
);
240 static void rpn_mod_i(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
242 if (mpfr_sgn(b
->mf
) == 0)
245 rpn_exec_int(r
, a
, b
, mpz_tdiv_r
);
248 /* Percent mode calculations */
249 static void rpn_add_p(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
254 mpfr_set(tmp
, b
->mf
, MPFR_DEFAULT_RND
);
255 mpfr_div_ui(tmp
, tmp
, 100, MPFR_DEFAULT_RND
);
256 mpfr_add_ui(tmp
, tmp
, 1, MPFR_DEFAULT_RND
);
257 mpfr_mul(r
->mf
, a
->mf
, tmp
, MPFR_DEFAULT_RND
);
261 static void rpn_sub_p(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
266 mpfr_set(tmp
, b
->mf
, MPFR_DEFAULT_RND
);
267 mpfr_div_ui(tmp
, tmp
, 100, MPFR_DEFAULT_RND
);
268 mpfr_sub_ui(tmp
, tmp
, 1, MPFR_DEFAULT_RND
);
269 mpfr_mul(r
->mf
, a
->mf
, tmp
, MPFR_DEFAULT_RND
);
273 static void rpn_mul_p(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
275 mpfr_mul(r
->mf
, a
->mf
, b
->mf
, MPFR_DEFAULT_RND
);
276 mpfr_div_ui(r
->mf
, r
->mf
, 100, MPFR_DEFAULT_RND
);
279 static void rpn_div_p(calc_number_t
*r
, calc_number_t
*a
, calc_number_t
*b
)
281 if (mpfr_sgn(b
->mf
) == 0)
284 mpfr_mul_ui(r
->mf
, a
->mf
, 100, MPFR_DEFAULT_RND
);
285 mpfr_div(r
->mf
, r
->mf
, b
->mf
, MPFR_DEFAULT_RND
);
290 void run_operator(calc_node_t
*result
,
293 unsigned int operation
)
295 if (calc
.base
== IDC_RADIO_DEC
) {
297 percent_mode
= FALSE
;
298 operator_list
[operation
].op_p(&result
->number
, &a
->number
, &b
->number
);
300 operator_list
[operation
].op_f(&result
->number
, &a
->number
, &b
->number
);
302 operator_list
[operation
].op_i(&result
->number
, &a
->number
, &b
->number
);
303 /* apply final limitator to result */
304 apply_int_mask(&result
->number
);
308 static void evalStack(calc_number_t
*number
)
310 stack_node_t
*op
, ip
;
313 mpfr_init(ip
.node
.number
.mf
);
316 prec
= operator_list
[ip
.node
.operation
].prec
;
317 while (!is_stack_empty()) {
320 if (prec
<= operator_list
[op
->node
.operation
].prec
) {
321 if (op
->node
.operation
== RPN_OPERATOR_PARENT
) continue;
323 rpn_copy(&calc
.prev
, &ip
.node
.number
);
324 run_operator(&ip
.node
, &op
->node
, &ip
.node
, op
->node
.operation
);
327 mpfr_clear(ip
.node
.number
.mf
);
336 if(ip
.node
.operation
!= RPN_OPERATOR_EQUAL
&& ip
.node
.operation
!= RPN_OPERATOR_PERCENT
)
339 calc
.prev_operator
= op
->node
.operation
;
341 rpn_copy(number
, &ip
.node
.number
);
342 mpfr_clear(ip
.node
.number
.mf
);
345 int exec_infix2postfix(calc_number_t
*number
, unsigned int func
)
349 if (is_stack_empty() && func
== RPN_OPERATOR_EQUAL
) {
350 /* if a number has been entered with exponential */
351 /* notation, I may update it with normal mode */
357 if (func
== RPN_OPERATOR_PERCENT
)
360 mpfr_init(tmp
.node
.number
.mf
);
361 rpn_copy(&tmp
.node
.number
, number
);
362 tmp
.node
.operation
= func
;
365 mpfr_clear(tmp
.node
.number
.mf
);
367 if (func
== RPN_OPERATOR_NONE
)
370 if (func
!= RPN_OPERATOR_PARENT
) {
371 calc
.last_operator
= func
;
377 void exec_change_infix(void)
379 stack_node_t
*op
= stack
;
383 if (op
->node
.operation
== RPN_OPERATOR_PARENT
||
384 op
->node
.operation
== RPN_OPERATOR_PERCENT
||
385 op
->node
.operation
== RPN_OPERATOR_EQUAL
)
387 /* remove the head, it will be re-inserted with new operator */
391 void exec_closeparent(calc_number_t
*number
)
393 stack_node_t
*op
, ip
;
395 rpn_alloc(&ip
.node
.number
);
396 rpn_copy(&ip
.node
.number
, number
);
397 while (!is_stack_empty()) {
400 if (op
->node
.operation
== RPN_OPERATOR_PARENT
)
403 run_operator(&ip
.node
, &op
->node
, &ip
.node
, op
->node
.operation
);
409 rpn_copy(number
, &ip
.node
.number
);
410 rpn_free(&ip
.node
.number
);
413 int eval_parent_count(void)
415 stack_node_t
*s
= stack
;
419 if (s
->node
.operation
== RPN_OPERATOR_PARENT
)
421 s
= (stack_node_t
*)(s
->next
);
428 while (!is_stack_empty())
430 /* clear prev and last typed operators */
432 calc
.last_operator
= 0;
435 void start_rpn_engine(void)
437 mpf_set_default_prec(512);
438 mpfr_set_default_prec(512);
440 mpfr_init(calc
.code
.mf
);
441 mpfr_init(calc
.prev
.mf
);
442 mpfr_init(calc
.memory
.number
.mf
);
443 mpfr_init(temp
.node
.number
.mf
);
444 rpn_zero(&calc
.memory
.number
);
447 void stop_rpn_engine(void)
449 mpfr_clear(calc
.code
.mf
);
450 mpfr_clear(calc
.prev
.mf
);
451 mpfr_clear(calc
.memory
.number
.mf
);
452 mpfr_clear(temp
.node
.number
.mf
);