ReactOS  0.4.12-dev-18-gf469aca
rpn_mpfr.c
Go to the documentation of this file.
1 #include "calc.h"
2 
3 typedef struct {
5  void *next;
7 
9 
10 typedef struct {
11  unsigned int prec;
12  operator_call op_f;
13  operator_call op_i;
14  operator_call op_p;
16 
20 
32 
33 /* Integer mode calculations */
39 
40 /* Percentage mode calculations */
45 
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
62 };
63 
65 {
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;
69 }
70 
71 static stack_node_t *pop()
72 {
73  if (stack == NULL)
74  return NULL;
75 
76  /* copy the node */
77  node_copy(&temp, stack);
78 
79  /* free the node */
80  mpfr_clear(stack->node.number.mf);
81  free(stack);
82  stack = temp.next;
83 
84  return &temp;
85 }
86 
87 static int is_stack_empty(void)
88 {
89  return (stack == NULL);
90 }
91 
92 static void push(stack_node_t *op)
93 {
95 
96  mpfr_init_set(z->node.number.mf,op->node.number.mf,MPFR_DEFAULT_RND);
97  z->node.operation = op->node.operation;
98  z->next = stack;
99  stack = z;
100 }
101 /*
102 static unsigned int get_prec(unsigned int opc)
103 {
104  unsigned int x;
105 
106  for (x=0; x<SIZEOF(operator_list); x++)
107  if (operator_list[x].opc == opc) break;
108  return operator_list[x].prec;
109 }
110 */
111 
112 typedef
113 __GMP_DECLSPEC void (*exec_call_t)
114 __GMP_PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr));
115 
116 static void rpn_exec_int(calc_number_t *r, calc_number_t *a, calc_number_t *b, exec_call_t cb)
117 {
118  mpz_t ai, bi;
119 
120  mpz_init(ai);
121  mpz_init(bi);
122  mpfr_get_z(ai, a->mf, MPFR_DEFAULT_RND);
123  mpfr_get_z(bi, b->mf, MPFR_DEFAULT_RND);
124  cb(ai, ai, bi);
125  mpfr_set_z(r->mf, ai, MPFR_DEFAULT_RND);
126  mpz_clear(ai);
127  mpz_clear(bi);
128 }
129 
130 
131 /* Real mode calculations */
133 {
134  mpfr_add(r->mf, a->mf, b->mf, MPFR_DEFAULT_RND);
135 }
136 
138 {
139  mpfr_sub(r->mf, a->mf, b->mf, MPFR_DEFAULT_RND);
140 }
141 
143 {
144  mpfr_mul(r->mf, a->mf, b->mf, MPFR_DEFAULT_RND);
145 }
146 
148 {
149  if (mpfr_sgn(b->mf) == 0)
150  calc.is_nan = TRUE;
151  else
152  mpfr_div(r->mf, a->mf, b->mf, MPFR_DEFAULT_RND);
153 }
154 
156 {
157  rpn_exec_int(r, a, b, mpz_and);
158 }
159 
161 {
162  rpn_exec_int(r, a, b, mpz_ior);
163 }
164 
166 {
167  rpn_exec_int(r, a, b, mpz_xor);
168 }
169 
171 {
172  unsigned long e;
173 
174  mpfr_trunc(r->mf, b->mf);
175  if (mpfr_fits_ulong_p(r->mf, MPFR_DEFAULT_RND) == 0)
176  calc.is_nan = TRUE;
177  else {
178  e = mpfr_get_ui(r->mf, MPFR_DEFAULT_RND);
179  mpfr_mul_2exp(r->mf, a->mf, e, MPFR_DEFAULT_RND);
180  }
181 }
182 
184 {
185  unsigned long e;
186 
187  mpfr_trunc(r->mf, b->mf);
188  if (mpfr_fits_ulong_p(r->mf, MPFR_DEFAULT_RND) == 0)
189  calc.is_nan = TRUE;
190  else {
191  e = mpfr_get_ui(r->mf, MPFR_DEFAULT_RND);
192  mpfr_div_2exp(r->mf, a->mf, e, MPFR_DEFAULT_RND);
193  }
194 }
195 
197 {
198  mpfr_pow(r->mf, a->mf, b->mf, MPFR_DEFAULT_RND);
199 }
200 
202 {
203  if (mpfr_sgn(b->mf) == 0)
204  calc.is_nan = TRUE;
205  else {
206  mpfr_t tmp;
207 
208  mpfr_init(tmp);
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);
212  mpfr_clear(tmp);
213  }
214 }
215 
216 /* Integer mode calculations */
218 {
219  rpn_exec_int(r, a, b, mpz_add);
220 }
221 
223 {
224  rpn_exec_int(r, a, b, mpz_sub);
225 }
226 
228 {
229  rpn_exec_int(r, a, b, mpz_mul);
230 }
231 
233 {
234  if (mpfr_sgn(b->mf) == 0)
235  calc.is_nan = TRUE;
236  else
237  rpn_exec_int(r, a, b, mpz_tdiv_q);
238 }
239 
241 {
242  if (mpfr_sgn(b->mf) == 0)
243  calc.is_nan = TRUE;
244  else
245  rpn_exec_int(r, a, b, mpz_tdiv_r);
246 }
247 
248 /* Percent mode calculations */
250 {
251  mpfr_t tmp;
252 
253  mpfr_init(tmp);
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);
258  mpfr_clear(tmp);
259 }
260 
262 {
263  mpfr_t tmp;
264 
265  mpfr_init(tmp);
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);
270  mpfr_clear(tmp);
271 }
272 
274 {
275  mpfr_mul(r->mf, a->mf, b->mf, MPFR_DEFAULT_RND);
276  mpfr_div_ui(r->mf, r->mf, 100, MPFR_DEFAULT_RND);
277 }
278 
280 {
281  if (mpfr_sgn(b->mf) == 0)
282  calc.is_nan = TRUE;
283  else {
284  mpfr_mul_ui(r->mf, a->mf, 100, MPFR_DEFAULT_RND);
285  mpfr_div(r->mf, r->mf, b->mf, MPFR_DEFAULT_RND);
286  }
287 }
288 
289 
291  calc_node_t *a,
292  calc_node_t *b,
293  unsigned int operation)
294 {
295  if (calc.base == IDC_RADIO_DEC) {
296  if (percent_mode) {
298  operator_list[operation].op_p(&result->number, &a->number, &b->number);
299  } else
300  operator_list[operation].op_f(&result->number, &a->number, &b->number);
301  } else {
302  operator_list[operation].op_i(&result->number, &a->number, &b->number);
303  /* apply final limiter to result */
304  apply_int_mask(&result->number);
305  }
306 }
307 
309 {
310  stack_node_t *op, ip;
311  unsigned int prec;
312 
313  mpfr_init(ip.node.number.mf);
314  op = pop();
315  node_copy(&ip, op);
316  prec = operator_list[ip.node.operation].prec;
317  while (!is_stack_empty()) {
318  op = pop();
319 
320  if (prec <= operator_list[op->node.operation].prec) {
321  if (op->node.operation == RPN_OPERATOR_PARENT) continue;
322 
323  rpn_copy(&calc.prev, &ip.node.number);
324  run_operator(&ip.node, &op->node, &ip.node, op->node.operation);
325  if (calc.is_nan) {
326  flush_postfix();
327  mpfr_clear(ip.node.number.mf);
328  return;
329  }
330  } else {
331  push(op);
332  break;
333  }
334  }
335 
337  push(&ip);
338 
340 
341  rpn_copy(number, &ip.node.number);
342  mpfr_clear(ip.node.number.mf);
343 }
344 
346 {
347  stack_node_t tmp;
348 
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 */
352  if (calc.sci_in)
353  return 1;
354  return 0;
355  }
356 
357  if (func == RPN_OPERATOR_PERCENT)
358  percent_mode = TRUE;
359 
360  mpfr_init(tmp.node.number.mf);
361  rpn_copy(&tmp.node.number, number);
362  tmp.node.operation = func;
363 
364  push(&tmp);
365  mpfr_clear(tmp.node.number.mf);
366 
367  if (func == RPN_OPERATOR_NONE)
368  return 0;
369 
370  if (func != RPN_OPERATOR_PARENT) {
372  evalStack(number);
373  }
374  return 1;
375 }
376 
378 {
379  stack_node_t *op = stack;
380 
381  if (op == NULL)
382  return;
383  if (op->node.operation == RPN_OPERATOR_PARENT ||
386  return;
387  /* remove the head, it will be re-inserted with new operator */
388  pop();
389 }
390 
392 {
393  stack_node_t *op, ip;
394 
395  rpn_alloc(&ip.node.number);
396  rpn_copy(&ip.node.number, number);
397  while (!is_stack_empty()) {
398  op = pop();
399 
401  break;
402 
403  run_operator(&ip.node, &op->node, &ip.node, op->node.operation);
404  if (calc.is_nan) {
405  flush_postfix();
406  return;
407  }
408  }
409  rpn_copy(number, &ip.node.number);
410  rpn_free(&ip.node.number);
411 }
412 
414 {
415  stack_node_t *s = stack;
416  int n = 0;
417 
418  while (s != NULL) {
420  n++;
421  s = (stack_node_t *)(s->next);
422  }
423  return n;
424 }
425 
427 {
428  while (!is_stack_empty())
429  pop();
430  /* clear prev and last typed operators */
432  calc.last_operator = 0;
433 }
434 
436 {
437  mpf_set_default_prec(512);
438  mpfr_set_default_prec(512);
439  stack = NULL;
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);
445 }
446 
447 void stop_rpn_engine(void)
448 {
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);
453 }
GLenum func
Definition: glext.h:6028
static const calc_operator_t operator_list[]
Definition: rpn_mpfr.c:46
DWORD base
Definition: calc.h:138
static void rpn_pow_f(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn_mpfr.c:196
#define TRUE
Definition: types.h:120
void rpn_copy(calc_number_t *dst, calc_number_t *src)
Definition: fun_mpfr.c:472
void(* operator_call)(calc_number_t *, calc_number_t *, calc_number_t *)
Definition: rpn_mpfr.c:8
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:47
calc_number_t code
Definition: calc.h:127
#define IDC_RADIO_DEC
Definition: resource.h:17
static void rpn_mul_f(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn_mpfr.c:142
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define free
Definition: debug_ros.c:5
void rpn_zero(calc_number_t *c)
Definition: fun_mpfr.c:467
void rpn_free(calc_number_t *c)
Definition: fun_mpfr.c:487
static void rpn_shl_f(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn_mpfr.c:170
static void rpn_add_f(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn_mpfr.c:132
static void rpn_mod_i(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn_mpfr.c:240
BOOL is_nan
Definition: calc.h:132
static void rpn_sqr_f(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn_mpfr.c:201
static void rpn_sub_f(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn_mpfr.c:137
static void rpn_add_i(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn_mpfr.c:217
GLuint n
Definition: s_context.h:57
struct node node
GLuint const GLubyte GLvoid * src
Definition: s_context.h:57
UINT op
Definition: effect.c:223
#define e
Definition: ke_i.h:82
static size_t double number
Definition: printf.c:64
int ip[4]
Definition: rtl.c:1176
GLdouble GLdouble z
Definition: glext.h:5874
smooth NULL
Definition: ftsmooth.c:416
static void rpn_add_p(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn_mpfr.c:249
unsigned int prec
Definition: rpn.c:11
unsigned int prev_operator
Definition: calc.h:147
int exec_infix2postfix(calc_number_t *number, unsigned int func)
Definition: rpn_mpfr.c:345
__GMP_DECLSPEC void exec_call_t __GMP_PROTO((mpz_ptr, mpz_srcptr, mpz_srcptr))
Definition: rpn_mpfr.c:114
static void rpn_or_f(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn_mpfr.c:160
static void rpn_div_i(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn_mpfr.c:232
static void rpn_mul_p(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn_mpfr.c:273
static void evalStack(calc_number_t *number)
Definition: rpn_mpfr.c:308
static void node_copy(stack_node_t *dst, stack_node_t *src)
Definition: rpn_mpfr.c:64
static stack_node_t temp
Definition: rpn_mpfr.c:18
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
unsigned int BOOL
Definition: ntddk_ex.h:94
static BOOL percent_mode
Definition: rpn_mpfr.c:19
void start_rpn_engine(void)
Definition: rpn_mpfr.c:435
static void rpn_sub_i(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn_mpfr.c:222
static void rpn_sub_p(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn_mpfr.c:261
BOOL sci_in
Definition: calc.h:134
unsigned int last_operator
Definition: calc.h:146
static DWORD cb
Definition: integrity.c:41
void flush_postfix()
Definition: rpn_mpfr.c:426
static void rpn_shr_f(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn_mpfr.c:183
calc_number_t number
Definition: calc.h:84
operator_call op_f
Definition: rpn.c:12
static void rpn_xor_f(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn_mpfr.c:165
GLdouble s
Definition: gl.h:2039
calc_node_t node
Definition: rpn.c:4
static unsigned __int64 next
Definition: rand_nt.c:6
void run_operator(calc_node_t *result, calc_node_t *a, calc_node_t *b, unsigned int operation)
Definition: rpn_mpfr.c:290
static void rpn_mul_i(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn_mpfr.c:227
GLuint const GLubyte GLvoid const GLvoid * dst
Definition: s_context.h:57
unsigned int operation
Definition: calc.h:85
static void rpn_exec_int(calc_number_t *r, calc_number_t *a, calc_number_t *b, exec_call_t cb)
Definition: rpn_mpfr.c:116
operator_call op_i
Definition: rpn.c:13
static void rpn_div_p(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn_mpfr.c:279
#define malloc
Definition: debug_ros.c:4
static void rpn_and_f(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn_mpfr.c:155
calc_node_t memory
Definition: calc.h:129
operator_call op_p
Definition: rpn.c:14
static stack_node_t * pop()
Definition: rpn_mpfr.c:71
void exec_closeparent(calc_number_t *number)
Definition: rpn_mpfr.c:391
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
void exec_change_infix(void)
Definition: rpn_mpfr.c:377
void * next
Definition: rpn.c:5
static void push(stack_node_t *op)
Definition: rpn_mpfr.c:92
static int is_stack_empty(void)
Definition: rpn_mpfr.c:87
calc_t calc
Definition: winmain.c:226
int eval_parent_count(void)
Definition: rpn_mpfr.c:413
GLuint64EXT * result
Definition: glext.h:11304
static stack_node_t * stack
Definition: rpn_mpfr.c:17
static void rpn_div_f(calc_number_t *r, calc_number_t *a, calc_number_t *b)
Definition: rpn_mpfr.c:147
void stop_rpn_engine(void)
Definition: rpn_mpfr.c:447
calc_number_t prev
Definition: calc.h:128
void apply_int_mask(calc_number_t *a)
Definition: fun_mpfr.c:3
void rpn_alloc(calc_number_t *c)
Definition: fun_mpfr.c:482