double compute(int size, unsigned int form, double_string *ds, counter *ops) { rpn_stack s = malloc(sizeof(rpn_stack)); unsigned int shift = form; int ops_p = 0; double v = 0.0; int i = 0; for(i = 0 ; i < size; i++) { if((shift & 0x01) == 1) { rpn_push(&s, ds->value); ds = ds->next; } else { switch(ops->values[ops_p++]) { case 0 : v = rpn_calc(&s, '+'); break; case 1 : v = rpn_calc(&s, '-'); break; case 2 : v = rpn_calc(&s, '*'); break; case 3 : v = rpn_calc(&s, '/'); break; } } shift = shift >> 1; } rpn_destroy(s); return v; }
//電卓関数モードで中間か逆ポーランドか選択可能 void calc(char* formula) { printf("\tCalc Exec : Start\n"); //エラーフラグのクリア error_flag = 0; #ifdef _Debug_enable //デバッグ用 printf("\t\tDebug : calc -> mode set search start\n"); #endif char tmp_buffer[BUFFER_LENGTH]; my_strcpy(tmp_buffer,formula); string_trim(tmp_buffer); //コマンド部分に関する記述 if(string_match(tmp_buffer,"set")) { printf("\tCalc Exec : detected \"set\"\n"); if(string_match(tmp_buffer,"mode=IN")) { mode = IN_MODE; printf("\tCalc Exec : set Calc mode = IN_MODE\n"); return; } else if(string_match(tmp_buffer,"mode=RPN")) { mode = RPN_MODE; printf("\tCalc Exec : set Calc mode = RPN_MODE\n"); return; } else { printf("\tCalc Exec : Please retry set mode.\n"); return; } } else if(string_match(tmp_buffer,"quit")||string_match(tmp_buffer,"exit")) { mode = EXIT_MODE; return; } #ifdef _Debug_enable //デバッグ用 printf("\t\tDebug : calc -> mode = %d, fromula = \"%s\"\n",mode,formula); #endif //計算関数呼び出し switch(mode) { case RPN_MODE : rpn_calc(formula); break; case IN_MODE : in_calc(formula); break; } }
//デバッグ用 //中間モードの関数(実際は逆ポーランドに変換) void in_calc(char* formula) { //中間置方だと空白があった場合に支障を来すことがあるので空白を削除 printf("\tIN Calc Exec : formula = \"%s\"\n",formula); string_trim(formula); printf("\tIN Calc : trim formula \"%s\"\n",formula); //RPNの形式へ変換 convert_in_formula_to_rpn_formula(formula); //RPNで計算実行 rpn_calc(formula); }
double compute_verbose(int size, unsigned int form, double_string *ds, counter *ops) { rpn_stack s = malloc(sizeof(rpn_stack)); unsigned int shift = form; int ops_p = 0; double v = 0.0; double p1, p2; int op_last = 0; int i = 0; for(i = 0 ; i < size; i++) { if((shift & 0x01) == 1) { rpn_push(&s, ds->value); ds = ds->next; op_last = 0; } else { switch(ops->values[ops_p++]) { case 0 : p1 = s->value; p2 = s->p->value; v = rpn_calc(&s, '+'); if(op_last == 0) printf("%.2f + %.2f = %.2f\n", p1, p2, v); else printf(" + %.2f = %.2f\n", p2, v); op_last = 1; break; case 1 : p1 = s->value; p2 = s->p->value; v = rpn_calc(&s, '-'); if(op_last == 0) printf("%.2f - %.2f = %.2f\n", p1, p2, v); else printf(" - %.2f = %.2f\n", p2, v); op_last = 1; break; case 2 : p1 = s->value; p2 = s->p->value; v = rpn_calc(&s, '*'); if(op_last == 0) printf("%.2f * %.2f = %.2f\n", p1, p2, v); else printf(" * %.2f = %.2f\n", p2, v); op_last = 1; break; case 3 : p1 = s->value; p2 = s->p->value; v = rpn_calc(&s, '/'); if(op_last == 0) printf("%.2f / %.2f = %.2f\n", p1, p2, v); else printf(" / %.2f = %.2f\n", p2, v); op_last = 1; break; } } shift = shift >> 1; } rpn_destroy(s); return v; }
int main() { char *o, *p, *line; queue *q; double *r, *s; double *pi = malloc(sizeof(double)); double *e = malloc(sizeof(double)); double *ans = malloc(sizeof(double)); *pi = 3.1415926535; *e = 2.7182818285; *ans = 0; hm = hashmap_new(); hashmap_put(hm, "pi", pi); hashmap_put(hm, "e", e); hashmap_put(hm, "ans", ans); /* read input using linenoise */ while((line = linenoise("> ")) != NULL) { /* add the line to history */ linenoiseHistoryAdd(line); /* check if there is an equals sign */ for (p = line; (*p != '\0') && (*p != '='); p++); if (*p == '\0') p = line; else { /* equals sign present */ /* check for spaces */ for (o = line; (*o != ' ') && (*o != '='); o++); *o = '\0'; p++; /* skip equals sign when parsing equation */ } q = syard_run(p); if (q == NULL) continue; #ifdef __DEBUG queue_foreach(q, testfunc, NULL); printf("\n"); #endif r = rpn_calc(q, variable_resolver, func_wl); if (r == NULL) continue; printf("= %g\n", *r); /* store ans */ *ans = *r; if (p != line) { /* equals sign present */ if ((s = hashmap_get(hm, line)) != NULL) { /* existing value, just overwrite it */ *s = *r; free(r); } else { /* new value */ hashmap_put(hm, line, r); } } else { /* no equals sign, so we're done with the number now */ free(r); } /* free storage and stuff */ linenoiseFree(line); } hashmap_iterate(hm, hm_cleaner, NULL); hashmap_destroy(hm); return 0; }