aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/edc_src.1645
1 files changed, 645 insertions, 0 deletions
diff --git a/doc/edc_src.1 b/doc/edc_src.1
new file mode 100644
index 0000000..4c33d41
--- /dev/null
+++ b/doc/edc_src.1
@@ -0,0 +1,645 @@
+.\" Copyright (C), 2023 Duncan Wilkie
+.\" You may distribute this file under the terms of the GNU Free
+.\" Documentation License.
+.TH edc 1 2023-11-15
+.ds edc \fIedc\fP
+.ds Edc \fIedc\fP
+.SH NAME
+edc \- the exact desk calculator
+.SH SYNOPSIS
+edc [-?V] [-e scriptexpression] [-f script-file]
+ [--expression=scriptexpression] [--file=script-file] [--help]
+ [--usage] [--version] [file ...]
+.SH DESCRIPTION
+.PP
+.B Edc
+is a
+.MR dc 1
+style RPN calculator program, distinct in its use of
+exact real arithmetic.
+It uses IC-Reals, a set of C routines developed at Imperial College
+that implement a system for performing exact (not arbitrary-precision)
+computations with real numbers (Edalat and Heckmann 2002).
+The distinction is subtle, but has significant consequences:
+try computing the 100th term of the sequence
+
+.EQ
+a(0) = 11 / 2,
+.EN
+
+.EQ
+a(1) = 61 / 11,
+.EN
+
+.EQ
+ a(n) = 111 ^-^ (1130 ^-^ 3000 ^/^ a(n ^-^ 2)) ^/^ a(n ^-^ 1)
+.EN
+
+in Emacs calc, at precisions 5, 10, 30, 60, 100, 110, 120, 130, and 140.
+
+.EX
+;; Evaluate, and then: M-x calc RET p 5 RET 'hell(100) RET
+;; etc.
+
+(defmath hell (n)
+ (let ((nm2 (/ :"11.0" :"2.0"))
+ (nm1 (/ :"61.0" :"11.0"))
+ (old 0))
+ (for ((i 3 n))
+ (setq old nm1)
+ (setq nm1 (- 111
+ (/ (- 1130
+ (/ 3000
+ nm2))
+ nm1)))
+ (setq nm2 old))
+ nm1))
+.EE
+
+You get the results
+.TS
+box center;
+Cb Cb
+L C.
+Precision Estimate
+5 100.
+10 100.
+30 100.
+60 99.(9^57)7
+100 100.0000000...
+120 100.(0^31)3...
+130 5.(9^7)83...
+140 5.(9^7)85...
+.TE
+
+This sequence provably converges to 6.
+And that should be scary; who would compute this to 130 digits of precision
+if the value for 60 were so near to a round number?
+Who would trust the result for 130 digits;
+how could you tell it was more correct?
+Maybe what caused this problem is worse with more digits.
+Not only do you need to worry about the truncation error of the sequence,
+but also the accumulated rounding error!
+.PP
+Exact real arithmetic avoids this problem via lazy precision.
+Numbers are viewed as streams of (signed) digits
+encoding chains of descending subsets, and when a computation returns,
+the result truly must be within the indicated subset.
+.PP
+The
+.B edc
+incantation
+
+.EX
+[0:1 0:2 111 1130 3000 0;2 / - 0;1 / - 0;1 r]0:s
+11/2 61/11 0;sx0;sx0;sx0;sx0;sx
+.EE
+
+gives approximately 5.75; computing further terms yields a sequence
+that seems to monotonically approach 6.
+If you repeat 0;sx 100 times (to compute the 100th term),
+the result is 6 to within 2 in 10^8.
+.PP
+.B Edc
+has very similar command syntax to its predecessor.
+Some exceptions are:
+.TP
+.PP
+Comparisons are ordered like a reasonable person would expect,
+i.e. '1 2 <' corresponds to infix '1 < 2', just as '1 2 -'
+corresponds to '1 - 2'.
+.TP
+.PP
+There is no 'X' command; 'Z', in addition to producing
+the number of digits of an integer and length of a string,
+simply produces the number of currently-computed digits
+of a real value.
+.TP
+.PP
+There is no '!' command.
+Enjoy the absence of shell-injection.
+.TP
+.PP
+There are no decimal points, save in output:
+real-valued input is provided through rational numbers.
+Examples: '1/2', '2/1', '123412341234/987098709870987'.
+Non-examples: '1 / 2', '12.7', '1/'.
+Irrational and transcendentals must be accessed by commands.
+This choice emphasizes the computable, non-floating-point nature
+of the tool. (And, the real reason, was easier to implement.)
+.TP
+.PP
+Comparisons take an extra integer argument, last on the stack: a precision.
+They execute their macros only if the comparison is provably true
+for the passed values computed to within the given precision.
+As a special case, numbers are considered equal
+if they are not provably not equal.
+(Comparisons of integers are, by contrast, computable;
+they have their usual meaning, and the precision is ignored.)
+.TP
+.PP
+The 'P' command instead pushes pi onto the stack.
+.TP
+.PP
+The 'n' command is renamed to 'm'.
+.TP
+.PP
+There are additional commands for common constants and special functions.
+.PD
+.SH OPTIONS
+.B Edc
+may be invoked with the following command-line options:
+.TP
+.B -V
+.TP
+.B --version
+Print out the version of
+.B edc
+that is being run and a copyright notice,
+then exit.
+.TP
+.B -h
+.TP
+.B --help
+Print a usage message briefly summarizing these command-line options
+and the bug-reporting address,
+then exit.
+.TP
+.B -e \fIscript\fP
+.TP
+.BI --expression= script
+Add the commands in
+.I script
+to the set of commands to be run while processing the input.
+.TP
+.B -f \fIscript-file\fP
+.TP
+.BI --file= script-file
+Add the commands contained in the file
+.I script-file
+to the set of commands to be run while processing the input.
+.PP
+If any command-line parameters remain after processing the above,
+these parameters are interpreted as the names of input files
+to be processed.
+A file name of
+.B -
+refers to the standard input stream.
+The standard input will be processed if no script files
+or expressions are specified.
+.PD
+.SH Printing Commands
+.TP
+.B p
+Prints the value on the top of the stack,
+without altering the stack.
+A newline is printed after the value.
+.TP
+.B n
+Prints the value on the top of the stack, popping it off,
+and does not print a newline after.
+.TP
+.B f
+Prints the entire contents of the stack
+.ig
+and the contents of all of the registers,
+..
+without altering anything.
+This is a good command to use if you are lost or want
+to figure out what the effect of some command has been.
+.PD
+.SH Arithmetic
+.TP
+.B +
+Pops two values off the stack, adds them,
+and pushes the result.
+.TP
+.B -
+Pops two values,
+subtracts the first one popped from the second one popped,
+and pushes the result.
+.TP
+.B *
+Pops two values, multiplies them, and pushes the result.
+.TP
+.B /
+Pops two values,
+divides the second one popped from the first one popped,
+and pushes the result.
+Performs a C-style integer division if both arguments
+are integers.
+.TP
+.B %
+Pops two values,
+computes the remainder of the division that the
+.B /
+command would do,
+and pushes that.
+The value computed is the same as that computed by
+the sequence \fBSd dld/ Ld*-\fP by definition.
+.TP
+.B ~
+Pops two values,
+divides the second one popped from the first one popped.
+The quotient is pushed first, and the remainder is pushed next.
+The value is the same as \fBSdSn lnld/ LnLd%\fP
+by definition.
+.TP
+.B ^
+Pops two values and exponentiates,
+using the first value popped as the exponent
+and the second popped as the base.
+.TP
+.B |
+Pops three values and computes a modular exponentiation.
+The first value popped is used as the reduction modulus;
+this value must be a non-zero number,
+and should be an integer.
+The second popped is used as the exponent;
+this value must be a non-negative number,
+and any fractional part of this exponent will be ignored.
+The third value popped is the base which gets exponentiated,
+which should be an integer.
+For small integers this is like the sequence \fBSm^Lm%\fP,
+but, unlike \fB^\fP, this command will work with arbitrarily large exponents.
+.TP
+.B v
+Pops one value, computes its square root, and pushes that.
+.PP
+Real values are forced on printing; the
+.B k
+command sets the number of digits after the decimal point to print.
+The default display precision value is 10.
+.SH
+Stack Control
+.TP
+.B c
+Clears the stack, rendering it empty.
+.TP
+.B d
+Duplicates the value on the top of the stack,
+pushing another copy of it.
+Thus, ``4d*p'' computes 4 squared and prints it.
+.TP
+.B r
+Reverses the order of (swaps) the top two values on the stack.
+.TP
+.B R
+Pops the top-of-stack as an integer
+.IR n .
+Cyclically rotates the top
+.I n
+items on the updated stack.
+If
+.I n
+is positive, then the rotation direction will make the topmost
+element the second-from top;
+if
+.I n
+is negative, then the rotation will make the topmost element the
+.IR n -th
+element from the top.
+If the stack depth is less than
+.IR n ,
+then the entire stack is rotated (in the appropriate direction),
+without any error being reported.
+.SH
+Registers
+.PP
+.B Edc
+provides 256 memory registers,
+each named by a single character.
+You can store a number or a string in a register and retrieve it later.
+.TP
+.BI s r
+Pop the value off the top of the stack and store
+it into register
+.IR r .
+.TP
+.BI l r
+Copy the value in register
+.I r
+and push it onto the stack.
+The value 0 is retrieved if the register is uninitialized.
+This does not alter the contents of
+.IR r .
+.PP
+Each register also contains its own stack.
+The current register value is the top of the register's stack.
+.TP
+.BI S r
+Pop the value off the top of the (main) stack and
+push it onto the stack of register
+.IR r .
+The previous value of the register becomes inaccessible.
+.TP
+.BI L r
+Pop the value off the top of register
+.IR r 's
+stack and push it onto the main stack.
+The previous value
+in register
+.IR r 's
+stack, if any,
+is now accessible via the
+.BI l r
+command.
+.SH
+Parameters
+.PP
+.B Edc
+has three parameters that control its operation:
+the display precision, the input radix, and the output radix.
+The display precision specifies the number
+of real digits after the decimal point to print.
+The input radix controls the interpretation of numbers typed in;
+all numbers typed in use this radix.
+The output radix is used for printing integers
+(all reals are output in decimal, as IC-Reals doesn't expose
+anything that makes that easy).
+Bases greater than 10 use as extra digits capital letters A through F;
+just as with
+.MR dc 1
+the bases 2 through 16 are supported.
+.PP
+The input and output radices are separate parameters;
+you can make them unequal,
+which can be useful or confusing.
+Each must be between 2 and 16 inclusive.
+The output must be nonnegative.
+.TP
+.B i
+Pops the value off the top of the stack
+and uses it to set the input radix.
+.TP
+.B o
+Pops the value off the top of the stack
+and uses it to set the output radix.
+.TP
+.B k
+Pops the value off the top of the stack
+and uses it to set the precision.
+.TP
+.B I
+Pushes the current input radix on the stack.
+.TP
+.B O
+Pushes the current output radix on the stack.
+.TP
+.B K
+Pushes the current precision on the stack.
+.SH
+Strings
+.PP
+.B Edc
+has a limited ability to operate on strings
+as well as on numbers;
+the only things you can do with strings are
+print them and execute them as macros
+(which means that the contents of the string are processed as
+.B edc
+commands).
+All registers and the stack can hold strings,
+and
+.B edc
+always knows whether any given object is a string or a number.
+Some commands such as arithmetic operations demand numbers
+as arguments and print errors if given strings.
+Other commands can accept either a number or a string;
+for example, the
+.B p
+command can accept either and prints the object
+according to its type.
+.TP
+.BI [ characters ]
+Makes a string containing
+.I characters
+(contained between balanced
+.B [
+and
+.B ]
+characters),
+and pushes it on the stack.
+For example,
+.B [foo]P
+prints the characters
+.B foo
+(with no newline).
+.TP
+.B a
+The top-of-stack is popped.
+If it was an integer, then the low-order byte of this number
+is converted into a string and pushed onto the stack.
+If it was a string,
+the first character of that string is pushed back.
+If it is real, an error is signalled, as reals have
+infinite digits.
+.TP
+.B x
+Pops a value off the stack and executes it as a macro.
+Normally it should be a string;
+if it is a number,
+it is simply pushed back onto the stack.
+For example,
+.B [1p]x
+executes the macro
+.B 1p
+which pushes
+.B 1
+on the stack and prints
+.B 1
+on a separate line.
+.PP
+Macros are most often stored in registers;
+.B [1p]sa
+stores a macro to print
+.B 1
+into register
+.BR a ,
+and
+.B lax
+invokes this macro.
+.TP
+.BI > r
+Pops three values off the stack and compares the lowest two,
+assuming they are numbers, within the precision indicated by the topmost.
+The contents of register
+.I r
+are executed as a macro if the lowest is provably greater
+within the precision.
+The precision is ignored if both are integers.
+Thus,
+.B 2 1 0>a
+will invoke register
+.BR a 's
+contents and
+.B 1 2 0>a
+will not.
+.TP
+.BI !> r
+Similar, but invokes the macro if the lowest is provably not greater
+(less than or equal to) the second lowest.
+.TP
+.BI < r
+Similar, but invokes the macro if the lowest is less
+than the second lowest.
+.TP
+.BI !< r
+Similar, but invokes the macro if the lowest is provably not less
+(greater than or equal to) the second lowest.
+.TP
+.BI = r
+Invokes invokes the macro if the two numbers popped
+are not provably not equal,
+i.e. if the intervals computed at the specified precision overlap.
+.TP
+.BI != r
+Similar, but invokes the macro if the two numbers popped are
+provably not equal, i.e. if the intervals computed
+at the specified precision do not overlap.
+.TP
+.B ?
+Reads a line from the terminal and executes it.
+This command allows a macro to request input from the user.
+.TP
+.B q
+exits from a macro and also from the macro which invoked it.
+If called from the top level,
+or from a macro which was called directly from the top level,
+the
+.B q
+command will cause
+.B edc
+to exit.
+.TP
+.B Q
+Pops a value off the stack and uses it as a count
+of levels of macro execution to be exited.
+Thus,
+.B 3Q
+exits three levels.
+The
+.B Q
+command will never cause
+.B edc
+to exit.
+.SH
+Status Inquiry
+.TP
+.B Z
+Pops a value off the stack,
+calculates the number of decimal digits it has
+(or number of characters, if it is a string)
+and pushes that number.
+The digit count for a number does
+.I not
+include any leading zeros,
+even if those appear to the right of the radix point.
+If the value is a real number,
+it pushes the number of digits computed so far.
+.TP
+.B z
+Pushes the current stack depth:
+the number of objects on the stack before the execution of the
+.B z
+command.
+.SH Edc Extensions
+.TP
+.B N
+Pops a value off the stack,
+pushing its negation.
+.TP
+.B M
+Pops a value off the stack,
+pushing its magnitude (absolute value).
+.TP
+.B e
+Pops a value off the stack,
+and pushes the exponential function of the result.
+.TP
+.B g
+Pops a value off the stack,
+and pushes the natural logarithm of the result.
+.TP
+.B t
+Pops a value off the stack.
+Interprets the next character (s(in), c(os),
+t(an), S(ec), C(sc), (co)T)
+as a trigonometric function,
+pushing its result.
+.TP
+.B h
+Pops a value off the stack.
+Interprets the next character (s(inh), c(osh),
+t(anh), S(ech), C(sch), (co)T(h))
+as a hyperbolic trigonometric function,
+pushing its result.
+.TP
+.B n
+Pops a value off the stack.
+Interprets the next two characters
+as a trigonometric or hyperbolic trigonometric function,
+pushing the result of the corresponding iNverse.
+.TP
+.B P
+Pushes pi.
+.TP
+.B X
+Pushes Euler's eXponential constant.
+.SH
+Miscellaneous
+.TP
+.B #
+Will interpret the rest of the line as a comment.
+.TP
+.BI : r
+Will pop the top two values off of the stack.
+The old second-to-top value will be stored in the array
+.IR r ,
+indexed by the old top-of-stack value.
+.TP
+.BI ; r
+Pops the top-of-stack and uses it as an index into
+the array
+.IR r .
+The selected value is then pushed onto the stack.
+.P
+Note that each stacked instance of a register has its own
+array associated with it.
+Thus \fB1 0:a 0Sa 2 0:a La 0;ap\fP will print 1,
+because the 2 was stored in an instance of 0:a that
+was later popped.
+.SH Errors
+Quoting the libc manual, ``the experienced user will know
+what is wrong.''
+For the inexperienced:
+.TP
+.BI ? c
+Unrecognized command
+.IR c .
+.TP
+.B !-
+Stack underflow.
+.TP
+.BI ! r -
+Register
+.IR r
+stack underflow.
+.TP
+.B !+
+Stack overflow.
+.TP
+.BI ! r +
+Register
+.IR r
+stack overflow.
+.TP
+.B !?
+Unsupported value.
+
+Errors that cause the program to prematurely exit are bugs.
+.SH BUGS
+Email bug reports to
+.B duncannwilkie@gmail.com
+.SH AUTHOR
+Duncan Wilkie <duncannwilkie@gmail.com>