Gavin Howard | 7a62fec | 2020-07-01 13:40:37 -0600 | [diff] [blame] | 1 | .\" |
| 2 | .\" SPDX-License-Identifier: BSD-2-Clause |
| 3 | .\" |
| 4 | .\" Copyright (c) 2018-2020 Gavin D. Howard and contributors. |
| 5 | .\" |
| 6 | .\" Redistribution and use in source and binary forms, with or without |
| 7 | .\" modification, are permitted provided that the following conditions are met: |
| 8 | .\" |
| 9 | .\" * Redistributions of source code must retain the above copyright notice, |
| 10 | .\" this list of conditions and the following disclaimer. |
| 11 | .\" |
| 12 | .\" * Redistributions in binary form must reproduce the above copyright notice, |
| 13 | .\" this list of conditions and the following disclaimer in the documentation |
| 14 | .\" and/or other materials provided with the distribution. |
| 15 | .\" |
| 16 | .\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| 17 | .\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 18 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 19 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
| 20 | .\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 21 | .\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 22 | .\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 23 | .\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 24 | .\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 25 | .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 26 | .\" POSSIBILITY OF SUCH DAMAGE. |
| 27 | .\" |
Gavin Howard | a51c501 | 2020-07-01 13:39:23 -0600 | [diff] [blame] | 28 | .TH "DC" "1" "July 2020" "Gavin D. Howard" "General Commands Manual" |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 29 | .SH Name |
| 30 | .PP |
| 31 | dc \- arbitrary\-precision reverse\-Polish notation calculator |
| 32 | .SH SYNOPSIS |
| 33 | .PP |
| 34 | \f[B]dc\f[] [\f[B]\-hiPvVx\f[]] [\f[B]\-\-version\f[]] |
| 35 | [\f[B]\-\-help\f[]] [\f[B]\-\-interactive\f[]] [\f[B]\-\-no\-prompt\f[]] |
| 36 | [\f[B]\-\-extended\-register\f[]] [\f[B]\-e\f[] \f[I]expr\f[]] |
| 37 | [\f[B]\-\-expression\f[]=\f[I]expr\f[]...] [\f[B]\-f\f[] |
| 38 | \f[I]file\f[]...] [\f[B]\-file\f[]=\f[I]file\f[]...] [\f[I]file\f[]...] |
| 39 | .SH DESCRIPTION |
| 40 | .PP |
| 41 | dc(1) is an arbitrary\-precision calculator. |
| 42 | It uses a stack (reverse Polish notation) to store numbers and results |
| 43 | of computations. |
| 44 | Arithmetic operations pop arguments off of the stack and push the |
| 45 | results. |
| 46 | .PP |
| 47 | If no files are given on the command\-line as extra arguments (i.e., not |
| 48 | as \f[B]\-f\f[] or \f[B]\-\-file\f[] arguments), then dc(1) reads from |
| 49 | \f[B]stdin\f[]. |
| 50 | Otherwise, those files are processed, and dc(1) will then exit. |
| 51 | .PP |
| 52 | This is different from the dc(1) on OpenBSD and possibly other dc(1) |
| 53 | implementations, where \f[B]\-e\f[] (\f[B]\-\-expression\f[]) and |
| 54 | \f[B]\-f\f[] (\f[B]\-\-file\f[]) arguments cause dc(1) to execute them |
| 55 | and exit. |
| 56 | The reason for this is that this dc(1) allows users to set arguments in |
| 57 | the environment variable \f[B]DC_ENV_ARGS\f[] (see the \f[B]ENVIRONMENT |
| 58 | VARIABLES\f[] section). |
| 59 | Any expressions given on the command\-line should be used to set up a |
| 60 | standard environment. |
| 61 | For example, if a user wants the \f[B]scale\f[] always set to |
| 62 | \f[B]10\f[], they can set \f[B]DC_ENV_ARGS\f[] to \f[B]\-e 10k\f[], and |
| 63 | this dc(1) will always start with a \f[B]scale\f[] of \f[B]10\f[]. |
| 64 | .PP |
| 65 | If users want to have dc(1) exit after processing all input from |
| 66 | \f[B]\-e\f[] and \f[B]\-f\f[] arguments (and their equivalents), then |
| 67 | they can just simply add \f[B]\-e q\f[] as the last command\-line |
| 68 | argument or define the environment variable \f[B]DC_EXPR_EXIT\f[]. |
| 69 | .SH OPTIONS |
| 70 | .PP |
| 71 | The following are the options that dc(1) accepts. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 72 | .TP |
| 73 | .B \f[B]\-h\f[], \f[B]\-\-help\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 74 | Prints a usage message and quits. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 75 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 76 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 77 | .TP |
| 78 | .B \f[B]\-v\f[], \f[B]\-V\f[], \f[B]\-\-version\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 79 | Print the version information (copyright header) and exit. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 80 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 81 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 82 | .TP |
| 83 | .B \f[B]\-i\f[], \f[B]\-\-interactive\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 84 | Forces interactive mode. |
| 85 | (See the \f[B]INTERACTIVE MODE\f[] section.) |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 86 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 87 | .PP |
| 88 | This is a \f[B]non\-portable extension\f[]. |
| 89 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 90 | .TP |
| 91 | .B \f[B]\-P\f[], \f[B]\-\-no\-prompt\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 92 | Disables the prompt in TTY mode. |
| 93 | (The prompt is only enabled in TTY mode. |
| 94 | See the \f[B]TTY MODE\f[] section) This is mostly for those users that |
| 95 | do not want a prompt or are not used to having them in dc(1). |
| 96 | Most of those users would want to put this option in |
| 97 | \f[B]DC_ENV_ARGS\f[]. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 98 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 99 | .PP |
| 100 | This is a \f[B]non\-portable extension\f[]. |
| 101 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 102 | .TP |
| 103 | .B \f[B]\-x\f[] \f[B]\-\-extended\-register\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 104 | Enables extended register mode. |
| 105 | See the \f[I]Extended Register Mode\f[] subsection of the |
| 106 | \f[B]REGISTERS\f[] section for more information. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 107 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 108 | .PP |
| 109 | This is a \f[B]non\-portable extension\f[]. |
| 110 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 111 | .TP |
| 112 | .B \f[B]\-e\f[] \f[I]expr\f[], \f[B]\-\-expression\f[]=\f[I]expr\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 113 | Evaluates \f[I]expr\f[]. |
| 114 | If multiple expressions are given, they are evaluated in order. |
| 115 | If files are given as well (see below), the expressions and files are |
| 116 | evaluated in the order given. |
| 117 | This means that if a file is given before an expression, the file is |
| 118 | read in and evaluated first. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 119 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 120 | .PP |
Gavin Howard | d459be0 | 2020-07-30 20:30:09 -0600 | [diff] [blame] | 121 | After processing all expressions and files, dc(1) will exit, unless |
| 122 | \f[B]\-\f[] (\f[B]stdin\f[]) was given as an argument at least once to |
| 123 | \f[B]\-f\f[] or \f[B]\-\-file\f[]. |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 124 | .PP |
| 125 | This is a \f[B]non\-portable extension\f[]. |
| 126 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 127 | .TP |
| 128 | .B \f[B]\-f\f[] \f[I]file\f[], \f[B]\-\-file\f[]=\f[I]file\f[] |
Gavin Howard | 03defed | 2020-07-03 12:52:22 -0600 | [diff] [blame] | 129 | Reads in \f[I]file\f[] and evaluates it, line by line, as though it were |
| 130 | read through \f[B]stdin\f[]. |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 131 | If expressions are also given (see above), the expressions are evaluated |
| 132 | in the order given. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 133 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 134 | .PP |
Gavin Howard | d459be0 | 2020-07-30 20:30:09 -0600 | [diff] [blame] | 135 | After processing all expressions and files, dc(1) will exit, unless |
| 136 | \f[B]\-\f[] (\f[B]stdin\f[]) was given as an argument at least once to |
| 137 | \f[B]\-f\f[] or \f[B]\-\-file\f[]. |
Gavin Howard | 90a5b2f | 2020-08-03 08:25:59 -0600 | [diff] [blame] | 138 | However, if any other \f[B]\-e\f[], \f[B]\-\-expression\f[], |
| 139 | \f[B]\-f\f[], or \f[B]\-\-file\f[] arguments are given after that, bc(1) |
| 140 | will give a fatal error and exit. |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 141 | .PP |
| 142 | This is a \f[B]non\-portable extension\f[]. |
| 143 | .RE |
| 144 | .PP |
| 145 | All long options are \f[B]non\-portable extensions\f[]. |
| 146 | .SH STDOUT |
| 147 | .PP |
| 148 | Any non\-error output is written to \f[B]stdout\f[]. |
| 149 | .PP |
| 150 | \f[B]Note\f[]: Unlike other dc(1) implementations, this dc(1) will issue |
| 151 | a fatal error (see the \f[B]EXIT STATUS\f[] section) if it cannot write |
| 152 | to \f[B]stdout\f[], so if \f[B]stdout\f[] is closed, as in \f[B]dc |
| 153 | >&\-\f[], it will quit with an error. |
| 154 | This is done so that dc(1) can report problems when \f[B]stdout\f[] is |
| 155 | redirected to a file. |
| 156 | .PP |
| 157 | If there are scripts that depend on the behavior of other dc(1) |
| 158 | implementations, it is recommended that those scripts be changed to |
| 159 | redirect \f[B]stdout\f[] to \f[B]/dev/null\f[]. |
| 160 | .SH STDERR |
| 161 | .PP |
| 162 | Any error output is written to \f[B]stderr\f[]. |
| 163 | .PP |
| 164 | \f[B]Note\f[]: Unlike other dc(1) implementations, this dc(1) will issue |
| 165 | a fatal error (see the \f[B]EXIT STATUS\f[] section) if it cannot write |
| 166 | to \f[B]stderr\f[], so if \f[B]stderr\f[] is closed, as in \f[B]dc |
| 167 | 2>&\-\f[], it will quit with an error. |
| 168 | This is done so that dc(1) can exit with an error code when |
| 169 | \f[B]stderr\f[] is redirected to a file. |
| 170 | .PP |
| 171 | If there are scripts that depend on the behavior of other dc(1) |
| 172 | implementations, it is recommended that those scripts be changed to |
| 173 | redirect \f[B]stderr\f[] to \f[B]/dev/null\f[]. |
| 174 | .SH SYNTAX |
| 175 | .PP |
| 176 | Each item in the input source code, either a number (see the |
| 177 | \f[B]NUMBERS\f[] section) or a command (see the \f[B]COMMANDS\f[] |
| 178 | section), is processed and executed, in order. |
| 179 | Input is processed immediately when entered. |
| 180 | .PP |
| 181 | \f[B]ibase\f[] is a register (see the \f[B]REGISTERS\f[] section) that |
| 182 | determines how to interpret constant numbers. |
| 183 | It is the "input" base, or the number base used for interpreting input |
| 184 | numbers. |
| 185 | \f[B]ibase\f[] is initially \f[B]10\f[]. |
| 186 | The max allowable value for \f[B]ibase\f[] is \f[B]16\f[]. |
| 187 | The min allowable value for \f[B]ibase\f[] is \f[B]2\f[]. |
| 188 | The max allowable value for \f[B]ibase\f[] can be queried in dc(1) |
| 189 | programs with the \f[B]T\f[] command. |
| 190 | .PP |
| 191 | \f[B]obase\f[] is a register (see the \f[B]REGISTERS\f[] section) that |
| 192 | determines how to output results. |
| 193 | It is the "output" base, or the number base used for outputting numbers. |
| 194 | \f[B]obase\f[] is initially \f[B]10\f[]. |
| 195 | The max allowable value for \f[B]obase\f[] is \f[B]DC_BASE_MAX\f[] and |
| 196 | can be queried with the \f[B]U\f[] command. |
| 197 | The min allowable value for \f[B]obase\f[] is \f[B]2\f[]. |
| 198 | Values are output in the specified base. |
| 199 | .PP |
| 200 | The \f[I]scale\f[] of an expression is the number of digits in the |
| 201 | result of the expression right of the decimal point, and \f[B]scale\f[] |
| 202 | is a register (see the \f[B]REGISTERS\f[] section) that sets the |
| 203 | precision of any operations (with exceptions). |
| 204 | \f[B]scale\f[] is initially \f[B]0\f[]. |
| 205 | \f[B]scale\f[] cannot be negative. |
| 206 | The max allowable value for \f[B]scale\f[] can be queried in dc(1) |
| 207 | programs with the \f[B]V\f[] command. |
| 208 | .SS Comments |
| 209 | .PP |
| 210 | Comments go from \f[B]#\f[] until, and not including, the next newline. |
| 211 | This is a \f[B]non\-portable extension\f[]. |
| 212 | .SH NUMBERS |
| 213 | .PP |
| 214 | Numbers are strings made up of digits, uppercase letters up to |
| 215 | \f[B]F\f[], and at most \f[B]1\f[] period for a radix. |
| 216 | Numbers can have up to \f[B]DC_NUM_MAX\f[] digits. |
| 217 | Uppercase letters are equal to \f[B]9\f[] + their position in the |
| 218 | alphabet (i.e., \f[B]A\f[] equals \f[B]10\f[], or \f[B]9+1\f[]). |
| 219 | If a digit or letter makes no sense with the current value of |
| 220 | \f[B]ibase\f[], they are set to the value of the highest valid digit in |
| 221 | \f[B]ibase\f[]. |
| 222 | .PP |
| 223 | Single\-character numbers (i.e., \f[B]A\f[] alone) take the value that |
| 224 | they would have if they were valid digits, regardless of the value of |
| 225 | \f[B]ibase\f[]. |
| 226 | This means that \f[B]A\f[] alone always equals decimal \f[B]10\f[] and |
| 227 | \f[B]F\f[] alone always equals decimal \f[B]15\f[]. |
| 228 | .SH COMMANDS |
| 229 | .PP |
| 230 | The valid commands are listed below. |
| 231 | .SS Printing |
| 232 | .PP |
| 233 | These commands are used for printing. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 234 | .TP |
| 235 | .B \f[B]p\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 236 | Prints the value on top of the stack, whether number or string, and |
| 237 | prints a newline after. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 238 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 239 | .PP |
| 240 | This does not alter the stack. |
| 241 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 242 | .TP |
| 243 | .B \f[B]n\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 244 | Prints the value on top of the stack, whether number or string, and pops |
| 245 | it off of the stack. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 246 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 247 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 248 | .TP |
| 249 | .B \f[B]P\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 250 | Pops a value off the stack. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 251 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 252 | .PP |
| 253 | If the value is a number, it is truncated and the absolute value of the |
| 254 | result is printed as though \f[B]obase\f[] is \f[B]UCHAR_MAX+1\f[] and |
| 255 | each digit is interpreted as an ASCII character, making it a byte |
| 256 | stream. |
| 257 | .PP |
| 258 | If the value is a string, it is printed without a trailing newline. |
| 259 | .PP |
| 260 | This is a \f[B]non\-portable extension\f[]. |
| 261 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 262 | .TP |
| 263 | .B \f[B]f\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 264 | Prints the entire contents of the stack, in order from newest to oldest, |
| 265 | without altering anything. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 266 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 267 | .PP |
| 268 | Users should use this command when they get lost. |
| 269 | .RE |
| 270 | .SS Arithmetic |
| 271 | .PP |
| 272 | These are the commands used for arithmetic. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 273 | .TP |
| 274 | .B \f[B]+\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 275 | The top two values are popped off the stack, added, and the result is |
| 276 | pushed onto the stack. |
| 277 | The \f[I]scale\f[] of the result is equal to the max \f[I]scale\f[] of |
| 278 | both operands. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 279 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 280 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 281 | .TP |
| 282 | .B \f[B]\-\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 283 | The top two values are popped off the stack, subtracted, and the result |
| 284 | is pushed onto the stack. |
| 285 | The \f[I]scale\f[] of the result is equal to the max \f[I]scale\f[] of |
| 286 | both operands. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 287 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 288 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 289 | .TP |
| 290 | .B \f[B]*\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 291 | The top two values are popped off the stack, multiplied, and the result |
| 292 | is pushed onto the stack. |
| 293 | If \f[B]a\f[] is the \f[I]scale\f[] of the first expression and |
| 294 | \f[B]b\f[] is the \f[I]scale\f[] of the second expression, the |
| 295 | \f[I]scale\f[] of the result is equal to |
| 296 | \f[B]min(a+b,max(scale,a,b))\f[] where \f[B]min()\f[] and \f[B]max()\f[] |
| 297 | return the obvious values. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 298 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 299 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 300 | .TP |
| 301 | .B \f[B]/\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 302 | The top two values are popped off the stack, divided, and the result is |
| 303 | pushed onto the stack. |
| 304 | The \f[I]scale\f[] of the result is equal to \f[B]scale\f[]. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 305 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 306 | .PP |
| 307 | The first value popped off of the stack must be non\-zero. |
| 308 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 309 | .TP |
| 310 | .B \f[B]%\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 311 | The top two values are popped off the stack, remaindered, and the result |
| 312 | is pushed onto the stack. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 313 | .RS |
| 314 | .PP |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 315 | Remaindering is equivalent to 1) Computing \f[B]a/b\f[] to current |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 316 | \f[B]scale\f[], and 2) Using the result of step 1 to calculate |
| 317 | \f[B]a\-(a/b)*b\f[] to \f[I]scale\f[] |
| 318 | \f[B]max(scale+scale(b),scale(a))\f[]. |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 319 | .PP |
| 320 | The first value popped off of the stack must be non\-zero. |
| 321 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 322 | .TP |
| 323 | .B \f[B]~\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 324 | The top two values are popped off the stack, divided and remaindered, |
| 325 | and the results (divided first, remainder second) are pushed onto the |
| 326 | stack. |
| 327 | This is equivalent to \f[B]x y / x y %\f[] except that \f[B]x\f[] and |
| 328 | \f[B]y\f[] are only evaluated once. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 329 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 330 | .PP |
| 331 | The first value popped off of the stack must be non\-zero. |
| 332 | .PP |
| 333 | This is a \f[B]non\-portable extension\f[]. |
| 334 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 335 | .TP |
| 336 | .B \f[B]^\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 337 | The top two values are popped off the stack, the second is raised to the |
| 338 | power of the first, and the result is pushed onto the stack. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 339 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 340 | .PP |
| 341 | The first value popped off of the stack must be an integer, and if that |
| 342 | value is negative, the second value popped off of the stack must be |
| 343 | non\-zero. |
| 344 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 345 | .TP |
| 346 | .B \f[B]v\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 347 | The top value is popped off the stack, its square root is computed, and |
| 348 | the result is pushed onto the stack. |
| 349 | The \f[I]scale\f[] of the result is equal to \f[B]scale\f[]. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 350 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 351 | .PP |
| 352 | The value popped off of the stack must be non\-negative. |
| 353 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 354 | .TP |
| 355 | .B \f[B]_\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 356 | If this command \f[I]immediately\f[] precedes a number (i.e., no spaces |
| 357 | or other commands), then that number is input as a negative number. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 358 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 359 | .PP |
| 360 | Otherwise, the top value on the stack is popped and copied, and the copy |
| 361 | is negated and pushed onto the stack. |
| 362 | This behavior without a number is a \f[B]non\-portable extension\f[]. |
| 363 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 364 | .TP |
| 365 | .B \f[B]b\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 366 | The top value is popped off the stack, and if it is zero, it is pushed |
| 367 | back onto the stack. |
| 368 | Otherwise, its absolute value is pushed onto the stack. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 369 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 370 | .PP |
| 371 | This is a \f[B]non\-portable extension\f[]. |
| 372 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 373 | .TP |
| 374 | .B \f[B]|\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 375 | The top three values are popped off the stack, a modular exponentiation |
| 376 | is computed, and the result is pushed onto the stack. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 377 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 378 | .PP |
| 379 | The first value popped is used as the reduction modulus and must be an |
| 380 | integer and non\-zero. |
| 381 | The second value popped is used as the exponent and must be an integer |
| 382 | and non\-negative. |
| 383 | The third value popped is the base and must be an integer. |
| 384 | .PP |
| 385 | This is a \f[B]non\-portable extension\f[]. |
| 386 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 387 | .TP |
| 388 | .B \f[B]G\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 389 | The top two values are popped off of the stack, they are compared, and a |
| 390 | \f[B]1\f[] is pushed if they are equal, or \f[B]0\f[] otherwise. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 391 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 392 | .PP |
| 393 | This is a \f[B]non\-portable extension\f[]. |
| 394 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 395 | .TP |
| 396 | .B \f[B]N\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 397 | The top value is popped off of the stack, and if it a \f[B]0\f[], a |
| 398 | \f[B]1\f[] is pushed; otherwise, a \f[B]0\f[] is pushed. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 399 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 400 | .PP |
| 401 | This is a \f[B]non\-portable extension\f[]. |
| 402 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 403 | .TP |
| 404 | .B \f[B](\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 405 | The top two values are popped off of the stack, they are compared, and a |
| 406 | \f[B]1\f[] is pushed if the first is less than the second, or \f[B]0\f[] |
| 407 | otherwise. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 408 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 409 | .PP |
| 410 | This is a \f[B]non\-portable extension\f[]. |
| 411 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 412 | .TP |
| 413 | .B \f[B]{\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 414 | The top two values are popped off of the stack, they are compared, and a |
| 415 | \f[B]1\f[] is pushed if the first is less than or equal to the second, |
| 416 | or \f[B]0\f[] otherwise. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 417 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 418 | .PP |
| 419 | This is a \f[B]non\-portable extension\f[]. |
| 420 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 421 | .TP |
| 422 | .B \f[B])\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 423 | The top two values are popped off of the stack, they are compared, and a |
| 424 | \f[B]1\f[] is pushed if the first is greater than the second, or |
| 425 | \f[B]0\f[] otherwise. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 426 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 427 | .PP |
| 428 | This is a \f[B]non\-portable extension\f[]. |
| 429 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 430 | .TP |
| 431 | .B \f[B]}\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 432 | The top two values are popped off of the stack, they are compared, and a |
| 433 | \f[B]1\f[] is pushed if the first is greater than or equal to the |
| 434 | second, or \f[B]0\f[] otherwise. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 435 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 436 | .PP |
| 437 | This is a \f[B]non\-portable extension\f[]. |
| 438 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 439 | .TP |
| 440 | .B \f[B]M\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 441 | The top two values are popped off of the stack. |
| 442 | If they are both non\-zero, a \f[B]1\f[] is pushed onto the stack. |
| 443 | If either of them is zero, or both of them are, then a \f[B]0\f[] is |
| 444 | pushed onto the stack. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 445 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 446 | .PP |
| 447 | This is like the \f[B]&&\f[] operator in bc(1), and it is \f[I]not\f[] a |
| 448 | short\-circuit operator. |
| 449 | .PP |
| 450 | This is a \f[B]non\-portable extension\f[]. |
| 451 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 452 | .TP |
| 453 | .B \f[B]m\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 454 | The top two values are popped off of the stack. |
| 455 | If at least one of them is non\-zero, a \f[B]1\f[] is pushed onto the |
| 456 | stack. |
| 457 | If both of them are zero, then a \f[B]0\f[] is pushed onto the stack. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 458 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 459 | .PP |
| 460 | This is like the \f[B]||\f[] operator in bc(1), and it is \f[I]not\f[] a |
| 461 | short\-circuit operator. |
| 462 | .PP |
| 463 | This is a \f[B]non\-portable extension\f[]. |
| 464 | .RE |
| 465 | .SS Stack Control |
| 466 | .PP |
| 467 | These commands control the stack. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 468 | .TP |
| 469 | .B \f[B]c\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 470 | Removes all items from ("clears") the stack. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 471 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 472 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 473 | .TP |
| 474 | .B \f[B]d\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 475 | Copies the item on top of the stack ("duplicates") and pushes the copy |
| 476 | onto the stack. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 477 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 478 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 479 | .TP |
| 480 | .B \f[B]r\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 481 | Swaps ("reverses") the two top items on the stack. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 482 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 483 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 484 | .TP |
| 485 | .B \f[B]R\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 486 | Pops ("removes") the top value from the stack. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 487 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 488 | .RE |
| 489 | .SS Register Control |
| 490 | .PP |
| 491 | These commands control registers (see the \f[B]REGISTERS\f[] section). |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 492 | .TP |
| 493 | .B \f[B]s\f[]\f[I]r\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 494 | Pops the value off the top of the stack and stores it into register |
| 495 | \f[I]r\f[]. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 496 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 497 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 498 | .TP |
| 499 | .B \f[B]l\f[]\f[I]r\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 500 | Copies the value in register \f[I]r\f[] and pushes it onto the stack. |
| 501 | This does not alter the contents of \f[I]r\f[]. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 502 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 503 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 504 | .TP |
| 505 | .B \f[B]S\f[]\f[I]r\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 506 | Pops the value off the top of the (main) stack and pushes it onto the |
| 507 | stack of register \f[I]r\f[]. |
| 508 | The previous value of the register becomes inaccessible. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 509 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 510 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 511 | .TP |
| 512 | .B \f[B]L\f[]\f[I]r\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 513 | Pops the value off the top of the stack for register \f[I]r\f[] and push |
| 514 | it onto the main stack. |
| 515 | The previous value in the stack for register \f[I]r\f[], if any, is now |
| 516 | accessible via the \f[B]l\f[]\f[I]r\f[] command. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 517 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 518 | .RE |
| 519 | .SS Parameters |
| 520 | .PP |
| 521 | These commands control the values of \f[B]ibase\f[], \f[B]obase\f[], and |
| 522 | \f[B]scale\f[]. |
| 523 | Also see the \f[B]SYNTAX\f[] section. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 524 | .TP |
| 525 | .B \f[B]i\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 526 | Pops the value off of the top of the stack and uses it to set |
| 527 | \f[B]ibase\f[], which must be between \f[B]2\f[] and \f[B]16\f[], |
| 528 | inclusive. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 529 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 530 | .PP |
| 531 | If the value on top of the stack has any \f[I]scale\f[], the |
| 532 | \f[I]scale\f[] is ignored. |
| 533 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 534 | .TP |
| 535 | .B \f[B]o\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 536 | Pops the value off of the top of the stack and uses it to set |
| 537 | \f[B]obase\f[], which must be between \f[B]2\f[] and |
| 538 | \f[B]DC_BASE_MAX\f[], inclusive (see the \f[B]LIMITS\f[] section). |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 539 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 540 | .PP |
| 541 | If the value on top of the stack has any \f[I]scale\f[], the |
| 542 | \f[I]scale\f[] is ignored. |
| 543 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 544 | .TP |
| 545 | .B \f[B]k\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 546 | Pops the value off of the top of the stack and uses it to set |
| 547 | \f[B]scale\f[], which must be non\-negative. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 548 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 549 | .PP |
| 550 | If the value on top of the stack has any \f[I]scale\f[], the |
| 551 | \f[I]scale\f[] is ignored. |
| 552 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 553 | .TP |
| 554 | .B \f[B]I\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 555 | Pushes the current value of \f[B]ibase\f[] onto the main stack. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 556 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 557 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 558 | .TP |
| 559 | .B \f[B]O\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 560 | Pushes the current value of \f[B]obase\f[] onto the main stack. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 561 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 562 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 563 | .TP |
| 564 | .B \f[B]K\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 565 | Pushes the current value of \f[B]scale\f[] onto the main stack. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 566 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 567 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 568 | .TP |
| 569 | .B \f[B]T\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 570 | Pushes the maximum allowable value of \f[B]ibase\f[] onto the main |
| 571 | stack. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 572 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 573 | .PP |
| 574 | This is a \f[B]non\-portable extension\f[]. |
| 575 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 576 | .TP |
| 577 | .B \f[B]U\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 578 | Pushes the maximum allowable value of \f[B]obase\f[] onto the main |
| 579 | stack. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 580 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 581 | .PP |
| 582 | This is a \f[B]non\-portable extension\f[]. |
| 583 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 584 | .TP |
| 585 | .B \f[B]V\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 586 | Pushes the maximum allowable value of \f[B]scale\f[] onto the main |
| 587 | stack. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 588 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 589 | .PP |
| 590 | This is a \f[B]non\-portable extension\f[]. |
| 591 | .RE |
| 592 | .SS Strings |
| 593 | .PP |
| 594 | The following commands control strings. |
| 595 | .PP |
| 596 | dc(1) can work with both numbers and strings, and registers (see the |
| 597 | \f[B]REGISTERS\f[] section) can hold both strings and numbers. |
| 598 | dc(1) always knows whether the contents of a register are a string or a |
| 599 | number. |
| 600 | .PP |
| 601 | While arithmetic operations have to have numbers, and will print an |
| 602 | error if given a string, other commands accept strings. |
| 603 | .PP |
| 604 | Strings can also be executed as macros. |
| 605 | For example, if the string \f[B][1pR]\f[] is executed as a macro, then |
| 606 | the code \f[B]1pR\f[] is executed, meaning that the \f[B]1\f[] will be |
| 607 | printed with a newline after and then popped from the stack. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 608 | .TP |
| 609 | .B \f[B][\f[]\f[I]characters\f[]\f[B]]\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 610 | Makes a string containing \f[I]characters\f[] and pushes it onto the |
| 611 | stack. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 612 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 613 | .PP |
| 614 | If there are brackets (\f[B][\f[] and \f[B]]\f[]) in the string, then |
| 615 | they must be balanced. |
| 616 | Unbalanced brackets can be escaped using a backslash (\f[B]\\\f[]) |
| 617 | character. |
| 618 | .PP |
| 619 | If there is a backslash character in the string, the character after it |
| 620 | (even another backslash) is put into the string verbatim, but the |
| 621 | (first) backslash is not. |
| 622 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 623 | .TP |
| 624 | .B \f[B]a\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 625 | The value on top of the stack is popped. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 626 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 627 | .PP |
| 628 | If it is a number, it is truncated and its absolute value is taken. |
| 629 | The result mod \f[B]UCHAR_MAX+1\f[] is calculated. |
| 630 | If that result is \f[B]0\f[], push an empty string; otherwise, push a |
| 631 | one\-character string where the character is the result of the mod |
| 632 | interpreted as an ASCII character. |
| 633 | .PP |
| 634 | If it is a string, then a new string is made. |
| 635 | If the original string is empty, the new string is empty. |
| 636 | If it is not, then the first character of the original string is used to |
| 637 | create the new string as a one\-character string. |
| 638 | The new string is then pushed onto the stack. |
| 639 | .PP |
| 640 | This is a \f[B]non\-portable extension\f[]. |
| 641 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 642 | .TP |
| 643 | .B \f[B]x\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 644 | Pops a value off of the top of the stack. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 645 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 646 | .PP |
| 647 | If it is a number, it is pushed back onto the stack. |
| 648 | .PP |
| 649 | If it is a string, it is executed as a macro. |
| 650 | .PP |
| 651 | This behavior is the norm whenever a macro is executed, whether by this |
| 652 | command or by the conditional execution commands below. |
| 653 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 654 | .TP |
| 655 | .B \f[B]>\f[]\f[I]r\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 656 | Pops two values off of the stack that must be numbers and compares them. |
| 657 | If the first value is greater than the second, then the contents of |
| 658 | register \f[I]r\f[] are executed. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 659 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 660 | .PP |
| 661 | For example, \f[B]0 1>a\f[] will execute the contents of register |
| 662 | \f[B]a\f[], and \f[B]1 0>a\f[] will not. |
| 663 | .PP |
| 664 | If either or both of the values are not numbers, dc(1) will raise an |
| 665 | error and reset (see the \f[B]RESET\f[] section). |
| 666 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 667 | .TP |
| 668 | .B \f[B]>\f[]\f[I]r\f[]\f[B]e\f[]\f[I]s\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 669 | Like the above, but will execute register \f[I]s\f[] if the comparison |
| 670 | fails. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 671 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 672 | .PP |
| 673 | If either or both of the values are not numbers, dc(1) will raise an |
| 674 | error and reset (see the \f[B]RESET\f[] section). |
| 675 | .PP |
| 676 | This is a \f[B]non\-portable extension\f[]. |
| 677 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 678 | .TP |
| 679 | .B \f[B]!>\f[]\f[I]r\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 680 | Pops two values off of the stack that must be numbers and compares them. |
| 681 | If the first value is not greater than the second (less than or equal |
| 682 | to), then the contents of register \f[I]r\f[] are executed. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 683 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 684 | .PP |
| 685 | If either or both of the values are not numbers, dc(1) will raise an |
| 686 | error and reset (see the \f[B]RESET\f[] section). |
| 687 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 688 | .TP |
| 689 | .B \f[B]!>\f[]\f[I]r\f[]\f[B]e\f[]\f[I]s\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 690 | Like the above, but will execute register \f[I]s\f[] if the comparison |
| 691 | fails. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 692 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 693 | .PP |
| 694 | If either or both of the values are not numbers, dc(1) will raise an |
| 695 | error and reset (see the \f[B]RESET\f[] section). |
| 696 | .PP |
| 697 | This is a \f[B]non\-portable extension\f[]. |
| 698 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 699 | .TP |
| 700 | .B \f[B]<\f[]\f[I]r\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 701 | Pops two values off of the stack that must be numbers and compares them. |
| 702 | If the first value is less than the second, then the contents of |
| 703 | register \f[I]r\f[] are executed. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 704 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 705 | .PP |
| 706 | If either or both of the values are not numbers, dc(1) will raise an |
| 707 | error and reset (see the \f[B]RESET\f[] section). |
| 708 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 709 | .TP |
| 710 | .B \f[B]<\f[]\f[I]r\f[]\f[B]e\f[]\f[I]s\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 711 | Like the above, but will execute register \f[I]s\f[] if the comparison |
| 712 | fails. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 713 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 714 | .PP |
| 715 | If either or both of the values are not numbers, dc(1) will raise an |
| 716 | error and reset (see the \f[B]RESET\f[] section). |
| 717 | .PP |
| 718 | This is a \f[B]non\-portable extension\f[]. |
| 719 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 720 | .TP |
| 721 | .B \f[B]!<\f[]\f[I]r\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 722 | Pops two values off of the stack that must be numbers and compares them. |
| 723 | If the first value is not less than the second (greater than or equal |
| 724 | to), then the contents of register \f[I]r\f[] are executed. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 725 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 726 | .PP |
| 727 | If either or both of the values are not numbers, dc(1) will raise an |
| 728 | error and reset (see the \f[B]RESET\f[] section). |
| 729 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 730 | .TP |
| 731 | .B \f[B]!<\f[]\f[I]r\f[]\f[B]e\f[]\f[I]s\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 732 | Like the above, but will execute register \f[I]s\f[] if the comparison |
| 733 | fails. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 734 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 735 | .PP |
| 736 | If either or both of the values are not numbers, dc(1) will raise an |
| 737 | error and reset (see the \f[B]RESET\f[] section). |
| 738 | .PP |
| 739 | This is a \f[B]non\-portable extension\f[]. |
| 740 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 741 | .TP |
| 742 | .B \f[B]=\f[]\f[I]r\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 743 | Pops two values off of the stack that must be numbers and compares them. |
| 744 | If the first value is equal to the second, then the contents of register |
| 745 | \f[I]r\f[] are executed. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 746 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 747 | .PP |
| 748 | If either or both of the values are not numbers, dc(1) will raise an |
| 749 | error and reset (see the \f[B]RESET\f[] section). |
| 750 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 751 | .TP |
| 752 | .B \f[B]=\f[]\f[I]r\f[]\f[B]e\f[]\f[I]s\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 753 | Like the above, but will execute register \f[I]s\f[] if the comparison |
| 754 | fails. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 755 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 756 | .PP |
| 757 | If either or both of the values are not numbers, dc(1) will raise an |
| 758 | error and reset (see the \f[B]RESET\f[] section). |
| 759 | .PP |
| 760 | This is a \f[B]non\-portable extension\f[]. |
| 761 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 762 | .TP |
| 763 | .B \f[B]!=\f[]\f[I]r\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 764 | Pops two values off of the stack that must be numbers and compares them. |
| 765 | If the first value is not equal to the second, then the contents of |
| 766 | register \f[I]r\f[] are executed. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 767 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 768 | .PP |
| 769 | If either or both of the values are not numbers, dc(1) will raise an |
| 770 | error and reset (see the \f[B]RESET\f[] section). |
| 771 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 772 | .TP |
| 773 | .B \f[B]!=\f[]\f[I]r\f[]\f[B]e\f[]\f[I]s\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 774 | Like the above, but will execute register \f[I]s\f[] if the comparison |
| 775 | fails. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 776 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 777 | .PP |
| 778 | If either or both of the values are not numbers, dc(1) will raise an |
| 779 | error and reset (see the \f[B]RESET\f[] section). |
| 780 | .PP |
| 781 | This is a \f[B]non\-portable extension\f[]. |
| 782 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 783 | .TP |
| 784 | .B \f[B]?\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 785 | Reads a line from the \f[B]stdin\f[] and executes it. |
| 786 | This is to allow macros to request input from users. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 787 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 788 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 789 | .TP |
| 790 | .B \f[B]q\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 791 | During execution of a macro, this exits the execution of that macro and |
| 792 | the execution of the macro that executed it. |
| 793 | If there are no macros, or only one macro executing, dc(1) exits. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 794 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 795 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 796 | .TP |
| 797 | .B \f[B]Q\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 798 | Pops a value from the stack which must be non\-negative and is used the |
| 799 | number of macro executions to pop off of the execution stack. |
| 800 | If the number of levels to pop is greater than the number of executing |
| 801 | macros, dc(1) exits. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 802 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 803 | .RE |
| 804 | .SS Status |
| 805 | .PP |
| 806 | These commands query status of the stack or its top value. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 807 | .TP |
| 808 | .B \f[B]Z\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 809 | Pops a value off of the stack. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 810 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 811 | .PP |
| 812 | If it is a number, calculates the number of significant decimal digits |
| 813 | it has and pushes the result. |
| 814 | .PP |
| 815 | If it is a string, pushes the number of characters the string has. |
| 816 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 817 | .TP |
| 818 | .B \f[B]X\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 819 | Pops a value off of the stack. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 820 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 821 | .PP |
| 822 | If it is a number, pushes the \f[I]scale\f[] of the value onto the |
| 823 | stack. |
| 824 | .PP |
| 825 | If it is a string, pushes \f[B]0\f[]. |
| 826 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 827 | .TP |
| 828 | .B \f[B]z\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 829 | Pushes the current stack depth (before execution of this command). |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 830 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 831 | .RE |
| 832 | .SS Arrays |
| 833 | .PP |
| 834 | These commands manipulate arrays. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 835 | .TP |
| 836 | .B \f[B]:\f[]\f[I]r\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 837 | Pops the top two values off of the stack. |
| 838 | The second value will be stored in the array \f[I]r\f[] (see the |
| 839 | \f[B]REGISTERS\f[] section), indexed by the first value. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 840 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 841 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 842 | .TP |
| 843 | .B \f[B];\f[]\f[I]r\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 844 | Pops the value on top of the stack and uses it as an index into the |
| 845 | array \f[I]r\f[]. |
| 846 | The selected value is then pushed onto the stack. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 847 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 848 | .RE |
| 849 | .SH REGISTERS |
| 850 | .PP |
| 851 | Registers are names that can store strings, numbers, and arrays. |
| 852 | (Number/string registers do not interfere with array registers.) |
| 853 | .PP |
| 854 | Each register is also its own stack, so the current register value is |
| 855 | the top of the stack for the register. |
| 856 | All registers, when first referenced, have one value (\f[B]0\f[]) in |
| 857 | their stack. |
| 858 | .PP |
| 859 | In non\-extended register mode, a register name is just the single |
| 860 | character that follows any command that needs a register name. |
| 861 | The only exception is a newline (\f[B]\[aq]\\n\[aq]\f[]); it is a parse |
| 862 | error for a newline to be used as a register name. |
| 863 | .SS Extended Register Mode |
| 864 | .PP |
| 865 | Unlike most other dc(1) implentations, this dc(1) provides nearly |
| 866 | unlimited amounts of registers, if extended register mode is enabled. |
| 867 | .PP |
| 868 | If extended register mode is enabled (\f[B]\-x\f[] or |
| 869 | \f[B]\-\-extended\-register\f[] command\-line arguments are given), then |
| 870 | normal single character registers are used \f[I]unless\f[] the character |
| 871 | immediately following a command that needs a register name is a space |
| 872 | (according to \f[B]isspace()\f[]) and not a newline |
| 873 | (\f[B]\[aq]\\n\[aq]\f[]). |
| 874 | .PP |
| 875 | In that case, the register name is found according to the regex |
| 876 | \f[B][a\-z][a\-z0\-9_]*\f[] (like bc(1) identifiers), and it is a parse |
| 877 | error if the next non\-space characters do not match that regex. |
| 878 | .SH RESET |
| 879 | .PP |
| 880 | When dc(1) encounters an error or a signal that it has a non\-default |
| 881 | handler for, it resets. |
| 882 | This means that several things happen. |
| 883 | .PP |
| 884 | First, any macros that are executing are stopped and popped off the |
| 885 | stack. |
| 886 | The behavior is not unlike that of exceptions in programming languages. |
| 887 | Then the execution point is set so that any code waiting to execute |
| 888 | (after all macros returned) is skipped. |
| 889 | .PP |
| 890 | Thus, when dc(1) resets, it skips any remaining code waiting to be |
| 891 | executed. |
| 892 | Then, if it is interactive mode, and the error was not a fatal error |
| 893 | (see the \f[B]EXIT STATUS\f[] section), it asks for more input; |
| 894 | otherwise, it exits with the appropriate return code. |
| 895 | .SH PERFORMANCE |
| 896 | .PP |
| 897 | Most dc(1) implementations use \f[B]char\f[] types to calculate the |
| 898 | value of \f[B]1\f[] decimal digit at a time, but that can be slow. |
| 899 | This dc(1) does something different. |
| 900 | .PP |
| 901 | It uses large integers to calculate more than \f[B]1\f[] decimal digit |
| 902 | at a time. |
| 903 | If built in a environment where \f[B]DC_LONG_BIT\f[] (see the |
| 904 | \f[B]LIMITS\f[] section) is \f[B]64\f[], then each integer has |
| 905 | \f[B]9\f[] decimal digits. |
| 906 | If built in an environment where \f[B]DC_LONG_BIT\f[] is \f[B]32\f[] |
| 907 | then each integer has \f[B]4\f[] decimal digits. |
| 908 | This value (the number of decimal digits per large integer) is called |
| 909 | \f[B]DC_BASE_DIGS\f[]. |
| 910 | .PP |
| 911 | In addition, this dc(1) uses an even larger integer for overflow |
| 912 | checking. |
| 913 | This integer type depends on the value of \f[B]DC_LONG_BIT\f[], but is |
| 914 | always at least twice as large as the integer type used to store digits. |
| 915 | .SH LIMITS |
| 916 | .PP |
Gavin Howard | e29e0f9 | 2020-06-28 12:46:58 -0600 | [diff] [blame] | 917 | The following are the limits on dc(1): |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 918 | .TP |
| 919 | .B \f[B]DC_LONG_BIT\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 920 | The number of bits in the \f[B]long\f[] type in the environment where |
| 921 | dc(1) was built. |
| 922 | This determines how many decimal digits can be stored in a single large |
| 923 | integer (see the \f[B]PERFORMANCE\f[] section). |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 924 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 925 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 926 | .TP |
| 927 | .B \f[B]DC_BASE_DIGS\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 928 | The number of decimal digits per large integer (see the |
| 929 | \f[B]PERFORMANCE\f[] section). |
| 930 | Depends on \f[B]DC_LONG_BIT\f[]. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 931 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 932 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 933 | .TP |
| 934 | .B \f[B]DC_BASE_POW\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 935 | The max decimal number that each large integer can store (see |
| 936 | \f[B]DC_BASE_DIGS\f[]) plus \f[B]1\f[]. |
| 937 | Depends on \f[B]DC_BASE_DIGS\f[]. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 938 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 939 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 940 | .TP |
| 941 | .B \f[B]DC_OVERFLOW_MAX\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 942 | The max number that the overflow type (see the \f[B]PERFORMANCE\f[] |
| 943 | section) can hold. |
| 944 | Depends on \f[B]DC_LONG_BIT\f[]. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 945 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 946 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 947 | .TP |
| 948 | .B \f[B]DC_BASE_MAX\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 949 | The maximum output base. |
| 950 | Set at \f[B]DC_BASE_POW\f[]. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 951 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 952 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 953 | .TP |
| 954 | .B \f[B]DC_DIM_MAX\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 955 | The maximum size of arrays. |
| 956 | Set at \f[B]SIZE_MAX\-1\f[]. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 957 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 958 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 959 | .TP |
| 960 | .B \f[B]DC_SCALE_MAX\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 961 | The maximum \f[B]scale\f[]. |
| 962 | Set at \f[B]DC_OVERFLOW_MAX\-1\f[]. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 963 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 964 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 965 | .TP |
| 966 | .B \f[B]DC_STRING_MAX\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 967 | The maximum length of strings. |
| 968 | Set at \f[B]DC_OVERFLOW_MAX\-1\f[]. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 969 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 970 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 971 | .TP |
| 972 | .B \f[B]DC_NAME_MAX\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 973 | The maximum length of identifiers. |
| 974 | Set at \f[B]DC_OVERFLOW_MAX\-1\f[]. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 975 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 976 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 977 | .TP |
| 978 | .B \f[B]DC_NUM_MAX\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 979 | The maximum length of a number (in decimal digits), which includes |
| 980 | digits after the decimal point. |
| 981 | Set at \f[B]DC_OVERFLOW_MAX\-1\f[]. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 982 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 983 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 984 | .TP |
| 985 | .B Exponent |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 986 | The maximum allowable exponent (positive or negative). |
| 987 | Set at \f[B]DC_OVERFLOW_MAX\f[]. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 988 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 989 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 990 | .TP |
| 991 | .B Number of vars |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 992 | The maximum number of vars/arrays. |
| 993 | Set at \f[B]SIZE_MAX\-1\f[]. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 994 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 995 | .RE |
| 996 | .PP |
| 997 | These limits are meant to be effectively non\-existent; the limits are |
| 998 | so large (at least on 64\-bit machines) that there should not be any |
| 999 | point at which they become a problem. |
| 1000 | In fact, memory should be exhausted before these limits should be hit. |
| 1001 | .SH ENVIRONMENT VARIABLES |
| 1002 | .PP |
Gavin Howard | e29e0f9 | 2020-06-28 12:46:58 -0600 | [diff] [blame] | 1003 | dc(1) recognizes the following environment variables: |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 1004 | .TP |
| 1005 | .B \f[B]DC_ENV_ARGS\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 1006 | This is another way to give command\-line arguments to dc(1). |
| 1007 | They should be in the same format as all other command\-line arguments. |
| 1008 | These are always processed first, so any files given in |
| 1009 | \f[B]DC_ENV_ARGS\f[] will be processed before arguments and files given |
| 1010 | on the command\-line. |
| 1011 | This gives the user the ability to set up "standard" options and files |
| 1012 | to be used at every invocation. |
| 1013 | The most useful thing for such files to contain would be useful |
| 1014 | functions that the user might want every time dc(1) runs. |
| 1015 | Another use would be to use the \f[B]\-e\f[] option to set |
| 1016 | \f[B]scale\f[] to a value other than \f[B]0\f[]. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 1017 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 1018 | .PP |
| 1019 | The code that parses \f[B]DC_ENV_ARGS\f[] will correctly handle quoted |
| 1020 | arguments, but it does not understand escape sequences. |
| 1021 | For example, the string \f[B]"/home/gavin/some dc file.dc"\f[] will be |
| 1022 | correctly parsed, but the string \f[B]"/home/gavin/some "dc" |
| 1023 | file.dc"\f[] will include the backslashes. |
| 1024 | .PP |
| 1025 | The quote parsing will handle either kind of quotes, \f[B]\[aq]\f[] or |
| 1026 | \f[B]"\f[]. |
| 1027 | Thus, if you have a file with any number of single quotes in the name, |
| 1028 | you can use double quotes as the outside quotes, as in \f[B]"some |
| 1029 | \[aq]bc\[aq] file.bc"\f[], and vice versa if you have a file with double |
| 1030 | quotes. |
| 1031 | However, handling a file with both kinds of quotes in |
| 1032 | \f[B]DC_ENV_ARGS\f[] is not supported due to the complexity of the |
| 1033 | parsing, though such files are still supported on the command\-line |
| 1034 | where the parsing is done by the shell. |
| 1035 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 1036 | .TP |
| 1037 | .B \f[B]DC_LINE_LENGTH\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 1038 | If this environment variable exists and contains an integer that is |
| 1039 | greater than \f[B]1\f[] and is less than \f[B]UINT16_MAX\f[] |
| 1040 | (\f[B]2^16\-1\f[]), dc(1) will output lines to that length, including |
| 1041 | the backslash newline combo. |
| 1042 | The default line length is \f[B]70\f[]. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 1043 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 1044 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 1045 | .TP |
| 1046 | .B \f[B]DC_EXPR_EXIT\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 1047 | If this variable exists (no matter the contents), dc(1) will exit |
| 1048 | immediately after executing expressions and files given by the |
| 1049 | \f[B]\-e\f[] and/or \f[B]\-f\f[] command\-line options (and any |
| 1050 | equivalents). |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 1051 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 1052 | .RE |
| 1053 | .SH EXIT STATUS |
| 1054 | .PP |
Gavin Howard | e29e0f9 | 2020-06-28 12:46:58 -0600 | [diff] [blame] | 1055 | dc(1) returns the following exit statuses: |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 1056 | .TP |
| 1057 | .B \f[B]0\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 1058 | No error. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 1059 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 1060 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 1061 | .TP |
| 1062 | .B \f[B]1\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 1063 | A math error occurred. |
| 1064 | This follows standard practice of using \f[B]1\f[] for expected errors, |
| 1065 | since math errors will happen in the process of normal execution. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 1066 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 1067 | .PP |
| 1068 | Math errors include divide by \f[B]0\f[], taking the square root of a |
| 1069 | negative number, attempting to convert a negative number to a hardware |
| 1070 | integer, overflow when converting a number to a hardware integer, and |
| 1071 | attempting to use a non\-integer where an integer is required. |
| 1072 | .PP |
| 1073 | Converting to a hardware integer happens for the second operand of the |
| 1074 | power (\f[B]^\f[]) operator. |
| 1075 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 1076 | .TP |
| 1077 | .B \f[B]2\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 1078 | A parse error occurred. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 1079 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 1080 | .PP |
| 1081 | Parse errors include unexpected \f[B]EOF\f[], using an invalid |
| 1082 | character, failing to find the end of a string or comment, and using a |
| 1083 | token where it is invalid. |
| 1084 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 1085 | .TP |
| 1086 | .B \f[B]3\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 1087 | A runtime error occurred. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 1088 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 1089 | .PP |
| 1090 | Runtime errors include assigning an invalid number to \f[B]ibase\f[], |
| 1091 | \f[B]obase\f[], or \f[B]scale\f[]; give a bad expression to a |
| 1092 | \f[B]read()\f[] call, calling \f[B]read()\f[] inside of a |
| 1093 | \f[B]read()\f[] call, type errors, and attempting an operation when the |
| 1094 | stack has too few elements. |
| 1095 | .RE |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 1096 | .TP |
| 1097 | .B \f[B]4\f[] |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 1098 | A fatal error occurred. |
Gavin Howard | 67207b3 | 2020-07-01 21:13:43 -0600 | [diff] [blame] | 1099 | .RS |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 1100 | .PP |
| 1101 | Fatal errors include memory allocation errors, I/O errors, failing to |
| 1102 | open files, attempting to use files that do not have only ASCII |
| 1103 | characters (dc(1) only accepts ASCII characters), attempting to open a |
| 1104 | directory as a file, and giving invalid command\-line options. |
| 1105 | .RE |
| 1106 | .PP |
| 1107 | The exit status \f[B]4\f[] is special; when a fatal error occurs, dc(1) |
| 1108 | always exits and returns \f[B]4\f[], no matter what mode dc(1) is in. |
| 1109 | .PP |
| 1110 | The other statuses will only be returned when dc(1) is not in |
| 1111 | interactive mode (see the \f[B]INTERACTIVE MODE\f[] section), since |
| 1112 | dc(1) resets its state (see the \f[B]RESET\f[] section) and accepts more |
| 1113 | input when one of those errors occurs in interactive mode. |
| 1114 | This is also the case when interactive mode is forced by the |
| 1115 | \f[B]\-i\f[] flag or \f[B]\-\-interactive\f[] option. |
| 1116 | .PP |
| 1117 | These exit statuses allow dc(1) to be used in shell scripting with error |
| 1118 | checking, and its normal behavior can be forced by using the |
| 1119 | \f[B]\-i\f[] flag or \f[B]\-\-interactive\f[] option. |
| 1120 | .SH INTERACTIVE MODE |
| 1121 | .PP |
| 1122 | Like bc(1), dc(1) has an interactive mode and a non\-interactive mode. |
| 1123 | Interactive mode is turned on automatically when both \f[B]stdin\f[] and |
| 1124 | \f[B]stdout\f[] are hooked to a terminal, but the \f[B]\-i\f[] flag and |
| 1125 | \f[B]\-\-interactive\f[] option can turn it on in other cases. |
| 1126 | .PP |
| 1127 | In interactive mode, dc(1) attempts to recover from errors (see the |
| 1128 | \f[B]RESET\f[] section), and in normal execution, flushes |
| 1129 | \f[B]stdout\f[] as soon as execution is done for the current input. |
| 1130 | .SH TTY MODE |
| 1131 | .PP |
| 1132 | If \f[B]stdin\f[], \f[B]stdout\f[], and \f[B]stderr\f[] are all |
| 1133 | connected to a TTY, dc(1) turns on "TTY mode." |
| 1134 | .PP |
| 1135 | TTY mode is required for history to be enabled (see the \f[B]COMMAND |
| 1136 | LINE HISTORY\f[] section). |
| 1137 | It is also required to enable special handling for \f[B]SIGINT\f[] |
| 1138 | signals. |
| 1139 | .PP |
| 1140 | The prompt is enabled in TTY mode. |
| 1141 | .PP |
| 1142 | TTY mode is different from interactive mode because interactive mode is |
| 1143 | required in the bc(1) |
| 1144 | specification (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html), |
| 1145 | and interactive mode requires only \f[B]stdin\f[] and \f[B]stdout\f[] to |
| 1146 | be connected to a terminal. |
| 1147 | .SH SIGNAL HANDLING |
| 1148 | .PP |
| 1149 | Sending a \f[B]SIGINT\f[] will cause dc(1) to stop execution of the |
| 1150 | current input. |
| 1151 | If dc(1) is in TTY mode (see the \f[B]TTY MODE\f[] section), it will |
| 1152 | reset (see the \f[B]RESET\f[] section). |
| 1153 | Otherwise, it will clean up and exit. |
| 1154 | .PP |
| 1155 | Note that "current input" can mean one of two things. |
| 1156 | If dc(1) is processing input from \f[B]stdin\f[] in TTY mode, it will |
| 1157 | ask for more input. |
| 1158 | If dc(1) is processing input from a file in TTY mode, it will stop |
| 1159 | processing the file and start processing the next file, if one exists, |
| 1160 | or ask for input from \f[B]stdin\f[] if no other file exists. |
| 1161 | .PP |
| 1162 | This means that if a \f[B]SIGINT\f[] is sent to dc(1) as it is executing |
| 1163 | a file, it can seem as though dc(1) did not respond to the signal since |
| 1164 | it will immediately start executing the next file. |
| 1165 | This is by design; most files that users execute when interacting with |
| 1166 | dc(1) have function definitions, which are quick to parse. |
| 1167 | If a file takes a long time to execute, there may be a bug in that file. |
| 1168 | The rest of the files could still be executed without problem, allowing |
| 1169 | the user to continue. |
| 1170 | .PP |
| 1171 | \f[B]SIGTERM\f[] and \f[B]SIGQUIT\f[] cause dc(1) to clean up and exit, |
| 1172 | and it uses the default handler for all other signals. |
| 1173 | The one exception is \f[B]SIGHUP\f[]; in that case, when dc(1) is in TTY |
| 1174 | mode, a \f[B]SIGHUP\f[] will cause dc(1) to clean up and exit. |
| 1175 | .SH COMMAND LINE HISTORY |
| 1176 | .PP |
| 1177 | dc(1) supports interactive command\-line editing. |
| 1178 | If dc(1) is in TTY mode (see the \f[B]TTY MODE\f[] section), history is |
| 1179 | enabled. |
| 1180 | Previous lines can be recalled and edited with the arrow keys. |
| 1181 | .PP |
| 1182 | \f[B]Note\f[]: tabs are converted to 8 spaces. |
| 1183 | .SH SEE ALSO |
| 1184 | .PP |
Gavin Howard | e29e0f9 | 2020-06-28 12:46:58 -0600 | [diff] [blame] | 1185 | bc(1) |
Gavin Howard | 5590565 | 2020-06-29 21:44:49 -0600 | [diff] [blame] | 1186 | .SH STANDARDS |
| 1187 | .PP |
| 1188 | The dc(1) utility operators are compliant with the operators in the |
| 1189 | bc(1) IEEE Std 1003.1\-2017 |
| 1190 | (“POSIX.1\-2017”) (https://pubs.opengroup.org/onlinepubs/9699919799/utilities/bc.html) |
| 1191 | specification. |
| 1192 | .SH BUGS |
| 1193 | .PP |
| 1194 | None are known. |
| 1195 | Report bugs at https://git.yzena.com/gavin/bc. |
| 1196 | .SH AUTHOR |
| 1197 | .PP |
| 1198 | Gavin D. |
| 1199 | Howard <yzena.tech@gmail.com> and contributors. |