allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (08/27/89)
Posting-number: Volume 8, Issue 21 Submitted-by: egray@fthood.UUCP Archive-name: rpn_eg [I see a few "questional" preprocessor constructs in this code. ++bsa] Rpn is a public domain "pop up" reverse polish notation calculator that is designed to have the same (dare I say?) "look and feel" of the Hewlett-Packard HP-16c. It can compile on virtually any flavor of Unix and MSDOS. The MSDOS version will require the public domain PC Curses package. I've included both the nroff version of the Unix manual page and the "ASCII'ized" version for folks (like MSDOS) without the Document Writers Workbench. A makefile isn't required... it's only one file. Have fun... Emmet P. Gray US Army, HQ III Corps & Fort Hood ...!uunet!uiucuxc!fthood!egray Attn: AFZF-DE-ENV fthood!egray@uxc.cso.uiuc.edu Directorate of Engineering & Housing Environmental Management Office Fort Hood, TX 76544-5057 ------------------------------------------------------------------------------ #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # rpn.c # rpn.1 # rpn.man # This archive created: Fri Aug 25 14:51:23 1989 export PATH; PATH=/bin:/usr/bin:$PATH echo shar: "extracting 'rpn.c'" '(19008 characters)' if test -f 'rpn.c' then echo shar: "will not over-write existing file 'rpn.c'" else sed 's/^X//' << \SHAR_EOF > 'rpn.c' X/* X * Simple RPN (Reverse Polish Notation) calculator. Layout and functions X * loosely modeled after the HP-16c. MSDOS versions will require the X * PC Curses package. X * X * on Unix compile with: X * cc -O [-f] -s rpn.c -o rpn -lm -lcurses [-ltermcap] [-lc_s] X * X * Emmet P. Gray US Army, HQ III Corps & Fort Hood X * ...!uunet!uiucuxc!fthood!egray Attn: AFZF-DE-ENV X * fthood!egray@uxc.cso.uiuc.edu Directorate of Engineering & Housing X * Environmental Management Office X * Fort Hood, TX 76544-5057 X */ X X#undef OLD_CURSES /* for old Xenix and Berkeley */ X#undef MSDOS /* for MSDOS (requires PC Curses) */ X#undef XENIX_3 /* for old Xenix 3.0/3.5 */ X#undef BIG_END_FIRST /* for Intel style CPU's */ X#undef ANSI_C /* for ANSI C */ X X#include <stdio.h> X#include <math.h> X#include <curses.h> X X#ifdef ANSI_C X#include <limits.h> X#include <float.h> X#else /* ANSI_C */ X#define LONG_MAX 0x7fffffff X#define ULONG_MAX 0xffffffff X#define DBL_DIG 15 X#define DBL_MAX 1.7976931348623167e+308 X#endif /* ANSI_C */ X X#define DBL_ULONG_MAX 4294967295.0 /* ULONG_MAX as a double */ X X#ifdef OLD_CURSES X#define wattron(win,A_REVERSE) wstandout(win) X#define wattroff(win,A_REVERSE) wstandend(win) X#define wattrset(win,A_NORMAL) wstandend(win) X#define cbreak crmode Xchar tb[1024]; X#endif /* OLD_CURSES */ X X#ifdef MSDOS X#define what_is_at(w,a,b) (w->_line[a][b]) X#define getenv strdup X#else /* MSDOS */ X#define what_is_at(w,a,b) (w->_y[a][b]) X#endif /* MSDOS */ X /* some fundamental contstants */ X#define MAX_LOGICAL 0xffffffff X#define SCREEN_SIZE 36 X#define STACK_SIZE 5 X#define MAX_FLOAT_DIGITS SCREEN_SIZE-1 X#define MAX_HEX_DIGITS 8 X#define MAX_OCTAL_DIGITS 11 X#define MAX_DECIMAL_DIGITS 10 X#define MAX_BINARY_DIGITS 32 X#define DECIMAL_PLACES 8 X /* operating modes */ X#define FLOAT 0 X#define HEX 1 X#define DECIMAL 2 X#define OCTAL 3 X#define BINARY 4 X /* location of calculator on screen */ X#define BASE_Y 5 X#define BASE_X 0 X Xstruct layout { X char key; X int y; X int x; X}; X Xdouble stack[STACK_SIZE] = {0.0}; Xdouble sto[10] = {0.0}; Xchar blank[SCREEN_SIZE + 1]; X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X int i, mode, store_it, position, over_flow, x, y, help_is_showing; X int got_decimal, got_exponent, want_out, decimal_places; X unsigned long int_part, dtoul(); X double op2, current, pop(), convert(); X char c, c1, input[SCREEN_SIZE], *strchr(), *memset(), *term, *getenv(); X char output[SCREEN_SIZE + 1], *bitpattern(), last_operator, *strcpy(); X void push(), exit(), paint_calc(), flash_key(), clear_display(); X WINDOW *win, *hwin, *help(), *newwin(); X X /* initialize the terminal */ X term = getenv("TERM"); X if (term == NULL || *term == '\0') { X printf("%s: TERM not defined...\n", argv[0]); X exit(1); X } X /* i=1 required for PC curses */ X i = 1; X#ifdef OLD_CURSES X i = tgetent(tb, term); X#else /* OLD_CURSES */ X setupterm(term, 1, &i); X#endif /* OLD_CURSES */ X if (i != 1) { X printf("%s: No terminfo data for '%s'...\n", argv[0], term); X exit(1); X } X initscr(); X cbreak(); X noecho(); X#ifdef XENIX_3 X raw(); X#endif /* XENIX_3 */ X /* percision in the display */ X if (argc > 1 && *argv[1] == '-') { X decimal_places = atoi(&argv[1][1]); X if (decimal_places < 0) X decimal_places = 0; X if (decimal_places > DBL_DIG) X decimal_places = DBL_DIG; X } X else X decimal_places = DECIMAL_PLACES; X X win = newwin(15, 47, BASE_Y, BASE_X); X paint_calc(win); X X memset(blank, ' ', SCREEN_SIZE); X blank[SCREEN_SIZE] = '\0'; X current = 0.0; X position = 0; X mode = FLOAT; X help_is_showing = 0; X last_operator = 0; X got_decimal = 0; X got_exponent = 0; X want_out = 0; X X while (1) { X c = wgetch(win); X /* erase the help window */ X if (help_is_showing) { X help_is_showing = 0; X werase(hwin); X wrefresh(hwin); X delwin(hwin); X X touchwin(win); X wrefresh(win); X } X X store_it = 0; X over_flow = 0; X /* get incoming digits */ X switch (mode) { X case FLOAT: X if (strchr("0123456789.eE+-", c) != NULL) X store_it++; X switch (c) { X case '.': X if (got_decimal || got_exponent) X store_it = 0; X got_decimal++; X break; X case 'e': X case 'E': X if (!position || got_exponent) X store_it = 0; X got_exponent++; X break; X X /* X * Is it an operator or is it X * the sign of the exponent? X */ X case '+': X case '-': X if (!position || (input[position - 1] != 'e' && input[position - 1] != 'E')) X store_it = 0; X break; X } X if (position >= MAX_FLOAT_DIGITS) X over_flow++; X break; X case HEX: X if (strchr("0123456789abcdef", c) != NULL) X store_it++; X if (position >= MAX_HEX_DIGITS) X over_flow++; X break; X case OCTAL: X if (strchr("01234567", c) != NULL) X store_it++; X if (position >= MAX_OCTAL_DIGITS) X over_flow++; X break; X case DECIMAL: X if (strchr("0123456789", c) != NULL) X store_it++; X if (position >= MAX_DECIMAL_DIGITS) X over_flow++; X break; X case BINARY: X if (strchr("01", c) != NULL) X store_it++; X if (position >= MAX_BINARY_DIGITS) X over_flow++; X break; X } X /* store digits */ X if (store_it) { X if (over_flow) { X fputc(7, stderr); X continue; X } X flash_key(win, c); X if (!position) X clear_display(win); X waddch(win, c); X wrefresh(win); X X input[position++] = c; X input[position] = '\0'; X continue; X } X /* process pseudo operators */ X switch (c) { X case 'q': /* time to quit? */ X case 'Q': X want_out++; X break; X case '\b': /* do a backspace */ X if (position) { X input[--position] = '\0'; X flash_key(win, c); X getyx(win, y, x); X x--; X wmove(win, y, x); X waddch(win, ' '); X wmove(win, y, x); X wrefresh(win); X } X else X fputc(7, stderr); X continue; X case '?': /* help! */ X flash_key(win, c); X hwin = help(); X help_is_showing = 1; X continue; X default: X break; X } X if (want_out) X break; X /* test for valid operator */ X if (strchr("/FhHDoOB*&|lLxX\r\n-^~sSrRC+", c) == NULL) { X fputc(7, stderr); X continue; X } X /* if you've got input, convert it */ X if (position) { X current = convert(input, mode); X X /* X * This is a little weird... if the last operator was X * the <enter>, then replace (rather than push) the X * value on stack. X */ X if (last_operator == '\r' || last_operator == '\n') X stack[0] = current; X else X push(current); X X position = 0; X input[0] = '\0'; X got_decimal = 0; X got_exponent = 0; X } X /* process "real" operators */ X switch (c) { X case '\r': X case '\n': X push(current); X break; X case '+': X current = pop() + pop(); X push(current); X break; X case '-': X op2 = pop(); X current = pop() - op2; X push(current); X break; X case '*': X current = pop() * pop(); X push(current); X break; X case '/': X op2 = pop(); X if (op2 == 0.0) { X clear_display(win); X mvwaddstr(win, 3, 5, "divide by zero"); X wrefresh(win); X continue; X } X current = pop() / op2; X push(current); X break; X case 'C': /* change sign */ X current = pop() * -1.0; X push(current); X break; X case 'F': /* float */ X mode = FLOAT; X mvwaddch(win, 3, SCREEN_SIZE + 5, ' '); X wmove(win, 3, 5); X break; X case 'h': X case 'H': /* hex */ X mode = HEX; X mvwaddch(win, 3, SCREEN_SIZE + 5, 'h'); X wmove(win, 3, 5); X break; X case 'D': /* decimal */ X mode = DECIMAL; X mvwaddch(win, 3, SCREEN_SIZE + 5, 'd'); X wmove(win, 3, 5); X break; X case 'o': X case 'O': /* octal */ X mode = OCTAL; X mvwaddch(win, 3, SCREEN_SIZE + 5, 'o'); X wmove(win, 3, 5); X break; X case 'B': /* binary */ X mode = BINARY; X mvwaddch(win, 3, SCREEN_SIZE + 5, 'b'); X wmove(win, 3, 5); X break; X case '&': /* and */ X int_part = dtoul(pop()) & dtoul(pop()); X current = int_part; X push(current); X break; X case '|': /* or */ X int_part = dtoul(pop()) | dtoul(pop()); X current = int_part; X push(current); X break; X case '^': /* exclusive or */ X int_part = dtoul(pop()) ^ dtoul(pop()); X current = int_part; X push(current); X break; X case '~': /* 1's complement */ X int_part = (~dtoul(pop()) & MAX_LOGICAL); X current = int_part; X push(current); X break; X case 'x': X case 'X': /* xchg x and y */ X op2 = pop(); X current = pop(); X push(op2); X push(current); X break; X case 's': X case 'S': /* store */ X flash_key(win, c); X c1 = wgetch(win); X if (strchr("0123456789", c1) == NULL) { X fputc(7, stderr); X continue; X } X /* doesn't disturb the stack */ X sto[c1 - '0'] = current; X break; X case 'r': X case 'R': /* recall */ X flash_key(win, c); X c1 = wgetch(win); X if (strchr("0123456789", c1) == NULL) { X fputc(7, stderr); X continue; X } X current = sto[c1 - '0']; X push(current); X break; X case 'l': X case 'L': /* roll the stack */ X op2 = stack[0]; X for (i = 0; i < STACK_SIZE - 1; i++) X stack[i] = stack[i + 1]; X stack[STACK_SIZE - 1] = op2; X current = stack[0]; X break; X default: X fputc(7, stderr); X continue; X } X last_operator = c; X /* display operator key */ X flash_key(win, c); X /* convert double to unsigned long */ X if (mode != FLOAT) X int_part = dtoul(current); X X /* X * Dectect overflows in float mode only. It's OK to overflow X * in the hex/dec/oct/bin modes. X */ X if (mode == FLOAT && fabs(current) >= DBL_MAX) { X clear_display(win); X mvwaddstr(win, 3, 5, "overflow"); X wrefresh(win); X continue; X } X /* print the answer */ X switch (mode) { X case FLOAT: X sprintf(output, "%.*g", decimal_places, current); X break; X case HEX: X sprintf(output, "%lx", int_part); X break; X case OCTAL: X sprintf(output, "%lo", int_part); X break; X case DECIMAL: X sprintf(output, "%lu", int_part); X break; X case BINARY: X strcpy(output, bitpattern(int_part)); X break; X } X clear_display(win); X waddstr(win, output); X wmove(win, 3, 5); X wrefresh(win); X } X X#ifdef OLD_CURSES X move(LINES - 1, 0); X refresh(); X#endif /* OLD_CURSES */ X endwin(); X exit(0); X} X X/* X * Push a number on the stack. If the stack is full, the "top" value X * is lost. X */ X Xvoid Xpush(f) Xdouble f; X{ X int i; X X for (i = STACK_SIZE - 1; i > 0; i--) X stack[i] = stack[i - 1]; X stack[0] = f; X return; X} X X/* X * Pop a value off the stack. The "top" value is always preserved. X */ X Xdouble Xpop() X{ X int i; X double f; X X f = stack[0]; X for (i = 0; i < STACK_SIZE - 1; i++) X stack[i] = stack[i + 1]; X return (f); X} X X/* X * Convert a double to an unsigned long. Some (most?) systems will generate X * a FPE (Floating Point Exception) if you attempt to assign a double that X * is greater than LONG_MAX. X */ X Xunsigned long Xdtoul(d) Xdouble d; X{ X double temp; X unsigned long ans; X /* is it too big for assignment? */ X if (fabs(d) > LONG_MAX) { X /* chop it to a resonable size */ X temp = fmod(d, DBL_ULONG_MAX); X /* X * if the fmod() returns a zero, then the number is just too X * big to fit any useful information in 32 bits. X */ X if (temp == 0.0) X ans = ULONG_MAX; X else { X if (temp > LONG_MAX) { X ans = (temp - LONG_MAX); X ans += LONG_MAX; X } X else X ans = temp; X } X /* boundary condition at zero */ X if (temp != 0.0 && d > DBL_ULONG_MAX) X ans -= 1L; X } X else /* gee, isn't this soooo much easier? */ X ans = d; X X return (ans & MAX_LOGICAL); X} X X/* X * Convert an ascii "number" into a double. Handles hex/oct/bin digits. X */ X Xdouble Xconvert(buf, mode) Xchar *buf; Xint mode; X{ X double f, atof(); X unsigned long strtoul(); X X switch (mode) { X case DECIMAL: X case FLOAT: X f = atof(buf); X break; X case HEX: X f = (double) strtoul(buf, (char **) NULL, 16); X break; X case OCTAL: X f = (double) strtoul(buf, (char **) NULL, 8); X break; X case BINARY: X f = (double) strtoul(buf, (char **) NULL, 2); X break; X } X return (f); X} X X/* X * Convert a number into its binary bit pattern. Returns a pointer to X * a static buffer. The BIG_END_FIRST pre-processor macro determines if X * the number is stored "big end first" on your processor. X */ X Xchar * Xbitpattern(val) Xunsigned long val; X{ X unsigned char c, *p; X int i, j, size, printed, bp; X static char bitbuf[SCREEN_SIZE]; X X /* max of 32 bits */ X size = sizeof(val); X if (size > 4) X size = 4; X X p = (unsigned char *) &val; X#ifdef BIG_END_FIRST X p += size - 1; X#endif /* BIG_END_FIRST */ X X bp = 0; X printed = 0; X for (i = 1; i <= size; i++) { X c = *p; X#ifdef BIG_END_FIRST X p--; X#else /* BIG_END_FIRST */ X p++; X#endif /* BIG_END_FIRST */ X if (c == 0 && !printed && i != size) X continue; X for (j = 7; j >= 0; j--) X bitbuf[bp++] = ((c >> j) & 1) ? '1' : '0'; X if (i != size) X bitbuf[bp++] = ' '; X printed++; X } X bitbuf[bp++] = '\0'; X return (bitbuf); X} X X/* X * Put a key in inverse video. This routine leaves the key in inverse video X * until the next key is pressed. X */ Xstruct layout button[] = { X 'a', 6, 3, 'b', 6, 7, 'c', 6, 11, 'd', 6, 15, 'e', 6, 19, X 'f', 6, 23, '7', 6, 28, '8', 6, 32, '9', 6, 36, '/', 6, 40, X '?', 8, 3, 'F', 8, 7, 'h', 8, 11, 'H', 8, 11, 'D', 8, 15, X 'o', 8, 19, 'O', 8, 19, 'B', 8, 23, '4', 8, 28, '5', 8, 32, X '6', 8, 36, '*', 8, 40, '&', 10, 3, '|', 10, 7, 'l', 10, 11, X 'L', 10, 11, 'x', 10, 15, 'X', 10, 15, '\b', 10, 19, '\n', 10, 23, X '\r', 10, 23, '1', 10, 28, '2', 10, 32, '3', 10, 36, '-', 10, 40, X 'q', 12, 3, 'Q', 12, 3, '^', 12, 7, '~', 12, 11, 's', 12, 15, X 'S', 12, 15, 'r', 12, 19, 'R', 12, 19, '0', 12, 28, '.', 12, 32, X 'C', 12, 36, '+', 12, 40, '\0', 0, 0}; X Xvoid Xflash_key(win, c) XWINDOW *win; Xchar c; X{ X int i, n, temp_x, old_x, old_y; X static int last_y = 0, last_x = 0; X static char keybuf[3]; X /* get x, y coordinates */ X n = 0; X while (button[n].key != '\0') { X if (button[n].key == c) X break; X n++; X } X if (button[n].key == '\0') X return; X X getyx(win, old_y, old_x); X /* undo last button */ X if (last_y) { X if (last_y == 10 && last_x == 23) { X for (i = 0; i < 3; i++) { X wmove(win, i + 10, 23); X wattrset(win, A_NORMAL); X waddstr(win, "<cr>"); X } X } X else { X wmove(win, last_y, last_x); X wattrset(win, A_NORMAL); X waddstr(win, keybuf); X } X } X /* the enter key is 3x4 chars */ X if (button[n].y == 10 && button[n].x == 23) { X for (i = 0; i < 3; i++) { X wmove(win, i + 10, 23); X wattron(win, A_REVERSE); X waddstr(win, "<cr>"); X wattroff(win, A_REVERSE); X } X } X else { /* flash a button */ X wmove(win, button[n].y, button[n].x); X wattron(win, A_REVERSE); X temp_x = button[n].x; X for (i = 0; i < 3; i++) { X keybuf[i] = what_is_at(win, button[n].y, temp_x++); X waddch(win, keybuf[i]); X } X wattroff(win, A_REVERSE); X } X wrefresh(win); X X wmove(win, old_y, old_x); X last_y = button[n].y; X last_x = button[n].x; X return; X} X X/* X * The image of the calculator. X */ X Xvoid Xpaint_calc(win) XWINDOW *win; X{ X void mybox(); X int i; X X waddstr(win, " \n"); X waddstr(win, " Reverse Polish Notation calculator v1.1 \n"); X waddstr(win, " +---------------------------------------+ \n"); X waddstr(win, " | | \n"); X waddstr(win, " +---------------------------------------+ \n"); X waddstr(win, " \n"); X waddstr(win, " a b c d e f 7 8 9 / \n"); X waddstr(win, " \n"); X waddstr(win, " ? Flt Hex Dec Oct Bin 4 5 6 * \n"); X waddstr(win, " \n"); X waddstr(win, " & | roL Xy ^H <cr> 1 2 3 - \n"); X waddstr(win, " <cr> \n"); X waddstr(win, " Quit ^ ~ Sto Rcl <cr> 0 . Chs + \n"); X waddstr(win, " \n"); X X /* X * If you've got line drawing characters, build a box around the X * calculator display, replacing the crude one above. X */ X#ifdef ACS_VLINE X for (i = 3; i < SCREEN_SIZE + 7; i++) { X mvwaddch(win, 2, i, ACS_HLINE); X mvwaddch(win, 4, i, ACS_HLINE); X } X mvwaddch(win, 3, 3, ACS_VLINE); X mvwaddch(win, 3, SCREEN_SIZE + 7, ACS_VLINE); X /* fix up corners */ X mvwaddch(win, 2, 3, ACS_ULCORNER); X mvwaddch(win, 2, SCREEN_SIZE + 7, ACS_URCORNER); X mvwaddch(win, 4, 3, ACS_LLCORNER); X mvwaddch(win, 4, SCREEN_SIZE + 7, ACS_LRCORNER); X#endif /* ACS_VLINE */ X X mybox(win); X wmove(win, 3, 5); X wrefresh(win); X return; X} X X/* X * A box() routine that will fix up the corners if your version of X * curses is too stupid to do that itself. X */ X Xvoid Xmybox(win) XWINDOW *win; X{ X#ifdef ACS_VLINE X box(win, 0, 0); X#else /* ACS_VLINE */ X box(win, '|', '-'); X mvwaddch(win, 0, 0, '+'); X mvwaddch(win, 0, win->_maxx - 1, '+'); X mvwaddch(win, win->_maxy - 1, 0, '+'); X mvwaddch(win, win->_maxy - 1, win->_maxx - 1, '+'); X#endif /* ACS_VLINE */ X return; X} X X/* X * Clear the calculator "display" by writing blanks to it. Does not X * clear the hex/oct/dec/bin flag at the end. X */ X Xvoid Xclear_display(win) XWINDOW *win; X{ X mvwaddstr(win, 3, 5, blank); X wmove(win, 3, 5); X wrefresh(win); X return; X} X X/* X * The help screen... it really only gives a list of the abbreviations. X */ X XWINDOW * Xhelp() X{ X WINDOW *hwin, *newwin(); X void mybox(); X X hwin = newwin(14, 46, 2, 34); X waddstr(hwin, "\n RPN v1.1 - 18 Aug 89\n\n"); X waddstr(hwin, " + add & logical and\n"); X waddstr(hwin, " - subtract | logical or\n"); X waddstr(hwin, " * multiply ^ exclusive or\n"); X waddstr(hwin, " / divide ~ 1's complement\n"); X waddstr(hwin, " <cr> enter key Chs change sign\n"); X waddstr(hwin, " Flt float mode Sto store [0-9]\n"); X waddstr(hwin, " Hex hex mode Rcl recall [0-9]\n"); X waddstr(hwin, " Oct octal mode roL roll stack\n"); X waddstr(hwin, " Bin binary mode Xy exchange x y\n"); X mybox(hwin); X wrefresh(hwin); X return (hwin); X} X X#ifndef ANSI_C X#include <errno.h> X#include <ctype.h> Xextern int errno; X Xunsigned long Xstrtoul(buf, trailing, base) Xchar *buf; Xchar **trailing; Xint base; X{ X int c; X unsigned long ans; X X ans = 0L; X X while (isspace(*buf)) X buf++; X /* try to guess the base */ X if (base == 0) { X if (*buf == '0') { X base = 8; X if (buf[1] == 'x' || buf[1] == 'X') X base = 16; X } X else X base = 10; X } X /* skip over '0x' and '0X' */ X if (base == 16) { X if (*buf == '0' && (buf[1] == 'x' || buf[1] == 'X')) X buf += 2; X } X X while (1) { X c = *buf; X if (isdigit(c)) X c -= '0'; X else if (islower(c)) X c -= 'a' - 10; X else if (isupper(c)) X c -= 'A' - 10; X else /* unrecognized character, so stop */ X break; X /* is this digit allowed? */ X if (c >= base) X break; X X if ((ULONG_MAX - (unsigned int) c) / (unsigned int) base < ans) { X ans = ULONG_MAX; X errno = ERANGE; X break; X } X ans = ans * base + c; X buf++; X } X X if (trailing) X *trailing = buf; X X return (ans); X} X#endif /* ANSI_C */ SHAR_EOF if test 19008 -ne "`wc -c < 'rpn.c'`" then echo shar: "error transmitting 'rpn.c'" '(should have been 19008 characters)' fi fi echo shar: "extracting 'rpn.1'" '(4028 characters)' if test -f 'rpn.1' then echo shar: "will not over-write existing file 'rpn.1'" else sed 's/^X//' << \SHAR_EOF > 'rpn.1' X.TH RPN 1 local X.SH NAME Xrpn \- an HP-16c reverse polish notation (rpn) calculator X.SH SYNOPSIS X.B rpn X[ X.B \-d X] X.SH DESCRIPTION X.I Rpn Xis a ``pop up'' calculator for Unix and MSDOS that is designed to Xoperate similar to the Hewlett-Packard HP-16c (Computer Scientist) Xcalculator. It can operate in a floating point, hexidecimal, decimal, Xoctal, or binary mode. X.PP XThe X.I \-d Xoption is used to specify the number of decimal point precision that Xwill appear in the display. The internal precision of the calculator is Xnot affected. X.PP XThe calculator appears on the screen as: X.PP X.RS 5 X.nf X+---------------------------------------------+ X| Reverse Polish Notation calculator v1.1 | X| +---------------------------------------+ | X| | | | X| +---------------------------------------+ | X| | X| a b c d e f 7 8 9 / | X| | X| ? Flt Hex Dec Oct Bin 4 5 6 * | X| | X| & | roL Xy ^H <cr> 1 2 3 - | X| <cr> | X| Quit ^ ~ Sto Rcl <cr> 0 . Chs + | X| | X+---------------------------------------------+ X.fi X.RE X.PP XThe ``buttons'' that appear on the screen turn to inverse video when the Xappropriate key on the keyboard is pressed. X.PP XReverse polish notation is an operating logic that envolves the use of Xthe ``enter'' key in lieu of an equal sign. To perform arithmetic, Xkey in the first number, press the ``enter'' key, key in the second Xnumber, and then press the operator. For example, to add 2 plus 3, Xyou type: X.PP X.RS 5 X2 ``enter'' 3 +. X.RE X.PP XThe current mode of the calculator is displayed in the last Xposition on the ``screen'' as a blank, 'h', 'd', 'o', or 'b' for the Xfloating point, hexidecimal, decimal, octal, and binary modes Xrespectively. X.PP XThe use of the hex, decimal, octal, or binary modes implies that Xfractional parts of numbers are discarded and that negative numbers are Xdisplayed as a 2's complement. X.SH COMMANDS XThe X.I rpn Xprogram can perform the following mathematical and logical functions: X.PP X.RS 5 X.nf X.if n .ta 2.5i X.if t .ta 2i X\fB+\fP addition \fB&\fP logical and X\fB-\fP subtraction \fB|\fP logical or X\fB*\fP multiplication \fB^\fP logical exculsive or X\fB/\fP division \fB~\fP 1's complement X.fi X.RE X.PP XThe following operators are also available: X.TP X.B ? XHelp screen. A pop-up help screen to explain the abreviations. X.TP X.B F XFloating point mode. Numbers with decimal points and/or exponents may Xbe used. Exponents are entered with the 'e' and may be followed by an Xoptional sign, as in 1.23e-12. X.TP X.B H XHexidecimal mode. Numbers use hexidecimal notation (digits in the range Xof 0-9 and a-f). The maximum hexidecimal number is 0xffffffff. To Xenter a hexidecimal digit in the range of a-f, you \fImust\fP use lower Xcase letters. X.TP X.B D XDecimal mode. Numbers use decimal notation (digits in the range of X0-9). The maximum decimal number is 4294967295. X.TP X.B O XOctal mode. Numbers use octal notation (digits in the range of 0-7). XThe maximum octal number is 0377777777777. X.TP X.B B Xbinary mode. Numbers use binary notation (the digits 0 and 1). The Xmaximum is 32 bits. X.TP X.B L XRoll the stack. The contents of the stack are ``rolled'' down by one Xposition. X.TP X.B X XExchange X and Y values. The last two values on the stack (X and Y) Xswap positions. X.TP X.B ^H XThe backspace key, to correct input. X.TP X.B ^M XThe ``enter'' key, shown as <cr> on the calculator. X.TP X.B Q XQuit. Exit the program. X.TP X.B S XStore a value in a register. Registers are numbered 0-9. To store a value Xin register 2, you enter S2. X.TP X.B R XRecall a value from a register. Registers are numbered 0-9. X.TP X.B C XChange sign. To enter a negative number, you first enter the number and Xthen change the sign. X.SH BUGS XMost operators are case sensitive. X.SH "SEE ALSO" Xdc(1), bc(1) SHAR_EOF if test 4028 -ne "`wc -c < 'rpn.1'`" then echo shar: "error transmitting 'rpn.1'" '(should have been 4028 characters)' fi fi echo shar: "extracting 'rpn.man'" '(5173 characters)' if test -f 'rpn.man' then echo shar: "will not over-write existing file 'rpn.man'" else sed 's/^X//' << \SHAR_EOF > 'rpn.man' X X X X RPN(1) (local) RPN(1) X X X X NAME X rpn - an HP-16c reverse polish notation (rpn) calculator X X SYNOPSIS X rpn [ -d ] X X DESCRIPTION X Rpn is a ``pop up'' calculator for Unix and MSDOS that is X designed to operate similar to the Hewlett-Packard HP-16c X (Computer Scientist) calculator. It can operate in a X floating point, hexidecimal, decimal, octal, or binary mode. X X The -d option is used to specify the number of decimal point X precision that will appear in the display. The internal X precision of the calculator is not affected. X X The calculator appears on the screen as: X X +---------------------------------------------+ X | Reverse Polish Notation calculator v1.1 | X | +---------------------------------------+ | X | | | | X | +---------------------------------------+ | X | | X | a b c d e f 7 8 9 / | X | | X | ? Flt Hex Dec Oct Bin 4 5 6 * | X | | X | & | roL Xy ^H <cr> 1 2 3 - | X | <cr> | X | Quit ^ ~ Sto Rcl <cr> 0 . Chs + | X | | X +---------------------------------------------+ X X The ``buttons'' that appear on the screen turn to inverse X video when the appropriate key on the keyboard is pressed. X X Reverse polish notation is an operating logic that envolves X the use of the ``enter'' key in lieu of an equal sign. To X perform arithmetic, key in the first number, press the X ``enter'' key, key in the second number, and then press the X operator. For example, to add 2 plus 3, you type: X X 2 ``enter'' 3 +. X X The current mode of the calculator is displayed in the last X position on the ``screen'' as a blank, 'h', 'd', 'o', or 'b' X for the floating point, hexidecimal, decimal, octal, and X binary modes respectively. X X The use of the hex, decimal, octal, or binary modes implies X that fractional parts of numbers are discarded and that X X X X Page 1 X X X X X X X RPN(1) (local) RPN(1) X X X X negative numbers are displayed as a 2's complement. X X COMMANDS X The rpn program can perform the following mathematical and X logical functions: X X + addition & logical and X - subtraction | logical or X * multiplication ^ logical exculsive or X / division ~ 1's complement X X The following operators are also available: X X ? Help screen. A pop-up help screen to explain the X abreviations. X X F Floating point mode. Numbers with decimal points X and/or exponents may be used. Exponents are entered X with the 'e' and may be followed by an optional sign, X as in 1.23e-12. X X H Hexidecimal mode. Numbers use hexidecimal notation X (digits in the range of 0-9 and a-f). The maximum X hexidecimal number is 0xffffffff. To enter a X hexidecimal digit in the range of a-f, you must use X lower case letters. X X D Decimal mode. Numbers use decimal notation (digits in X the range of 0-9). The maximum decimal number is X 4294967295. X X O Octal mode. Numbers use octal notation (digits in the X range of 0-7). The maximum octal number is X 0377777777777. X X B binary mode. Numbers use binary notation (the digits 0 X and 1). The maximum is 32 bits. X X L Roll the stack. The contents of the stack are X ``rolled'' down by one position. X X X Exchange X and Y values. The last two values on the X stack (X and Y) swap positions. X X ^H The backspace key, to correct input. X X ^M The ``enter'' key, shown as <cr> on the calculator. X X Q Quit. Exit the program. X X S Store a value in a register. Registers are numbered X 0-9. To store a value in register 2, you enter S2. X X X X Page 2 X X X X X X X RPN(1) (local) RPN(1) X X X X R Recall a value from a register. Registers are numbered X 0-9. X X C Change sign. To enter a negative number, you first X enter the number and then change the sign. X X BUGS X Most operators are case sensitive. X X SEE ALSO X dc(1), bc(1) X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X Page 3 X X X SHAR_EOF if test 5173 -ne "`wc -c < 'rpn.man'`" then echo shar: "error transmitting 'rpn.man'" '(should have been 5173 characters)' fi fi exit 0 # End of shell archive