From 11da511c784eca003deb90c23570f0873954e0de Mon Sep 17 00:00:00 2001 From: Duncan Wilkie Date: Sat, 18 Nov 2023 06:11:09 -0600 Subject: Initial commit. --- doc/edc_src.1 | 645 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 645 insertions(+) create mode 100644 doc/edc_src.1 (limited to 'doc/edc_src.1') 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 -- cgit v1.2.3