Umgekehrt polnische Notation
Dieses Programm ist ein Taschenrechner mit umgekehrt polnischer Notation.
/* * UPN - a reverse polish calculator * Copyright (C) 2005 Nicolas Bellm * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * gcc -lm -std=c99 upn.c * */ #include <stdio.h> #include <math.h> #include <error.h> #define SIZE 255 double stack[SIZE]; double *p; int push(double d, double *r) { if (p < &stack[SIZE]) { *p = *r = d; p++; return 0; } else { error(0, 0, "Stack-Überlauf"); return 1; } } int pop(double *r) { if (p > &stack[0]) { p--; *r = *p; return 0; } else { error(0, 0, "Stack-Unterlauf"); return 1; } } double add(double d1, double d2) { return d1 + d2; } double sub(double d1, double d2) { return d1 - d2; } double mul(double d1, double d2) { return d1 * d2; } double div(double d1, double d2) { return d1 / d2; } double root(double d1, double d2) { return pow(d2, 1/d1); } int calc(double f(double, double)) { double d1, d2; if (pop(&d2) || pop(&d1)) { return 1; } d1 = f(d1, d2); if (!isnormal(d1)) { error(0, 0, "Ergebnis ist keine Zahl!"); return 1; } push(d1, &d1); printf("%lf\n",d1); return 0; } int cal(double f(double)) { double d; if (pop(&d)) { return 1; } d = f(d); if (!isnormal(d)) { error(0, 0, "Ergebnis ist keine Zahl!"); return 1; } push(d, &d); printf("%lf\n",d); return 0; } int main() { double d; char buf[SIZE]; p = &stack[0]; while(1) { printf(">"); fgets(buf, SIZE, stdin); if (buf && buf[0] != '\n' && sscanf(buf, "%lf", &d)) { push(d, &d); } else { switch(buf[0]) { case '+': calc(add); break; case '-': calc(sub); break; case '*': calc(mul); break; case '/': calc(div); break; case '^': calc(pow); break; case 's': cal(sqrt); break; case 'c': cal(cbrt); break; case 'r': calc(root); break; case 'x': return 0; default: error (0, 0, "Fehlerhafte Eingabe"); break; } } } }