Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenrpn_mpfr.cGo to the documentation of this file.00001 #include "calc.h" 00002 00003 typedef struct { 00004 calc_node_t node; 00005 void *next; 00006 } stack_node_t; 00007 00008 typedef void (*operator_call)(calc_number_t *, calc_number_t *, calc_number_t *); 00009 00010 typedef struct { 00011 unsigned int prec; 00012 operator_call op_f; 00013 operator_call op_i; 00014 operator_call op_p; 00015 } calc_operator_t; 00016 00017 static stack_node_t *stack; 00018 static stack_node_t temp; 00019 static BOOL percent_mode; 00020 00021 static void rpn_add_f(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00022 static void rpn_sub_f(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00023 static void rpn_mul_f(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00024 static void rpn_div_f(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00025 static void rpn_pow_f(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00026 static void rpn_sqr_f(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00027 static void rpn_and_f(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00028 static void rpn_or_f (calc_number_t *r, calc_number_t *a, calc_number_t *b); 00029 static void rpn_xor_f(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00030 static void rpn_shl_f(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00031 static void rpn_shr_f(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00032 00033 /* Integer mode calculations */ 00034 static void rpn_add_i(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00035 static void rpn_sub_i(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00036 static void rpn_mul_i(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00037 static void rpn_div_i(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00038 static void rpn_mod_i(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00039 00040 /* Percentage mode calculations */ 00041 static void rpn_add_p(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00042 static void rpn_sub_p(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00043 static void rpn_mul_p(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00044 static void rpn_div_p(calc_number_t *r, calc_number_t *a, calc_number_t *b); 00045 00046 static const calc_operator_t operator_list[] = { 00047 { 0, NULL, NULL, NULL, }, // RPN_OPERATOR_PARENT 00048 { 0, NULL, NULL, NULL, }, // RPN_OPERATOR_PERCENT 00049 { 0, NULL, NULL, NULL, }, // RPN_OPERATOR_EQUAL 00050 { 1, rpn_or_f, rpn_or_f, NULL, }, // RPN_OPERATOR_OR 00051 { 2, rpn_xor_f, rpn_xor_f, NULL, }, // RPN_OPERATOR_XOR 00052 { 3, rpn_and_f, rpn_and_f, NULL, }, // RPN_OPERATOR_AND 00053 { 4, rpn_shl_f, rpn_shl_f, NULL, }, // RPN_OPERATOR_LSH 00054 { 4, rpn_shr_f, rpn_shr_f, NULL, }, // RPN_OPERATOR_RSH 00055 { 5, rpn_add_f, rpn_add_i, rpn_add_p, }, // RPN_OPERATOR_ADD 00056 { 5, rpn_sub_f, rpn_sub_i, rpn_sub_p, }, // RPN_OPERATOR_SUB 00057 { 6, rpn_mul_f, rpn_mul_i, rpn_mul_p, }, // RPN_OPERATOR_MULT 00058 { 6, rpn_div_f, rpn_div_i, rpn_div_p, }, // RPN_OPERATOR_DIV 00059 { 6, rpn_mod_i, rpn_mod_i, NULL, }, // RPN_OPERATOR_MOD 00060 { 7, rpn_pow_f, NULL, NULL, }, // RPN_OPERATOR_POW 00061 { 7, rpn_sqr_f, NULL, NULL, }, // RPN_OPERATOR_SQR 00062 }; 00063 00064 static void node_copy(stack_node_t *dst, stack_node_t *src) 00065 { 00066 mpfr_set(dst->node.number.mf,src->node.number.mf,MPFR_DEFAULT_RND); 00067 dst->node.operation = src->node.operation; 00068 dst->next = src->next; 00069 } 00070 00071 static stack_node_t *pop() 00072 { 00073 if (stack == NULL) 00074 return NULL; 00075 00076 /* copy the node */ 00077 node_copy(&temp, stack); 00078 00079 /* free the node */ 00080 mpfr_clear(stack->node.number.mf); 00081 free(stack); 00082 stack = temp.next; 00083 00084 return &temp; 00085 } 00086 00087 static int is_stack_empty(void) 00088 { 00089 return (stack == NULL); 00090 } 00091 00092 static void push(stack_node_t *op) 00093 { 00094 stack_node_t *z = (stack_node_t *)malloc(sizeof(stack_node_t)); 00095 00096 mpfr_init_set(z->node.number.mf,op->node.number.mf,MPFR_DEFAULT_RND); 00097 z->node.operation = op->node.operation; 00098 z->next = stack; 00099 stack = z; 00100 } 00101 /* 00102 static unsigned int get_prec(unsigned int opc) 00103 { 00104 unsigned int x; 00105 00106 for (x=0; x<SIZEOF(operator_list); x++) 00107 if (operator_list[x].opc == opc) break; 00108 return operator_list[x].prec; 00109 } 00110 */ 00111 00112 typedef 00113 __GMP_DECLSPEC void (*exec_call_t) 00114 __GMP_PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr)); 00115 00116 static void rpn_exec_int(calc_number_t *r, calc_number_t *a, calc_number_t *b, exec_call_t cb) 00117 { 00118 mpz_t ai, bi; 00119 00120 mpz_init(ai); 00121 mpz_init(bi); 00122 mpfr_get_z(ai, a->mf, MPFR_DEFAULT_RND); 00123 mpfr_get_z(bi, b->mf, MPFR_DEFAULT_RND); 00124 cb(ai, ai, bi); 00125 mpfr_set_z(r->mf, ai, MPFR_DEFAULT_RND); 00126 mpz_clear(ai); 00127 mpz_clear(bi); 00128 } 00129 00130 00131 /* Real mode calculations */ 00132 static void rpn_add_f(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00133 { 00134 mpfr_add(r->mf, a->mf, b->mf, MPFR_DEFAULT_RND); 00135 } 00136 00137 static void rpn_sub_f(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00138 { 00139 mpfr_sub(r->mf, a->mf, b->mf, MPFR_DEFAULT_RND); 00140 } 00141 00142 static void rpn_mul_f(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00143 { 00144 mpfr_mul(r->mf, a->mf, b->mf, MPFR_DEFAULT_RND); 00145 } 00146 00147 static void rpn_div_f(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00148 { 00149 if (mpfr_sgn(b->mf) == 0) 00150 calc.is_nan = TRUE; 00151 else 00152 mpfr_div(r->mf, a->mf, b->mf, MPFR_DEFAULT_RND); 00153 } 00154 00155 static void rpn_and_f(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00156 { 00157 rpn_exec_int(r, a, b, mpz_and); 00158 } 00159 00160 static void rpn_or_f(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00161 { 00162 rpn_exec_int(r, a, b, mpz_ior); 00163 } 00164 00165 static void rpn_xor_f(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00166 { 00167 rpn_exec_int(r, a, b, mpz_xor); 00168 } 00169 00170 static void rpn_shl_f(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00171 { 00172 unsigned long e; 00173 00174 mpfr_trunc(r->mf, b->mf); 00175 if (mpfr_fits_ulong_p(r->mf, MPFR_DEFAULT_RND) == 0) 00176 calc.is_nan = TRUE; 00177 else { 00178 e = mpfr_get_ui(r->mf, MPFR_DEFAULT_RND); 00179 mpfr_mul_2exp(r->mf, a->mf, e, MPFR_DEFAULT_RND); 00180 } 00181 } 00182 00183 static void rpn_shr_f(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00184 { 00185 unsigned long e; 00186 00187 mpfr_trunc(r->mf, b->mf); 00188 if (mpfr_fits_ulong_p(r->mf, MPFR_DEFAULT_RND) == 0) 00189 calc.is_nan = TRUE; 00190 else { 00191 e = mpfr_get_ui(r->mf, MPFR_DEFAULT_RND); 00192 mpfr_div_2exp(r->mf, a->mf, e, MPFR_DEFAULT_RND); 00193 } 00194 } 00195 00196 static void rpn_pow_f(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00197 { 00198 mpfr_pow(r->mf, a->mf, b->mf, MPFR_DEFAULT_RND); 00199 } 00200 00201 static void rpn_sqr_f(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00202 { 00203 if (mpfr_sgn(b->mf) == 0) 00204 calc.is_nan = TRUE; 00205 else { 00206 mpfr_t tmp; 00207 00208 mpfr_init(tmp); 00209 mpfr_set(tmp, b->mf, MPFR_DEFAULT_RND); 00210 mpfr_ui_div(tmp, 1, tmp, MPFR_DEFAULT_RND); 00211 mpfr_pow(r->mf, a->mf, tmp, MPFR_DEFAULT_RND); 00212 mpfr_clear(tmp); 00213 } 00214 } 00215 00216 /* Integer mode calculations */ 00217 static void rpn_add_i(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00218 { 00219 rpn_exec_int(r, a, b, mpz_add); 00220 } 00221 00222 static void rpn_sub_i(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00223 { 00224 rpn_exec_int(r, a, b, mpz_sub); 00225 } 00226 00227 static void rpn_mul_i(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00228 { 00229 rpn_exec_int(r, a, b, mpz_mul); 00230 } 00231 00232 static void rpn_div_i(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00233 { 00234 if (mpfr_sgn(b->mf) == 0) 00235 calc.is_nan = TRUE; 00236 else 00237 rpn_exec_int(r, a, b, mpz_tdiv_q); 00238 } 00239 00240 static void rpn_mod_i(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00241 { 00242 if (mpfr_sgn(b->mf) == 0) 00243 calc.is_nan = TRUE; 00244 else 00245 rpn_exec_int(r, a, b, mpz_tdiv_r); 00246 } 00247 00248 /* Percent mode calculations */ 00249 static void rpn_add_p(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00250 { 00251 mpfr_t tmp; 00252 00253 mpfr_init(tmp); 00254 mpfr_set(tmp, b->mf, MPFR_DEFAULT_RND); 00255 mpfr_div_ui(tmp, tmp, 100, MPFR_DEFAULT_RND); 00256 mpfr_add_ui(tmp, tmp, 1, MPFR_DEFAULT_RND); 00257 mpfr_mul(r->mf, a->mf, tmp, MPFR_DEFAULT_RND); 00258 mpfr_clear(tmp); 00259 } 00260 00261 static void rpn_sub_p(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00262 { 00263 mpfr_t tmp; 00264 00265 mpfr_init(tmp); 00266 mpfr_set(tmp, b->mf, MPFR_DEFAULT_RND); 00267 mpfr_div_ui(tmp, tmp, 100, MPFR_DEFAULT_RND); 00268 mpfr_sub_ui(tmp, tmp, 1, MPFR_DEFAULT_RND); 00269 mpfr_mul(r->mf, a->mf, tmp, MPFR_DEFAULT_RND); 00270 mpfr_clear(tmp); 00271 } 00272 00273 static void rpn_mul_p(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00274 { 00275 mpfr_mul(r->mf, a->mf, b->mf, MPFR_DEFAULT_RND); 00276 mpfr_div_ui(r->mf, r->mf, 100, MPFR_DEFAULT_RND); 00277 } 00278 00279 static void rpn_div_p(calc_number_t *r, calc_number_t *a, calc_number_t *b) 00280 { 00281 if (mpfr_sgn(b->mf) == 0) 00282 calc.is_nan = TRUE; 00283 else { 00284 mpfr_mul_ui(r->mf, a->mf, 100, MPFR_DEFAULT_RND); 00285 mpfr_div(r->mf, r->mf, b->mf, MPFR_DEFAULT_RND); 00286 } 00287 } 00288 00289 00290 void run_operator(calc_node_t *result, 00291 calc_node_t *a, 00292 calc_node_t *b, 00293 unsigned int operation) 00294 { 00295 if (calc.base == IDC_RADIO_DEC) { 00296 if (percent_mode) { 00297 percent_mode = FALSE; 00298 operator_list[operation].op_p(&result->number, &a->number, &b->number); 00299 } else 00300 operator_list[operation].op_f(&result->number, &a->number, &b->number); 00301 } else { 00302 operator_list[operation].op_i(&result->number, &a->number, &b->number); 00303 /* apply final limitator to result */ 00304 apply_int_mask(&result->number); 00305 } 00306 } 00307 00308 static void evalStack(calc_number_t *number) 00309 { 00310 stack_node_t *op, ip; 00311 unsigned int prec; 00312 00313 mpfr_init(ip.node.number.mf); 00314 op = pop(); 00315 node_copy(&ip, op); 00316 prec = operator_list[ip.node.operation].prec; 00317 while (!is_stack_empty()) { 00318 op = pop(); 00319 00320 if (prec <= operator_list[op->node.operation].prec) { 00321 if (op->node.operation == RPN_OPERATOR_PARENT) continue; 00322 00323 rpn_copy(&calc.prev, &ip.node.number); 00324 run_operator(&ip.node, &op->node, &ip.node, op->node.operation); 00325 if (calc.is_nan) { 00326 flush_postfix(); 00327 mpfr_clear(ip.node.number.mf); 00328 return; 00329 } 00330 } else { 00331 push(op); 00332 break; 00333 } 00334 } 00335 00336 if(ip.node.operation != RPN_OPERATOR_EQUAL && ip.node.operation != RPN_OPERATOR_PERCENT) 00337 push(&ip); 00338 00339 calc.prev_operator = op->node.operation; 00340 00341 rpn_copy(number, &ip.node.number); 00342 mpfr_clear(ip.node.number.mf); 00343 } 00344 00345 int exec_infix2postfix(calc_number_t *number, unsigned int func) 00346 { 00347 stack_node_t tmp; 00348 00349 if (is_stack_empty() && func == RPN_OPERATOR_EQUAL) { 00350 /* if a number has been entered with exponential */ 00351 /* notation, I may update it with normal mode */ 00352 if (calc.sci_in) 00353 return 1; 00354 return 0; 00355 } 00356 00357 if (func == RPN_OPERATOR_PERCENT) 00358 percent_mode = TRUE; 00359 00360 mpfr_init(tmp.node.number.mf); 00361 rpn_copy(&tmp.node.number, number); 00362 tmp.node.operation = func; 00363 00364 push(&tmp); 00365 mpfr_clear(tmp.node.number.mf); 00366 00367 if (func == RPN_OPERATOR_NONE) 00368 return 0; 00369 00370 if (func != RPN_OPERATOR_PARENT) { 00371 calc.last_operator = func; 00372 evalStack(number); 00373 } 00374 return 1; 00375 } 00376 00377 void exec_change_infix(void) 00378 { 00379 stack_node_t *op = stack; 00380 00381 if (op == NULL) 00382 return; 00383 if (op->node.operation == RPN_OPERATOR_PARENT || 00384 op->node.operation == RPN_OPERATOR_PERCENT || 00385 op->node.operation == RPN_OPERATOR_EQUAL) 00386 return; 00387 /* remove the head, it will be re-inserted with new operator */ 00388 pop(); 00389 } 00390 00391 void exec_closeparent(calc_number_t *number) 00392 { 00393 stack_node_t *op, ip; 00394 00395 rpn_alloc(&ip.node.number); 00396 rpn_copy(&ip.node.number, number); 00397 while (!is_stack_empty()) { 00398 op = pop(); 00399 00400 if (op->node.operation == RPN_OPERATOR_PARENT) 00401 break; 00402 00403 run_operator(&ip.node, &op->node, &ip.node, op->node.operation); 00404 if (calc.is_nan) { 00405 flush_postfix(); 00406 return; 00407 } 00408 } 00409 rpn_copy(number, &ip.node.number); 00410 rpn_free(&ip.node.number); 00411 } 00412 00413 int eval_parent_count(void) 00414 { 00415 stack_node_t *s = stack; 00416 int n = 0; 00417 00418 while (s != NULL) { 00419 if (s->node.operation == RPN_OPERATOR_PARENT) 00420 n++; 00421 s = (stack_node_t *)(s->next); 00422 } 00423 return n; 00424 } 00425 00426 void flush_postfix() 00427 { 00428 while (!is_stack_empty()) 00429 pop(); 00430 /* clear prev and last typed operators */ 00431 calc.prev_operator = 00432 calc.last_operator = 0; 00433 } 00434 00435 void start_rpn_engine(void) 00436 { 00437 mpf_set_default_prec(512); 00438 mpfr_set_default_prec(512); 00439 stack = NULL; 00440 mpfr_init(calc.code.mf); 00441 mpfr_init(calc.prev.mf); 00442 mpfr_init(calc.memory.number.mf); 00443 mpfr_init(temp.node.number.mf); 00444 rpn_zero(&calc.memory.number); 00445 } 00446 00447 void stop_rpn_engine(void) 00448 { 00449 mpfr_clear(calc.code.mf); 00450 mpfr_clear(calc.prev.mf); 00451 mpfr_clear(calc.memory.number.mf); 00452 mpfr_clear(temp.node.number.mf); 00453 } Generated on Thu Feb 9 04:38:58 2012 for ReactOS by
1.6.3
|