rca(1) General Commands Manual rca(1) NAME rca - a rich/RPN (and more) programmer's calculator SYNOPSIS rca [ initial rca command text ] DESCRIPTION rca is a command-line reverse polish notation (RPN) calculator loosely inspired by the long line of Hewlett-Packard scientific calculators. Operators include scientific, logical, and bitwise operations. rca can also evaluate traditional infix (parenthesized) expressions, greatly expanding its usefulness. As a programmer's calculator, word width can be adjusted to emulate the arithmetic of any class of CPU. rca can also be easily incorporated into shell scripts to provide floating point support. Whitespace in rca's input is often optional, though some cases will cause ambiguity. Any text following (and including) a # character is ignored as a comment. The value at the top of the stack can be shown with the p command, and the entire stack with P. Autoprinting will print the top of the stack after most input lines. This is on by default; it can be toggled off with 0 autoprint (or 0 a). If rca is built with the readline library, then command line editing, command history, and command completion are available. REVERSE POLISH NOTATION Numbers entered by the user are pushed onto a stack. An operator pops those stack entries, usually 1 or 2 at a time, and pushes the result of the operation back on the stack. There are operators for the usual arithmetic operations (+, -, etc), functions (sin, cos, sqrt, etc), bit-shifting and manipulation (<<, >>, &, |, etc), logical operations (&&, ||), and comparators (==, !=, <=, etc). There are also unit conversions available (i2mm, oz2g, f2c, and more). A complete list of operators can be obtained with the help (or ?) command. The top two elements on the stack, in HP tradition, are sometimes referred to in the documentation as x and y, but not literally within the program itself with one exception: the lastx (or lx) operator returns the value that was at the top of stack just previous to the most recently executed operator. INFIX NOTATION rca supports infix (i.e., traditional, "normal") expressions. Such expressions must be fully enclosed in parentheses, and cannot cross to a new line. (Infix expressions are translated to RPN by an implementation of Dijkstra's "shunting yard" algorithm, and then executed as usual.) A single line of input can be a mix of RPN notation (unparenthesized) and complete infix expressions (parenthesized). The infix expressions "escape" the RPN model, and are evaluated with fairly typical rules of precedence (see OPERATOR PRECEDENCE below). All input number formats are accepted in infix, just as in RPN. All rca stack operators can be used as infix functions, including the unary operators (i.e., -x +x ~x !x), and all of the comparison, logical, and bitwise operators. Infix expressions result in a value pushed onto the stack: (-3 + 5) will push the value 2. With single operand operators, the operand will always follow the operator. For two operand operators, one operand will be to either side of the operator. Exponentiation would be written as ( 3 ** 2 ), (giving 9), and bit-setting as (2 setb 3) (giving 10). The expression (sin 180 == cos 90) yields the value 1, i.e. "true". The lastx (or lx) operator can be used in an infix expression. It returns the value of x (i.e., the top of stack) prior to the expression being invoked. Variables, named with a leading '_' (underscore), like _a, _tmp, or _my_var. can be referenced for either reading or writing. (Variab See the SPECIAL VALUES AND VARIABLES section, below. Multiple expressions separated by ';' (semicolon) can be enclosed in a single pair of parentheses. The result of the parenthesized expression is the result of the last such sub-expression. (Like ',' in the C language, ';' is implemented as an operator whose result is its right-hand operand -- the left-hand operand is discarded (after evaluation). So ';' is also available in RPN: when executed, it discards the second-to-top stack element, leaving the top undisturbed.) If an error occurs during evaluation of an infix expression, evaluation will cease, and the stack will be left as it was at the point of the error. OPERATING MODES rca can be configured into two main modes of operation: floating point (the default) using the F command, and integer, using one of D (signed decimal), U (unsigned decimal), H (hex), O (octal), or B (binary). The difference between the various integer modes lies in how values are displayed by default, but floating point differs in a few additional ways. Most math is done in long double, regardless of mode, but in integer mode all stack values are masked to the current word width, and sign extended, if necessary. Where the difference matters, math is performed using signed arithmetic in signed decimal (D) mode, but using unsigned arithmetic in U, H, O,and B modes. The input base of a number is independent of the mode, and controlled entirely by how it is entered: 10, 0xa, 0o12, 0b1010 and 1e01 are all the same value. The mode does not affect input: for example, hex values must include the "0x" prefix even in H mode.) Note that octal must be entered using the "0o" prefix, which is also how octal will be printed. The more traditional "0" prefix will be interpreted as decimal. Also note that numbers can be entered as negative decimals even when the resulting bit pattern will be interpreted using unsigned arithmetic. Floating point In floating point mode (i.e., F mode), all operations use the full size of long double. Printing can be controlled by either the precision (k) command (which specifies a number of digits for the printf "%g" format), or by the decimals (K) command (which specifies the number of decimals for the printf "%f" format). So the value of pi multiplied by 1 million will display as 3.14159e+06 with 6 k or as 3,141,592.6535898 with 7 K. Scientific notation (e.g., 1e09) will be used in precision mode when the exponent is less than -4, or greater than the chosen precision. (These cutoffs come from directly from printf.) rca will try to prevent you from printing with more than the available significant digits on the system: the default precision value is set based on this limit (18 digits for most modern PC architectures), and can't be raised above it. However, if viewing %f output (by choosing a decimals (K) value), it's easy to start seeing "unclean" bits if the magnitude of the number grows beyond the number of significant digits. The numbers are really big at that point: over 1e19 on a modern system. Use precision (k) display to select "smart" printing, which will hide insignificant digits. Because floating point is inherently inexact, values are sometimes calculated which are almost correct (like .99999999999... instead of 1), but not quite. rca tries to help by "snapping" values that are very close to integers to those integers, and by rounding when the precision limits of the floating point representation are reached. See also the DATA TYPES, OVERFLOW, ACCURACY section, below. Integer Integer mode is selected with any of the following commands, which also choose the default display format: D (signed decimal), U (unsigned decimal), H (hex), O (octal), or B (binary). The default printing format is used by the p, P, and autoprint commands. Regardless of the default format, individual values can be viewed at any time in any format by using f, d, u, h, o, or b. By default the width of rca's integers is the maximum supported, but it can be configured to as few as 2 bits using the width (or w) command. Requesting a width of 0 will choose the maximum width. The maximum supported width will be either the width of the long long data type, or of the long double mantissa, whichever is smaller. This results in 64 bits on most PC architectures in 2025. Two counter-examples: The Raspberry Pi 3 has just 52 bits of long double mantissa, so rca's maximum integer width there is limited to 52, at least on a 32 bit OS. The Raspberry Pi 4 supports 128-bit "quad-precision" floats with 113 bits of mantissa, so has excellent floating point accuracy: about 33 decimal digits. But integers in rca are still limited to the largest native integer size, 64 bits.) Values will be masked to the current word width for both use and display, whether they are input by the user or result from an operation. Arithmetic on all values will be signed. If floating operations are used on width-restricted integers, the width restriction will be ignored for the operation, but masking will happen when storing the result. Numeric separators rca can add commas (or the locale's "thousands separator") to group the numbers it prints. These separators can be toggled on or off with 0/1 s (or separators). Separators will never appear in the fractional part of a value. The separators are strictly cosmetic, based on the printed digits. No bitwise splitting (e.g., into bytes) is implied. Numeric grouping will not be functional if the locale doesn't define a thousands separator. Also, numeric grouping may not be functional if rca is built with libraries other than glibc. (In that case the separators command will be missing entirely.) On input, the locale's currency symbol and thousands separator will be ignored, as a convenience for doing arithmetic on copy/pasted data. If the locale isn't configured, then for the purpose of input stripping only, these symbols will be set to defaults of '$', and ',', respectively. SPECIAL VALUES AND VARIABLES The pi and e operators push the obvious constants onto the stack. In the HP tradition, the sto ("store") operator copies x to an off-stack storage location (without disturbing the stack). rcl ("recall") fetches that value, pushing it onto the stack. These commands are largely superceded by rca variables. Variables are created dynamically (with a value of 0) on first reference, either by assigning a value ( _var = 42), or by using it ( _var + 17). Variables' names must start with an underscore character. Variables cannot be deleted. In RPN, simply naming the variable will push its value to the stack. To write to a variable in RPN, the "assign to" operator (=) must be used immediately before naming the variable. If = is not follwed by a variable name, it's a no-op. (This is the only "stateful" RPN operation.) The following two sequences are equivalent. Both set 4 variables: _w, _l, _area, and _diagonal. 3=_w 4=_l * = _area _l 2 ^ _w 2 ^ + sqrt = _diagonal and (_w=3; _l=4; _area=_l * _w; _diagonal = sqrt (_w^2 + _l^2)) Variables can be listed with variables or vars. CONFIGURATION rca doesn't read a configuration file on startup. Instead, commands are read from the environment variable RCA_INIT, and from any command line arguments. Initial conditions can be established by either method. Printed output from commands run from $RCA_INIT is suppressed. The commands that control rca's operation and appearance have all been fully described elsewhere, but a concise list may be useful: F, D, U, H, O, and B choose float or integer, and the default output base. (Startup: F) precision (or k) chooses "significant digits" output, and how many. (Startup: 6) decimals (or K) chooses "decimal places" output, and how many. width (or w) chooses the size of integers, in bits. (Startup: system maximum, likely 64). rightalign (or right) toggles whether values should be vertically aligned at the left margin by their first digit, or to the right, by their decimal point. (Startup: enabled) zerofill (or z) toggles whether or not hex, octal, and binary integers will be left-padded out to the chosen word width with zeros. (Startup: disabled) degrees toggles whether degrees are used by the trig functions, instead of radians. (Startup: enabled) separators (or s) toggles whether output will include separators (usually ',', but see the LOCALE section) for readability. (Startup: enabled) autoprint (or a) toggles printing of the top of stack after newlines. (Startup: enabled) errorexit forces rca to exit on any subsequent error. Normally errors which result from user input are reported, but operation continues. (Startup: disabled) All of the listed commands will print a confirmation message, but to avoid confusion, that message will only print if the command is the last on its line of input. HELP The help or ? gives a complete list of operators/commands. If $PAGER is set in the environment, the shell command it names will be used to display the help text. (The command must read the text from standard input.) Otherwise the text will be sent directly to stdout. The state command will print a verbose summary of rca's current state. OPERATOR PRECEDENCE Infix evaluation depends on operator precedence and associativity. The precedence command lists the operators by decreasing precedence. The 'R' denotes those which are right associative. All others group left to right. (This list has no meaning for RPN.) 1 ( ) 2 R ~ ! + - chs negate nop recip sqrt sin cos tan asin acos atan exp ln log2 log10 abs frac int i2mm mm2i ft2m m2ft mi2km km2mi f2c c2f oz2g g2oz oz2ml ml2oz q2l l2q d2r r2d mpg2l100km 3 R ^ ** 4 atan2 5 * x / % 6 + - 7 >> << 8 & clearb 9 xor 10 | setb 11 < > <= >= 12 == != 13 && 14 || 15 = 16 ; There's some personal preference in there. Like C, Java, JavaScript, and Rust (but unlike Python and bc), the ! operator (logical NOT) is a high-precedence unary operator and binds very strongly. So (!_a == _b) is the same as ((!_a) == _b). But unlike C, Java, and JavaScript (but like Ruby, Python, Rust, and bc), the bitwise operators bind more tightly than comparison operators. So (_a & _b == 5) is the same as ((_a & _b) == 5). Even Dennis Ritchie thought C got that one wrong. OPERATOR NOTES Most operators behave as they are commonly understood to. A few need more specific documentation. In rca's infix expressions, exponentiation (^ or **) is right associative, and has lower precedence than unary minus. Each of these lines returns a result of 1 (true): ((2 ^ 3 ^ 2) == (2 ^ (3 ^ 2))) # i.e., 512 ((-3 ^ 2) == ((-3) ^ 2))) # i.e., 9 modulo is a floating point operation, not integer. It uses the C fmodl() library. frac applied to negative values will give a negative result. In an infix expression, operators with two arguments expect them to the left and right. This is intuitive for symbolic operators (as in 1 + 2 ), but for named operators it can look odd. (0xf0 setb 3 ), for example, sets bit 3 in 0xf0. atan2 works similarly. This expression: (sin 30 atan2 cos 30) could also be written as ((sin 30) atan2 (cos 30)) and will evaluate to "30". (In RPN, this would be 30 sin 30 cos atan2.) The trigonometric functions (sin, cos, tan, asin, acos, atan, and atan2) take and return angles in degrees by default. 0 degrees will switch them to radians, and 1 degrees will switch them back. Also, the d2r/r2d operators convert the angle units directly. Bitwise operations (~ <<, >>, &, |, xor, clearb, and setb) convert their operands to integer first, regardless of mode. As might be expected, these operations will discard fractional parts, and may discard significant digits, including the sign of the value. Bitwise operations will not execute, and will cause an error, if either operand will not fit in a long long. sum (or avg) will pop and add (or add and then average) previous entries on the stack, stopping when the stack is empty, or when a stack marker previously set with the mark command is reached. The mark would be set before entering the data for a subsequent sum (or avg), in order to limit its reach. N mark (i.e., a mark command with an argument of N) will cause a later sum (or avg) to include the current top N values, plus any more values that have been pushed prior to the sum. N cannot be greater than the length of the stack. 0 mark will cause only subsequent pushes to be summed/averaged. -1 mark will clear the mark. sum and avg are the only operators to consume more than 2 stack elements. LOCALE The locale is consulted for just three things. The locale chooses the decimal point. Usually this is '.', but is also commonly ','. If the locale defines a thousands separator, it will be used for numeric grouping, and will be ignored during input. If the locale doesn't define a thousands separator, there will be no numeric grouping. If the locale defines a currency symbol, and its value doesn't match the name of any rca command, it will be ignored on input. If the locale doesn't define a currency symbol, it will be set to "$", and ignored on input. DATA TYPES, OVERFLOW, ACCURACY All stack values in rca are stored in long double format. This is convenient for a calculator which will primarily deal with floating point, but can affect rca's mixed model. Changing rca's operating mode from floating point to an integer mode requires conversion of all stack values to integer. If the conversion from long double to long long can't be done without loss, a error message is issued, but the conversion has already occurred, and the loss cannot be undone. If simply displaying a float value as integer, without changing modes, then the original value is unchanged. Execution will proceed after the warning unless errorexit has been enabled. Some floating point operations give results which are invalid ("nan", i.e., "not a number") or "+inf" or "-inf" (i.e., infinity). When converting to integer mode, these values will be preserved, along with their semantics: any computation involving nan will return nan, and any conditionals involving nan will return false. rca doesn't distinguish between mathematical poles (e.g., the value of "tan(pi/2)") and overflow conditions (very large finite values that could be represented, if only you'd bought a better calculator). Both show as "+/-inf". Floating point math by its nature is imprecise. It's not uncommon for small rounding errors, and errors introduced by the necessary binary to decimal conversions, to change values in obvious ways. Something that should be 0 may instead have a very tiny value, or two numbers which should be equal may differ by an insignificant amount. rca attempts to help by adjusting values pushed on the stack. First, values within about 2e-18 (system dependent) of an integer are forced to that integer. Then, values are decimal- rounded to rca's maximum precision (again, usually 18 digits). This rounding/snapping behavior can be disabled with the 0 rounding command, but be warned: simple equalities, like (1.2 * 3 == 3.6) may no longer hold true. Using the r and R commands to print and work in raw floating hex mode (printf's "%a" format) can help show what's going on. EXIT STATUS rca will normally exit with status 0 or 1. To satisfy normal shell boolean logic semantics, the exit status will be 0 if the top of stack is non-zero, and 1 if the top of stack is 0. A normal exit with an empty stack causes an exit status of 2. Unrecoverable internal errors (e.g., failed memory allocation) cause an exit status of 3. Errors resulting from user input (parsing errors, empty stack, data conversion warnings) are non- fatal unless the errorexit toggle has been set. In that case, those warnings and errors will cause exit status of 4. This can be useful when rca is used non-interactively. SHELL SUPPORT Incorporating rca into the shell is straightforward: # This shell snippet gives simple access to rca's floating point # capability from a POSIX shell. Use it with "source rca_float". # # After including this code, use lines like this to calculate: # foo=$(fe "$bar * pi") # or like this for a conditional expression: # if fc "(10 * 3) < $foo"; then ... # # Use RCA_INIT to set common initial conditions. Defaults are # provided here, but values set externally will override. export RCA_INIT="3decimals 0separators 1errorexit ${RCA_INIT:-}" _rca_run() # support routine { local output exitcode output=$(rca "$*" q) exitcode=$? case $exitcode in 0|1) echo $output return $exitcode ;; esac echo rca failure: $output >&2 exit $exitcode } fe() # Evaluate a floating point expression. { _rca_run "( $* )" return 0 } fc() # Evaluate a floating point conditional expression. { _rca_run "( $* )" >/dev/null } AUTHOR Paul Fox created rca (formerly called "ca") very slowly over a span of decades, starting in 1993. 2026-02-03 rca(1)