[ don't let the size and number of features fool you -- this is a great
calculator for those of us who can never remember the obscure and "help"-
less syntax of bc and dc. it happens that you could use this package to
verify the correctness of your floating-point implementation, but even
if you're just trying to calculate disk geometries or sales tax, this is
very probably the best and easiest-to-use tool for the job.
it builds and installs and runs perfectly on my ultrix system.
--vix ]
Calc is an arbitrary precision calculator. It handles large integers,
fractions, real numbers (approximated using fractions), complex numbers,
strings, and matrices. The size of numbers and the precision of real
calculations is limited only by the available memory and the run time.
Calc can be used interactively by the user to evaluate expressions.
It can also be programmed using a language much like C. This allows
the user to define complicated functions which can then also be used
interactively.
There are many built-in functions (e.g., gcd, comb, sin, exp, det).
Many of these functions are useful in number theory.
In addition to the built-in types, calc can also handle new types of
objects whose representation and operations are defined by the user
(e.g., quadratic surds, quaternions, modular arithmetic).
Calc is written in C so as to be portable. No assembly language is
used, and machine dependencies are few. When building calc, the major
dependency is knowing whether your machine is big or little endian.
Calc has been successfully built on several different types of machines.
The code for the arbitrary precision routines is independent of the code
for the rest of the calculator. These routines can be called by your own
C programs to manipulate either large integers, or large fractions.
These sources are also available by anonymous ftp from ftp.uu.net in the
directory pub/calc. Calc will also be distributed as part of 4.4BSD, and
has been given to the GNU project.
Enjoy!
David I. Bell
db...@pdact.pd.necisa.oz.au
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 1 (of 21)."
# Contents: README func.h help help/Makefile help/credit
# help/environment help/expression help/header help/help
# help/history help/interrupt help/intro help/list help/operator
# help/sums help/todo help/usage help/variable label.h lib
# lib/Makefile lib/bernoulli.cal lib/bigprime.cal lib/deg.cal
# lib/mersenne.cal lib/nextprim.cal lib/pell.cal lib/pi.cal
# lib/pollard.cal lib/psqrt.cal lib/solve.cal lib/sumsq.cal
# lib/unitfrac.cal lib/varargs.cal lint.sed stdarg.h string.h
# symbol.h version.c
# Wrapped by dbell@elm on Tue Feb 25 15:20:52 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(1357 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
X
X# Copyright (c) 1992 David I. Bell
X# Permission is granted to use, distribute, or modify this source,
X# provided that this copyright notice remains intact.
X#
X# Arbitrary precision calculator.
X
XI am allowing this calculator to be freely distributed for personal uses.
XLike all multi-precision programs, you should not depend absolutely on
Xits results, since bugs in such programs can be insidious and only rarely
Xshow up.
X
X-dbell-
X
Xp.s. By Landon Curt Noll
X
XTo build calc:
X
X 1) Look at the makefile, and adjust it to suit your needs.
X
X 2) build some calc documentation:
X
X (cd help; make full) <- after this, read the file help/full
X
X 3) build calc:
X
X make
X
X 4) test calc:
X
X After you have built calc, you can test it by running calc and
X giving calc the following input:
X
X read lib/regress <- error messages should be printed
X read lib/lucas
X read lib/lucas_chk
X lucas_chk(200) <- should produce no error messages
X exit
X
XIf you find bugs, or better yet have bug fixes; or if you have suggested
Xchanges, or better yet have patches, send them to both myself and DBell:
X
X cho...@toad.com {uunet,pyramid,sun}!hoptoad!chongo
X db...@pdact.pd.necisa.oz.au {uunet,pyramid}!pdact.pd.necisa.oz.au!dbell
X
XThe file doc/todo section points out some needs for calc. Suggestions
Xon other enhancements, and help in doing these are welcome.
END_OF_FILE
if test 1357 -ne `wc -c <'README'`; then
echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'func.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'func.h'\"
else
echo shar: Extracting \"'func.h'\" \(2162 characters\)
sed "s/^X//" >'func.h' <<'END_OF_FILE'
X/*
X * Copyright (c) 1992 David I. Bell
X * Permission is granted to use, distribute, or modify this source,
X * provided that this copyright notice remains intact.
X */
X
X
X/*
X * Structure of a function.
X * The f_opcodes array is actually of variable size.
X */
Xtypedef struct func FUNC;
Xstruct func {
X FUNC *f_next; /* next function in list */
X unsigned long f_opcodecount; /* size of opcode array */
X unsigned int f_localcount; /* number of local variables */
X unsigned int f_paramcount; /* max number of parameters */
X char *f_name; /* function name */
X VALUE f_savedvalue; /* saved value of last expression */
X long f_opcodes[1]; /* array of opcodes (variable length) */
X};
X
X
X/*
X * Amount of space needed to allocate a function of n opcodes.
X */
X#define funcsize(n) (sizeof(FUNC) + (n) * sizeof(long))
X
X
X/*
X * Size of a character pointer rounded up to a number of opcodes.
X */
X#define PTR_SIZE ((sizeof(char *) + sizeof(long) - 1) / sizeof(long))
X
X
Xextern FUNC *curfunc; /* current function being compiled */
Xextern FUNC *findfunc(); /* return function given index */
Xextern char *namefunc(); /* return function name given index */
Xextern BOOL evaluate(); /* evaluate a line */
Xextern long adduserfunc();
Xextern void beginfunc(); /* initialize a function for definition */
Xextern int builtinopcode(); /* return the opcode for a built-in function */
Xextern void addop(); /* add an opcode to the current function */
Xextern void endfunc(); /* commit the just defined function for use */
Xextern void addopindex(); /* add an opcode & index to the current func */
Xextern void addoplabel(); /* add jump-type opcode + label to the func */
Xextern void addopptr(); /* add an opcode + char ptr to the func */
Xextern void showbuiltins(); /* show list of primitive builtin funcs */
Xextern int getbuiltinfunc(); /* return the index of a built-in func */
Xextern void builtincheck(); /* determine if the # of arguments are legal */
Xextern void addopfunction(); /* add opcode + index + arg count to the func */
Xextern void showfunctions(); /* show the list of user defined functs */
Xextern void clearopt(); /* clear optimization done for next opcode */
X
X/* END CODE */
END_OF_FILE
if test 2162 -ne `wc -c <'func.h'`; then
echo shar: \"'func.h'\" unpacked with wrong size!
fi
# end of 'func.h'
fi
if test ! -d 'help' ; then
echo shar: Creating directory \"'help'\"
mkdir 'help'
fi
if test -f 'help/Makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'help/Makefile'\"
else
echo shar: Extracting \"'help/Makefile'\" \(1602 characters\)
sed "s/^X//" >'help/Makefile' <<'END_OF_FILE'
X#
X# help - makefile for calc help files
X#
X# Copyright (c) 1992 David I. Bell and Landon Curt Noll
X# Permission is granted to use, distribute, or modify this source,
X# provided that this copyright notice remains intact.
X#
X# Arbitrary precision calculator.
X#
X# calculator by David I. Bell
X# makefile by Landon Curt Noll
X
X# Normally, the upper level makefile will set these values. We provide
X# a default here just in case you want to build from this directory.
X#
X# where to install things
XHELPDIR= /usr/local/lib/calc/help
X# how to build a directory
XMKDIR=mkdir -p
X#MKDIR=mkdir
X
X# The header file, along with these files form the full help file.
X#
XFULL_HELP_FILES=intro command expression define variable statement \
X operator types obj mat list file builtin config interrupt \
X history usage credit
X
X# We install these help files
X#
XHELP_FILES= ${FULL_HELP_FILES} full overview stdlib environment todo credit help
X
XSHELL= /bin/sh
X
Xall: ${HELP_FILES}
X
Xfull: header ${FULL_HELP_FILES}
X rm -f full
X cp header full
X chmod +w full
X @for i in ${FULL_HELP_FILES}; do \
X echo '' >> full; \
X echo '' >> full; \
X echo "cat $$i >> full"; \
X cat $$i >> full; \
X done
X chmod 0444 full
X
Xstdlib: ../lib/README
X rm -f stdlib
X cp ../lib/README stdlib
X chmod 0444 stdlib
X
Xclean:
X
Xclobber:
X rm -f full stdlib
X
Xinstall: all
X -@if [ ! -d ${HELPDIR} ]; then \
X echo " ${MKDIR} ${HELPDIR}"; \
X ${MKDIR} ${HELPDIR}; \
X fi
X @for i in ${HELP_FILES}; do \
X echo " rm -f ${HELPDIR}/$$i"; \
X rm -f ${HELPDIR}/$$i; \
X echo " chmod 0444 $$i"; \
X chmod 0444 $$i; \
X echo " cp $$i ${HELPDIR}"; \
X cp $$i ${HELPDIR}; \
X done
END_OF_FILE
if test 1602 -ne `wc -c <'help/Makefile'`; then
echo shar: \"'help/Makefile'\" unpacked with wrong size!
fi
# end of 'help/Makefile'
fi
if test -f 'help/credit' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'help/credit'\"
else
echo shar: Extracting \"'help/credit'\" \(847 characters\)
sed "s/^X//" >'help/credit' <<'END_OF_FILE'
XCredits
X
X Written by David I. Bell.
X
X Thanks for suggestions and encouragement from Peter Miller,
X Neil Justusson, and Landon Noll.
X
X Portions of this program are derived from an earlier set of
X public domain arbitrarily precision routines which was posted
X to the net around 1984. By now, there is almost no recognizable
X code left from that original source.
X
X Most of this source and binary is:
X
X Copyright (c) 1992 David I. Bell
X
X A few files are a joint copyright between David I. Bell and Landon Noll.
X
X Permission is granted to use, distribute, or modify this source,
X provided that this copyright notice remains intact.
X
X Send calc comments, suggestions, bug fixes, enhancements and
X interesting calc scripts that you would like you see included in
X future distributions to:
X
X db...@pdact.pd.necisa.oz.au and cho...@toad.com
X
X Enjoy!
END_OF_FILE
if test 847 -ne `wc -c <'help/credit'`; then
echo shar: \"'help/credit'\" unpacked with wrong size!
fi
# end of 'help/credit'
fi
if test -f 'help/environment' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'help/environment'\"
else
echo shar: Extracting \"'help/environment'\" \(1659 characters\)
sed "s/^X//" >'help/environment' <<'END_OF_FILE'
XEnvironment variables
X
X CALCPATH
X
X A :-separated list of directories used to search for
X scripts filenames that do not begin with /, ./ or ~.
X
X If this variable does not exist, a compiled value
X is used. Typically compiled in value is:
X
X .:./lib:~/lib:${LIBDIR}/calc
X
X where ${LIBDIR} is usually:
X
X /usr/local/lib/calc
X
X This value is used by the READ command. It is an error
X if no such readable file is found.
X
X
X CALCRC
X
X On startup (unless -h or -q was given on the command
X line), calc searches for files along the :-separated
X $CALCRC environment variable.
X
X If this variable does not exist, a compiled value
X is used. Typically compiled in value is:
X
X ${LIBDIR}/startup:~/.calcrc
X
X where ${LIBDIR} is usually:
X
X /usr/local/lib/calc
X
X Missing files along the $CALCRC path are silently ignored.
X
X HOME
X
X This value is taken to be the home directory of the
X current user. It is used when files begin with '~/'.
X
X If this variable does not exist, the home directory password
X entry of the current user is used. If that information
X is not available, '.' is used.
X
X PAGER
X
X When invoking help, this environment variable is used
X to display a help file.
X
X If this variable does not exist, a compiled value
X is used. Typically compiled in value is something
X such as 'more', 'less', 'pg' or 'cat'.
X
X SHELL
X
X When a !-command is used, the program indicated by
X this environment variable is used.
X
X If this variable does not exist, a compiled value
X is used. Typically compiled in value is something
X such as 'sh' is used.
END_OF_FILE
if test 1659 -ne `wc -c <'help/environment'`; then
echo shar: \"'help/environment'\" unpacked with wrong size!
fi
# end of 'help/environment'
fi
if test -f 'help/expression' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'help/expression'\"
else
echo shar: Extracting \"'help/expression'\" \(1413 characters\)
sed "s/^X//" >'help/expression' <<'END_OF_FILE'
XExpression sequences
X
X This is a sequence of statements, of which expression statements
X are the commonest case. Statements are separated with semicolons,
X and the newline character generally ends the sequence. If any
X statement is an expression by itself, or is associated with an
X 'if' statement which is true, then two special things can happen.
X If the sequence is executed at the top level of the calculator,
X then the value of '.' is set to the value of the last expression.
X Also, if an expression is a non-assignment, then the value of the
X expression is automatically printed if its value is not NULL.
X Some operations such as pre-increment and plus-equals are also
X treated as assignments.
X
X Examples of this are the following:
X
X expression sets '.' to prints
X ---------- ----------- ------
X 3+4 7 7
X 2*4; 8+1; fact(3) 6 8, 9, and 6
X x=3^2 9 -
X if (3 < 2) 5; else 6 6 6
X x++ old x -
X print fact(4) - 24
X null() null() -
X
X Variables can be defined at the beginning of an expression sequence.
X This is most useful for local variables, as in the following example,
X which sums the square roots of the first few numbers:
X
X local s, i; s = 0; for (i = 0; i < 10; i++) s += sqrt(i); s
X
X If a return statement is executed in an expression sequence, then
X the result of the expression sequence is the returned value. In
X this case, '.' is set to the value, but nothing is printed.
END_OF_FILE
if test 1413 -ne `wc -c <'help/expression'`; then
echo shar: \"'help/expression'\" unpacked with wrong size!
fi
# end of 'help/expression'
fi
if test -f 'help/header' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'help/header'\"
else
echo shar: Extracting \"'help/header'\" \(64 characters\)
sed "s/^X//" >'help/header' <<'END_OF_FILE'
X CALC - An arbitrary precision calculator.
X by David I. Bell
END_OF_FILE
if test 64 -ne `wc -c <'help/header'`; then
echo shar: \"'help/header'\" unpacked with wrong size!
fi
# end of 'help/header'
fi
if test -f 'help/help' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'help/help'\"
else
echo shar: Extracting \"'help/help'\" \(1210 characters\)
sed "s/^X//" >'help/help' <<'END_OF_FILE'
XFor more information while running calc, type help followed by one of the
Xfollowing topics:
X
X topic description
X ----- -----------
X intro a brief introduction to calc
X command top level commands
X expression expression sequences
X define how to define functions
X variable variables and variable declarations
X statement flow control and declaration statements
X operator math, relational, logic and variable access operators
X types builtin data types
X obj user defined data types
X mat using matrices
X list using lists
X file using files
X builtin builtin functions
X config configuration parameters
X interrupt how interrupts are handled
X history command history
X usage how to invoke the calc command
X todo needed enhancements
X credit who wrote calc, and who helped, copyright
X full all of the above topics
X help this file
X overview brief overview of calc
X stdlib description of some lib files shipped with calc
X environment how environment variables effect calc
X
XFor example:
X
X help usage
X
Xwill print the calc command usage information. One can obtain calc help
Xwithout invoking any startup code by running calc as follows:
X
X calc -q help topic
X
Xwhere 'topic' is one of the topics listed above.
END_OF_FILE
if test 1210 -ne `wc -c <'help/help'`; then
echo shar: \"'help/help'\" unpacked with wrong size!
fi
# end of 'help/help'
fi
if test -f 'help/history' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'help/history'\"
else
echo shar: Extracting \"'help/history'\" \(1019 characters\)
sed "s/^X//" >'help/history' <<'END_OF_FILE'
XCommand history
X
X There is a crude command history feature in the calculator.
X If a terminal line begins with an exclamation mark or back quote
X character (! or `), then the terminal line is handled specially.
X
X The command just typed can be re-executed by typing the
X line '``' (two back quotes).
X
X Other previous commands can be executed again by typing '`nn'
X (backquote <number>), where nn is the command number to be
X ex-executed. This number is displayed in the prompt for each
X input line, so it is easy to re-execute commands that are still
X visible on the screen. Negative numbers can be used to re-execute
X the n'th command back.
X
X The list of 20 previous commands can be displayed by typing '`h'
X (backquote h). By typing '`hnn' (backquote h <number>), one
X can ex-execute the last 'nn' commands.
X
X Up to 255 commands are saved in the history stack.
X
X A UNIX command can be executed by typing '!cmd', where cmd
X is the command to execute. If cmd is not given, then a shell
X command level is started.
END_OF_FILE
if test 1019 -ne `wc -c <'help/history'`; then
echo shar: \"'help/history'\" unpacked with wrong size!
fi
# end of 'help/history'
fi
if test -f 'help/interrupt' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'help/interrupt'\"
else
echo shar: Extracting \"'help/interrupt'\" \(1306 characters\)
sed "s/^X//" >'help/interrupt' <<'END_OF_FILE'
XInterrupts
X
X While a calculation is in progress, you can generate the SIGINT
X signal, and the calculator will catch it. At appropriate points
X within a calculation, the calculator will check that the signal
X has been given, and will abort the calculation cleanly. If the
X calculator is in the middle of a large calculation, it might be
X a while before the interrupt has an effect.
X
X You can generate the SIGINT signal multiple times if necessary,
X and each time the calculator will abort the calculation at a more
X risky place within the calculation. Each new interrupt prints a
X message of the form:
X
X [Abort level n]
X
X where n ranges from 1 to 3. For n equal to 1, the calculator will
X abort calculations at the next statement boundary. For n equal to 2,
X the calculator will abort calculations at the next opcode boundary.
X For n equal to 3, the calculator will abort calculations at the next
X lowest level arithmetic operation boundary.
X
X If a final interrupt is given when n is 3, the calculator will
X immediately abort the current calculation and longjmp back to the
X top level command level. Doing this may result in corrupted data
X structures and unpredictable future behavior, and so should only
X be done as a last resort. You are advised to quit the calculator
X after this has been done.
END_OF_FILE
if test 1306 -ne `wc -c <'help/interrupt'`; then
echo shar: \"'help/interrupt'\" unpacked with wrong size!
fi
# end of 'help/interrupt'
fi
if test -f 'help/intro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'help/intro'\"
else
echo shar: Extracting \"'help/intro'\" \(1895 characters\)
sed "s/^X//" >'help/intro' <<'END_OF_FILE'
XQuick introduction
X
X This is an interactive calculator which provides for easy large
X numeric calculations, but which also can be easily programmed
X for difficult or long calculations. It can accept a command line
X argument, in which case it executes that single command and exits.
X Otherwise, it enters interactive mode. In this mode, it accepts
X commands one at a time, processes them, and displays the answers.
X In the simplest case, commands are simply expressions which are
X evaluated. For example, the following line can be input:
X
X 3 * (4 + 1)
X
X and the calculator will print 15.
X
X The special '.' symbol (called dot), represents the result of the
X last command expression, if any. This is of great use when a series
X of partial results are calculated, or when the output mode is changed
X and the last result needs to be redisplayed. For example, the above
X result can be doubled by typing:
X
X . * 2
X
X and the calculator will print 30.
X
X For more complex calculations, variables can be used to save the
X intermediate results. For example, the result of adding 7 to the
X previous result can be saved by typing:
X
X old = . + 7
X
X Functions can be used in expressions. There are a great number of
X pre-defined functions. For example, the following will calculate
X the factorial of the value of 'old':
X
X fact(old)
X
X and the calculator prints 13763753091226345046315979581580902400000000.
X Notice that numbers can be very large. (There is a practical limit
X of several thousand digits before calculations become too slow.)
X
X The calculator can calculate transcendental functions, and accept and
X display numbers in real or exponential format. For example, typing:
X
X config("display", 50)
X epsilon(1e-50)
X sin(1)
X
X prints "~.84147098480789650665250232163029899962256306079837".
X
X The calculator also knows about complex numbers, so that typing:
X
X (2+3i) * (4-3i)
X
X prints "17+6i".
END_OF_FILE
if test 1895 -ne `wc -c <'help/intro'`; then
echo shar: \"'help/intro'\" unpacked with wrong size!
fi
# end of 'help/intro'
fi
if test -f 'help/list' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'help/list'\"
else
echo shar: Extracting \"'help/list'\" \(1880 characters\)
sed "s/^X//" >'help/list' <<'END_OF_FILE'
XUsing lists
X
X Lists are a sequence of values which are doubly linked so that
X elements can be removed or inserted anywhere within the list.
X The function 'list' creates a list with possible initial elements.
X For example,
X
X x = list(4, 6, 7);
X
X creates a list in the variable x of three elements, in the order
X 4, 6, and 7.
X
X The 'push' and 'pop' functions insert or remove an element from
X the beginning of the list. The 'append' and 'remove' functions
X insert or remove an element from the end of the list. The 'insert'
X and 'delete' functions insert or delete an element from the middle
X (or ends) of a list. The functions which insert elements return
X the null value, but the functions which remove an element return
X the element as their value. The 'size' function returns the number
X of elements in the list.
X
X Note that these functions manipulate the actual list argument,
X instead of returning a new list. Thus in the example:
X
X push(x, 9);
X
X x becomes a list of four elements, in the order 9, 4, 6, and 7.
X Lists can be copied by assigning them to another variable.
X
X An arbitrary element of a linked list can be accessed by using the
X double-bracket operator. The beginning of the list has index 0.
X Thus in the new list x above, the expression x[[0]] returns the
X value of the first element of the list, which is 9. Note that this
X indexing does not remove elements from the list.
X
X Since lists are doubly linked in memory, random access to arbitrary
X elements can be slow if the list is large. However, for each list
X a pointer is kept to the latest indexed element, thus relatively
X sequential accesses to the elements in a list will not be slow.
X
X Lists can be searched for particular values by using the 'search'
X and 'rsearch' functions. They return the element number of the
X found value (zero based), or null if the value does not exist in
X the list.
END_OF_FILE
if test 1880 -ne `wc -c <'help/list'`; then
echo shar: \"'help/list'\" unpacked with wrong size!
fi
# end of 'help/list'
fi
if test -f 'help/operator' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'help/operator'\"
else
echo shar: Extracting \"'help/operator'\" \(2549 characters\)
sed "s/^X//" >'help/operator' <<'END_OF_FILE'
XOperators
X
X The operators are similar to C, but the precedence of most of
X the operators differs. In addition, there are several additional
X operators, and some C operators are missing. The following list
X gives the operators arranged in order of precedence, from the
X least tightly binding to the most tightly binding.
X
X
X , Comma operator.
X For situations in which a comma is used for another purpose
X (function arguments, array indexing, and the print statement),
X parenthesis must be used around the comma operator.
X
X a?:b:c Conditional value.
X The test for 'a' is identical to an if test.
X
X = += -= *= /= %= //= &= |= <<= >>= ^= **=
X Assignments.
X
X || Conditional OR.
X Unlike C, the result is the first non-zero expression or 0,
X instead of just 0 or 1.
X
X && Conditional AND.
X Unlike C, the result is the last expression or 0,
X instead of just 0 or 1.
X
X == != <= >= < >
X Relations.
X
X + -
X Binary plus and minus.
X
X * / // %
X Multiply, divide. and modulo.
X Please Note: The '/' operator is a fractional divide,
X whereas the '//' is an integral divide. Thus think of '/'
X as division of real numbers, and think of '//' as division
X of integers (e.g., 8 / 3 is 8/3 whereas 8 // 3 is 2).
X The '%' is integral or fractional modulus (e.g., 11%4 is 3,
X and 10%pi() is ~.575222).
X
X | Logical OR.
X The signs of numbers do not affect the bit value.
X
X & Logical AND.
X The signs of numbers do not affect the bit value.
X
X ^ ** << >>
X Powers and shifts.
X The '^' and '**' are both exponentiation (e.g., 2^3 is 8).
X The signs of numbers do not affect the bit values of shifts.
X These operators associate rightward (e.g., 1<<3^2 is 512).
X
X + - !
X Unary operators.
X The '!' is the logical NOT operator. Be careful about
X using this as the first character of a top level command,
X since it is also used for executing UNIX commands.
X
X ++ --
X Pre or post indexing.
X These are applicable only to variables.
X
X [ ] [[ ]] . ( )
X Indexing, double-bracket indexing, element references,
X and function calls. Indexing can only be applied to matrices,
X element references can only be applied to objects, but
X double-bracket indexing can be applied to matrices, objects,
X or lists.
X
X variables constants . ( )
X These are variable names and constants, the special '.' symbol,
X or a parenthesized expression. Variable names begin with a
X letter, but then can contain letters, digits, or underscores.
X Constants are numbers in various formats, or strings inside
X either single or double quote marks.
END_OF_FILE
if test 2549 -ne `wc -c <'help/operator'`; then
echo shar: \"'help/operator'\" unpacked with wrong size!
fi
# end of 'help/operator'
fi
if test -f 'help/sums' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'help/sums'\"
else
echo shar: Extracting \"'help/sums'\" \(361 characters\)
sed "s/^X//" >'help/sums' <<'END_OF_FILE'
X58784 4 Makefile
X34745 25 builtin
X43439 6 command
X641 9 config
X9511 2 credit
X37950 6 define
X3174 4 environment
X52378 3 expression
X46486 15 file
X42777 3 help
X23416 2 history
X51967 3 interrupt
X30991 4 intro
X35089 4 list
X50373 9 mat
X43038 14 obj
X13133 5 operator
X12056 14 overview
X29205 17 statement
X0 0 sums
X1418 5 todo
X129 8 types
X47095 2 usage
X19801 5 variable
END_OF_FILE
if test 361 -ne `wc -c <'help/sums'`; then
echo shar: \"'help/sums'\" unpacked with wrong size!
fi
# end of 'help/sums'
fi
if test -f 'help/todo' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'help/todo'\"
else
echo shar: Extracting \"'help/todo'\" \(2320 characters\)
sed "s/^X//" >'help/todo' <<'END_OF_FILE'
XNeeded enhancements
X
X Send calc comments, suggestions, bug fixes, enhancements and
X interesting calc scripts that you would like you see included in
X future distributions to:
X
X db...@pdact.pd.necisa.oz.au and cho...@toad.com
X
X The following items are in the calc wish list. Programs like
X this can be extended and improved forever. The following is a
X list of changes which might be done someday.
X
X * Use faster multiply and divide algorithms for large numbers.
X
X * Add error handling statements, so that QUITs, errors from the
X 'eval' function, division by zeroes, and so on can be caught.
X This should be done using syntax similar to:
X
X ONERROR statement DO statement;
X
X Something like signal isn't versatile enough.
X
X * Add a debugging capability so that functions can be single stepped,
X breakpoints inserted, variables displayed, and so on.
X
X * Figure out how to write all variables out to a file, including
X deeply nested arrays, lists, and objects.
X
X * Make the command history useful:
X
X allowing editing of old commands
X enable history to also re-fetch the results of old
X commands, not just re-executing them
X allow the inclusion of old commands or values of old
X commands inside expressions.
X
X * Add a "ksh-like" history editor (both vi and emacs mode).
X
X * Implement pointers.
X
X * Add initializers for matrices. Perhaps allow something line:
X
X mat yummo[] = {2, 3, 5, 7, 13, 17, 19, 31, 61, 89, 107};
X
X * Eliminate the need for the define keyword by doing smarter parsing.
X
X * Allow results of a command (or all commands) to be re-directed to a
X file or piped into a unix command.
X
X * Add some kind of #include and #define facility. Perhaps use
X the C pre-processor itself?
X
X * Implement an autoload feature. Associate a calc library filename
X with a function, object, matrix or variable. On the 1st reference
X of such item, perform an automatic load of that file.
X
X * Allow one to undefine anything. Allow one to test of anything
X is defined.
X
X * Support a more general input and output base mode and just dec,
X hex or octal.
X
X * Allow support of POSIX bc via a translator reads bc commands,
X converts it to calc and pipes it into calc.
X
X * Implement symbolic algebra, such as polynomial manipulation.
END_OF_FILE
if test 2320 -ne `wc -c <'help/todo'`; then
echo shar: \"'help/todo'\" unpacked with wrong size!
fi
# end of 'help/todo'
fi
if test -f 'help/usage' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'help/usage'\"
else
echo shar: Extracting \"'help/usage'\" \(551 characters\)
sed "s/^X//" >'help/usage' <<'END_OF_FILE'
XCalc command line
X
X Calc has the following command line:
X
X calc [-h] [-q] [calc_command ...]
X
X -h print a help message (equivalent to the
X help command)
X
X -q By default, calc executes each file specified
X in the :-separated list found in the environment
X variable $CALCRC. If $CALCRC does not exist,
X an internal default is used.
X
X If some calc_commands arguments are given on the command line,
X calc executes these commands and then exists. If no command
X line arguments are given, calc prompts and reads commands
X from standard input.
END_OF_FILE
if test 551 -ne `wc -c <'help/usage'`; then
echo shar: \"'help/usage'\" unpacked with wrong size!
fi
# end of 'help/usage'
fi
if test -f 'help/variable' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'help/variable'\"
else
echo shar: Extracting \"'help/variable'\" \(2423 characters\)
sed "s/^X//" >'help/variable' <<'END_OF_FILE'
XVariable declarations
X
X Variables can be declared as either being global or local.
X Global variables are visible to all functions and on the command
X line. Local variables are visible only within a single function or
X command sequence. When the function or command sequence returns,
X the local variables are deleted.
X
X To declare one or more variables, the 'local' or 'global' keywords
X are used, followed by the desired list of variable names, separated
X by commas. The definition is terminated with a semicolon. Examples
X of declarations are:
X
X local x, y, z;
X global fred;
X local foo, bar;
X
X Within function declarations, all variables must be defined.
X But on the top level command line, assignments automatically define
X global variables as needed. For example, on the top level command
X line, the following defines the global variable x if it had not
X already been defined:
X
X x = 7
X
X Variables have no fixed type, thus there is no need or way to
X specify the types of variables as they are defined. Instead, the
X types of variables change as they are assigned to or are specified
X in special statements such as 'mat' and 'obj'. When a variable is
X first defined using 'local' or 'global', it has the null type.
X
X If a procedure defines a local variable name which matches a
X global variable name, or has a parameter name which matches a
X global variable name, then the local variable or parameter takes
X precedence within that procedure, and the global variable is not
X directly accessible.
X
X There are no pointers in the calculator language, thus all
X arguments to user-defined functions are normally passed by value.
X This is true even for matrices, strings, and lists. In order
X to circumvent this, the '&' operator is allowed before a variable
X when it is an argument to a function. When this is done, the
X address of the variable is passed to the function instead of its
X value. This is true no matter what the type of the variable is.
X This allows for fast calls of functions when the passed variable
X is huge (such as a large array). However, the passed variable can
X then be changed by the function if the parameter is assigned into.
X The function being called does not need to know if the variable
X is being passed by value or by address.
X
X Built-in functions and object functions always accept their
X arguments as addresses, thus there is no need to use '&' when
X calling built-in functions.
END_OF_FILE
if test 2423 -ne `wc -c <'help/variable'`; then
echo shar: \"'help/variable'\" unpacked with wrong size!
fi
# end of 'help/variable'
fi
if test -f 'label.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'label.h'\"
else
echo shar: Extracting \"'label.h'\" \(534 characters\)
sed "s/^X//" >'label.h' <<'END_OF_FILE'
X/*
X * Copyright (c) 1992 David I. Bell
X * Permission is granted to use, distribute, or modify this source,
X * provided that this copyright notice remains intact.
X */
X
X
X/*
X * Label structures.
X */
Xtypedef struct {
X long l_offset; /* offset into code of label */
X long l_chain; /* offset into code of undefined chain */
X char *l_name; /* name of label if any */
X} LABEL;
X
Xextern void initlabels(), definelabel(), addlabel();
Xextern void checklabels(), clearlabel(), setlabel();
Xextern void uselabel();
X
X/* END CODE */
END_OF_FILE
if test 534 -ne `wc -c <'label.h'`; then
echo shar: \"'label.h'\" unpacked with wrong size!
fi
# end of 'label.h'
fi
if test ! -d 'lib' ; then
echo shar: Creating directory \"'lib'\"
mkdir 'lib'
fi
if test -f 'lib/Makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'lib/Makefile'\"
else
echo shar: Extracting \"'lib/Makefile'\" \(1215 characters\)
sed "s/^X//" >'lib/Makefile' <<'END_OF_FILE'
X#
X# lib - makefile for calc library scripts
X#
X# Copyright (c) 1992 David I. Bell and Landon Curt Noll
X# Permission is granted to use, distribute, or modify this source,
X# provided that this copyright notice remains intact.
X#
X# Arbitrary precision calculator.
X#
X# calculator by David I. Bell
X# makefile by Landon Curt Noll
X
X# Normally, the upper level makefile will set these values. We provide
X# a default here just in case you want to build from this directory.
X#
X# where to install things
XLIBDIR= /usr/local/lib/calc
X# how to build a directory
XMKDIR=mkdir -p
X#MKDIR=mkdir
X
X# The calc files to install
X#
XCALC_FILES= README bigprime.cal deg.cal ellip.cal lucas.cal lucas_chk.cal \
X lucas_tbl.cal mersenne.cal mod.cal nextprim.cal pell.cal pi.cal \
X pollard.cal poly.cal psqrt.cal quat.cal regress.cal solve.cal \
X sumsq.cal surd.cal unitfrac.cal varargs.cal
X
XSHELL= /bin/sh
X
Xall: ${CALC_FILES}
X
Xclean:
X
Xclobber:
X
Xinstall: all
X -@if [ ! -d ${LIBDIR} ]; then \
X echo " ${MKDIR} ${LIBDIR}"; \
X ${MKDIR} ${LIBDIR}; \
X fi
X @for i in ${CALC_FILES}; do \
X echo " rm -f ${LIBDIR}/$$i"; \
X rm -f ${LIBDIR}/$$i; \
X echo " chmod 0444 $$i"; \
X chmod 0444 $$i; \
X echo " cp $$i ${LIBDIR}"; \
X cp $$i ${LIBDIR}; \
X done
END_OF_FILE
if test 1215 -ne `wc -c <'lib/Makefile'`; then
echo shar: \"'lib/Makefile'\" unpacked with wrong size!
fi
# end of 'lib/Makefile'
fi
if test -f 'lib/bernoulli.cal' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'lib/bernoulli.cal'\"
else
echo shar: Extracting \"'lib/bernoulli.cal'\" \(1454 characters\)
sed "s/^X//" >'lib/bernoulli.cal' <<'END_OF_FILE'
X/*
X * Copyright (c) 1992 David I. Bell
X * Calculate the Nth Bernoulli number B(n).
X * This uses the following symbolic formula to calculate B(n):
X *
X * (b+1)^(n+1) - b^(n+1) = 0
X *
X * where b is a dummy value, and each power b^i gets replaced by B(i).
X * For example, for n = 3:
X * (b+1)^4 - b^4 = 0
X * b^4 + 4*b^3 + 6*b^2 + 4*b + 1 - b^4 = 0
X * 4*b^3 + 6*b^2 + 4*b + 1 = 0
X * 4*B(3) + 6*B(2) + 4*B(1) + 1 = 0
X * B(3) = -(6*B(2) + 4*B(1) + 1) / 4
X *
X * The combinatorial factors in the expansion of the above formula are
X * calculated interatively, and we use the fact that B(2i+1) = 0 if i > 0.
X * Since all previous B(n)'s are needed to calculate a particular B(n), all
X * values obtained are saved in an array for ease in repeated calculations.
X */
Xglobal Bn, Bnmax;
Xmat Bn[1001];
XBnmax = 0;
X
X
Xdefine B(n)
X{
X local nn, np1, i, sum, mulval, divval, combval;
X
X if (!isint(n) || (n < 0))
X quit "Non-negative integer required for Bernoulli";
X
X if (n == 0)
X return 1;
X if (n == 1)
X return -1/2;
X if (isodd(n))
X return 0;
X if (n > 1000)
X quit "Very large Bernoulli";
X
X if (n <= Bnmax)
X return Bn[n];
X
X for (nn = Bnmax + 2; nn <= n; nn+=2) {
X np1 = nn + 1;
X mulval = np1;
X divval = 1;
X combval = 1;
X sum = 1 - np1 / 2;
X for (i = 2; i < np1; i+=2) {
X combval = combval * mulval-- / divval++;
X combval = combval * mulval-- / divval++;
X sum += combval * Bn[i];
X }
X Bn[nn] = -sum / np1;
X }
X Bnmax = n;
X return Bn[n];
X}
X
Xprint 'B(n) defined';
END_OF_FILE
if test 1454 -ne `wc -c <'lib/bernoulli.cal'`; then
echo shar: \"'lib/bernoulli.cal'\" unpacked with wrong size!
fi
# end of 'lib/bernoulli.cal'
fi
if test -f 'lib/bigprime.cal' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'lib/bigprime.cal'\"
else
echo shar: Extracting \"'lib/bigprime.cal'\" \(565 characters\)
sed "s/^X//" >'lib/bigprime.cal' <<'END_OF_FILE'
X/*
X * Copyright (c) 1992 David I. Bell
X * Permission is granted to use, distribute, or modify this source,
X * provided that this copyright notice remains intact.
X *
X * A prime test, base a, on p*2^x+1 for even x>m.
X */
X
Xdefine bigprime(a, m, p)
X{
X local n1, n;
X
X n1 = 2^m * p;
X for (;;) {
X m++;
X n1 += n1;
X n = n1 + 1;
X if (isodd(m))
X continue;
X print m;
X if (pmod(a, n1 / 2, n) != n1)
X continue;
X if (pmod(a, n1 / p, n) == 1)
X continue;
X print " " : n;
X }
X}
X
Xglobal lib_debug;
Xif (!isnum(lib_debug) || lib_debug>0) print "bigprime(a, m, p) defined";
END_OF_FILE
if test 565 -ne `wc -c <'lib/bigprime.cal'`; then
echo shar: \"'lib/bigprime.cal'\" unpacked with wrong size!
fi
# end of 'lib/bigprime.cal'
fi
if test -f 'lib/deg.cal' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'lib/deg.cal'\"
else
echo shar: Extracting \"'lib/deg.cal'\" \(2204 characters\)
sed "s/^X//" >'lib/deg.cal' <<'END_OF_FILE'
X/*
X * Copyright (c) 1992 David I. Bell
X * Permission is granted to use, distribute, or modify this source,
X * provided that this copyright notice remains intact.
X *
X * Calculate in degrees, minutes, and seconds.
X */
X
Xobj dms {deg, min, sec};
X
Xdefine dms(deg, min, sec)
X{
X local ans;
X
X if (isnull(sec))
X sec = 0;
X if (isnull(min))
X min = 0;
X obj dms ans;
X ans.deg = deg;
X ans.min = min;
X ans.sec = sec;
X fixdms(&ans);
X return ans;
X}
X
X
Xdefine dms_add(a, b)
X{
X local ans;
X
X obj dms ans;
X ans.deg = 0;
X ans.min = 0;
X ans.sec = 0;
X if (istype(a, ans)) {
X ans.deg += a.deg;
X ans.min += a.min;
X ans.sec += a.sec;
X } else
X ans.deg += a;
X if (istype(b, ans)) {
X ans.deg += b.deg;
X ans.min += b.min;
X ans.sec += b.sec;
X } else
X ans.deg += b;
X fixdms(&ans);
X return ans;
X}
X
X
Xdefine dms_neg(a)
X{
X local ans;
X
X obj dms ans;
X ans.deg = -ans.deg;
X ans.min = -ans.min;
X ans.sec = -ans.sec;
X return ans;
X}
X
X
Xdefine dms_sub(a, b)
X{
X return a - b;
X}
X
X
Xdefine dms_mul(a, b)
X{
X local ans;
X
X obj dms ans;
X if (istype(a, ans) && istype(b, ans))
X quit "Cannot multiply degrees together";
X if (istype(a, ans)) {
X ans.deg = a.deg * b;
X ans.min = a.min * b;
X ans.sec = a.sec * b;
X } else {
X ans.deg = b.deg * a;
X ans.min = b.min * a;
X ans.sec = b.sec * a;
X }
X fixdms(&ans);
X return ans;
X}
X
X
Xdefine dms_print(a)
X{
X print a.deg : 'd' : a.min : 'm' : a.sec : 's' :;
X}
X
X
Xdefine dms_abs(a)
X{
X return a.deg + a.min / 60 + a.sec / 3600;
X}
X
X
Xdefine fixdms(a)
X{
X a.min += frac(a.deg) * 60;
X a.deg = int(a.deg);
X a.sec += frac(a.min) * 60;
X a.min = int(a.min);
X a.min += a.sec // 60;
X a.sec %= 60;
X a.deg += a.min // 60;
X a.min %= 60;
X a.deg %= 360;
X}
X
Xglobal lib_debug;
Xif (!isnum(lib_debug) || lib_debug>0) print "obj dms {deg, min, sec} defined"
Xif (!isnum(lib_debug) || lib_debug>0) print "dms(deg, min, sec) defined"
Xif (!isnum(lib_debug) || lib_debug>0) print "dms_add(a, b) defined"
Xif (!isnum(lib_debug) || lib_debug>0) print "dms_neg(a) defined"
Xif (!isnum(lib_debug) || lib_debug>0) print "dms_sub(a, b) defined"
Xif (!isnum(lib_debug) || lib_debug>0) print "dms_mul(a, b) defined"
Xif (!isnum(lib_debug) || lib_debug>0) print "dms_print(a) defined"
Xif (!isnum(lib_debug) || lib_debug>0) print "dms_abs(a) defined"
END_OF_FILE
if test 2204 -ne `wc -c <'lib/deg.cal'`; then
echo shar: \"'lib/deg.cal'\" unpacked with wrong size!
fi
# end of 'lib/deg.cal'
fi
if test -f 'lib/mersenne.cal' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'lib/mersenne.cal'\"
else
echo shar: Extracting \"'lib/mersenne.cal'\" \(843 characters\)
sed "s/^X//" >'lib/mersenne.cal' <<'END_OF_FILE'
X/*
X * Copyright (c) 1992 David I. Bell
X * Permission is granted to use, distribute, or modify this source,
X * provided that this copyright notice remains intact.
X *
X * Perform a primality test of 2^p-1, for prime p>1.
X */
X
Xdefine mersenne(p)
X{
X local u, i, p_mask;
X
X /* firewall */
X if (! isint(p))
X quit "p is not an integer";
X
X /* two is a special case */
X if (p == 2)
X return 1;
X
X /* if p is not prime, then 2^p-1 is not prime */
X if (! ptest(p,10))
X return 0;
X
X /* calculate 2^p-1 for later mods */
X p_mask = 2^p - 1;
X
X /* lltest: u(i+1) = u(i)^2 - 2 mod 2^p-1 */
X u = 4;
X for (i = 2; i < p; ++i) {
X u = u^2 - 2;
X u = u&p_mask + u>>p;
X if (u > p_mask)
X u = u&p_mask + 1;
X }
X
X /* 2^p-1 is prime iff u(p) = 0 mod 2^p-1 */
X return (u == p_mask);
X}
X
Xglobal lib_debug;
Xif (!isnum(lib_debug) || lib_debug>0) print "mersenne(p) defined";
END_OF_FILE
if test 843 -ne `wc -c <'lib/mersenne.cal'`; then
echo shar: \"'lib/mersenne.cal'\" unpacked with wrong size!
fi
# end of 'lib/mersenne.cal'
fi
if test -f 'lib/nextprim.cal' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'lib/nextprim.cal'\"
else
echo shar: Extracting \"'lib/nextprim.cal'\" \(450 characters\)
sed "s/^X//" >'lib/nextprim.cal' <<'END_OF_FILE'
X/*
X * Copyright (c) 1992 David I. Bell
X * Permission is granted to use, distribute, or modify this source,
X * provided that this copyright notice remains intact.
X *
X * Function to find the next prime (probably).
X */
X
Xdefine nextprime(n, tries)
X{
X if (isnull(tries))
X tries = 20;
X if (iseven(n))
X n++;
X while (ptest(n, tries) == 0)
X n += 2;
X return n;
X}
X
Xglobal lib_debug;
Xif (!isnum(lib_debug) || lib_debug>0) print "nextprime(n, tries) defined";
END_OF_FILE
if test 450 -ne `wc -c <'lib/nextprim.cal'`; then
echo shar: \"'lib/nextprim.cal'\" unpacked with wrong size!
fi
# end of 'lib/nextprim.cal'
fi
if test -f 'lib/pell.cal' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'lib/pell.cal'\"
else
echo shar: Extracting \"'lib/pell.cal'\" \(1290 characters\)
sed "s/^X//" >'lib/pell.cal' <<'END_OF_FILE'
X/*
X * Copyright (c) 1992 David I. Bell
X * Permission is granted to use, distribute, or modify this source,
X * provided that this copyright notice remains intact.
X *
X * Solve Pell's equation; Returns the solution X to: X^2 - D * Y^2 = 1.
X * Type the solution to pells equation for a particular D.
X */
X
Xdefine pell(D)
X{
X local X, Y;
X
X X = pellx(D);
X if (isnull(X)) {
X print "D=":D:" is square";
X return;
X }
X Y = isqrt((X^2 - 1) / D);
X print X : "^2 - " : D : "*" : Y : "^2 = " : X^2 - D*Y^2;
X}
X
X
X/*
X * Function to solve Pell's equation
X * Returns the solution X to:
X * X^2 - D * Y^2 = 1
X */
Xdefine pellx(D)
X{
X local R, Rp, U, Up, V, Vp, A, T, Q1, Q2, n, ans, tmp;
X
X mat ans[2,2];
X mat tmp[2,2];
X
X R = isqrt(D);
X Vp = D - R^2;
X if (Vp == 0)
X return;
X Rp = R + R;
X U = Rp;
X Up = U;
X V = 1;
X A = 0;
X n = 0;
X ans[0,0] = 1;
X ans[1,1] = 1;
X tmp[0,1] = 1;
X tmp[1,0] = 1;
X do {
X T = V;
X V = A * (Up - U) + Vp;
X Vp = T;
X A = U // V;
X Up = U;
X U = Rp - U % V;
X tmp[0,0] = A;
X ans *= tmp;
X n++;
X } while (A != Rp);
X Q2 = ans[[1]];
X Q1 = isqrt(Q2^2 * D + 1);
X if (isodd(n)) {
X T = Q1^2 + D * Q2^2;
X Q2 = Q1 * Q2 * 2;
X Q1 = T;
X }
X return Q1;
X}
X
Xglobal lib_debug;
Xif (!isnum(lib_debug) || lib_debug>0) print "pell(D) defined";
Xif (!isnum(lib_debug) || lib_debug>0) print "pellx(D) defined";
END_OF_FILE
if test 1290 -ne `wc -c <'lib/pell.cal'`; then
echo shar: \"'lib/pell.cal'\" unpacked with wrong size!
fi
# end of 'lib/pell.cal'
fi
if test -f 'lib/pi.cal' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'lib/pi.cal'\"
else
echo shar: Extracting \"'lib/pi.cal'\" \(1320 characters\)
sed "s/^X//" >'lib/pi.cal' <<'END_OF_FILE'
X/*
X * Copyright (c) 1992 David I. Bell
X * Permission is granted to use, distribute, or modify this source,
X * provided that this copyright notice remains intact.
X *
X * Calculate pi within the specified epsilon using the quartic convergence
X * iteration.
X */
X
Xdefine qpi(epsilon)
X{
X local niter, yn, ym, tm, an, am, t, tn, sqrt2, epsilon2, count, digits;
X local bits, bits2;
X
X if (isnull(epsilon))
X epsilon = epsilon();
X digits = digits(1/epsilon);
X if (digits <= 8) { niter = 1; epsilon = 1e-8; }
X else if (digits <= 40) { niter = 2; epsilon = 1e-40; }
X else if (digits <= 170) { niter = 3; epsilon = 1e-170; }
X else if (digits <= 693) { niter = 4; epsilon = 1e-693; }
X else {
X niter = 4;
X t = 693;
X while (t < epsilon) {
X ++niter;
X t *= 4;
X }
X }
X epsilon2 = epsilon/(digits/10 + 1);
X digits = digits(1/epsilon2);
X sqrt2 = sqrt(2, epsilon2);
X bits = abs(log2(epsilon)) + 1;
X bits2 = abs(log2(epsilon2)) + 1;
X yn = sqrt2 - 1;
X an = 6 - 4 * sqrt2;
X tn = 2;
X for (count = 0; count < niter; count++) {
X ym = yn;
X am = an;
X tn *= 4;
X t = sqrt(sqrt(1-ym^4, epsilon2), epsilon2);
X yn = (1-t)/(1+t);
X an = (1+yn)^4*am-tn*yn*(1+yn+yn^2);
X yn = bround(yn, bits2);
X an = bround(an, bits2);
X }
X return (bround(1/an, bits));
X}
X
Xglobal lib_debug;
Xif (!isnum(lib_debug) || lib_debug>0) print "qpi(epsilon) defined";
END_OF_FILE
if test 1320 -ne `wc -c <'lib/pi.cal'`; then
echo shar: \"'lib/pi.cal'\" unpacked with wrong size!
fi
# end of 'lib/pi.cal'
fi
if test -f 'lib/pollard.cal' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'lib/pollard.cal'\"
else
echo shar: Extracting \"'lib/pollard.cal'\" \(630 characters\)
sed "s/^X//" >'lib/pollard.cal' <<'END_OF_FILE'
X/*
X * Copyright (c) 1992 David I. Bell
X * Permission is granted to use, distribute, or modify this source,
X * provided that this copyright notice remains intact.
X *
X * Factor using Pollard's p-1 method.
X */
X
Xdefine factor(N, B, ai, af)
X{
X local a, k, i, d;
X
X if (isnull(B))
X B = 1000;
X if (isnull(ai))
X ai = 2;
X if (isnull(af))
X af = ai + 20;
X k = lcmfact(B);
X d = lfactor(N, B);
X if (d > 1)
X return d;
X for (a = ai; a <= af; a++) {
X i = pmod(a, k, N);
X d = gcd(i - 1, N);
X if ((d > 1) && (d != N))
X return d;
X }
X return 1;
X}
X
Xglobal lib_debug;
Xif (!isnum(lib_debug) || lib_debug>0) print "factor(N, B, ai, af) defined";
END_OF_FILE
if test 630 -ne `wc -c <'lib/pollard.cal'`; then
echo shar: \"'lib/pollard.cal'\" unpacked with wrong size!
fi
# end of 'lib/pollard.cal'
fi
if test -f 'lib/psqrt.cal' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'lib/psqrt.cal'\"
else
echo shar: Extracting \"'lib/psqrt.cal'\" \(1010 characters\)
sed "s/^X//" >'lib/psqrt.cal' <<'END_OF_FILE'
X/*
X * Copyright (c) 1992 David I. Bell
X * Permission is granted to use, distribute, or modify this source,
X * provided that this copyright notice remains intact.
X *
X * Calculate square roots modulo a prime.
X *
X * Returns null if number is not prime or if there is no square root.
X * The smaller square root is always returned.
X */
X
Xdefine psqrt(u, p)
X{
X local p1, q, n, y, r, v, w, t, k;
X
X p1 = p - 1;
X r = lowbit(p1);
X q = p >> r;
X t = 1 << (r - 1);
X for (n = 2; ; n++) {
X if (ptest(n, 1) == 0)
X continue;
X y = pmod(n, q, p);
X k = pmod(y, t, p);
X if (k == 1)
X continue;
X if (k != p1)
X return;
X break;
X }
X t = pmod(u, (q - 1) / 2, p);
X v = (t * u) % p;
X w = (t^2 * u) % p;
X while (w != 1) {
X k = 0;
X t = w;
X do {
X k++;
X t = t^2 % p;
X } while (t != 1);
X if (k == r)
X return;
X t = pmod(y, 1 << (r - k - 1), p);
X y = t^2 % p;
X v = (v * t) % p;
X w = (w * y) % p;
X r = k;
X }
X return min(v, p - v);
X}
X
X
Xglobal lib_debug;
Xif (!isnum(lib_debug) || lib_debug>0) print "psqrt(u, p) defined";
END_OF_FILE
if test 1010 -ne `wc -c <'lib/psqrt.cal'`; then
echo shar: \"'lib/psqrt.cal'\" unpacked with wrong size!
fi
# end of 'lib/psqrt.cal'
fi
if test -f 'lib/solve.cal' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'lib/solve.cal'\"
else
echo shar: Extracting \"'lib/solve.cal'\" \(1192 characters\)
sed "s/^X//" >'lib/solve.cal' <<'END_OF_FILE'
X/*
X * Copyright (c) 1992 David I. Bell
X * Permission is granted to use, distribute, or modify this source,
X * provided that this copyright notice remains intact.
X *
X * Solve the equation f(x) = 0 to within the desired error value for x.
X * The function 'f' must be defined outside of this routine, and the low
X * and high values are guesses which must produce values with opposite signs.
X */
X
Xdefine solve(low, high, epsilon)
X{
X local flow, fhigh, fmid, mid, places;
X
X if (isnull(epsilon))
X epsilon = epsilon();
X if (epsilon <= 0)
X quit "Non-positive epsilon value";
X places = highbit(1 + int(1/epsilon)) + 1;
X flow = f(low);
X if (abs(flow) < epsilon)
X return low;
X fhigh = f(high);
X if (abs(flow) < epsilon)
X return high;
X if (sgn(flow) == sgn(fhigh))
X quit "Non-opposite signs";
X while (1) {
X mid = bround(high - fhigh * (high - low) / (fhigh - flow), places);
X if ((mid == low) || (mid == high))
X places++;
X fmid = f(mid);
X if (abs(fmid) < epsilon)
X return mid;
X if (sgn(fmid) == sgn(flow)) {
X low = mid;
X flow = fmid;
X } else {
X high = mid;
X fhigh = fmid;
X }
X }
X}
X
Xglobal lib_debug;
Xif (!isnum(lib_debug) || lib_debug>0) print "solve(low, high, epsilon) defined";
END_OF_FILE
if test 1192 -ne `wc -c <'lib/solve.cal'`; then
echo shar: \"'lib/solve.cal'\" unpacked with wrong size!
fi
# end of 'lib/solve.cal'
fi
if test -f 'lib/sumsq.cal' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'lib/sumsq.cal'\"
else
echo shar: Extracting \"'lib/sumsq.cal'\" \(879 characters\)
sed "s/^X//" >'lib/sumsq.cal' <<'END_OF_FILE'
X/*
X * Copyright (c) 1992 David I. Bell
X * Permission is granted to use, distribute, or modify this source,
X * provided that this copyright notice remains intact.
X *
X * Determine the unique two positive integers whose squares sum to the
X * specified prime. This is always possible for all primes of the form
X * 4N+1, and always impossible for primes of the form 4N-1.
X */
X
Xdefine ss(p)
X{
X local a, b, i, p4;
X
X if (p == 2) {
X print "1^2 + 1^2 = 2";
X return;
X }
X if ((p % 4) != 1) {
X print p, "is not of the form 4N+1";
X return;
X }
X if (!ptest(p, min(p-2, 10))) {
X print p, "is not a prime";
X return;
X }
X p4 = (p - 1) / 4;
X i = 2;
X do {
X a = pmod(i++, p4, p);
X } while ((a^2 % p) == 1);
X b = p;
X while (b^2 > p) {
X i = b % a;
X b = a;
X a = i;
X }
X print a : "^2 +" , b : "^2 =" , a^2 + b^2;
X}
X
Xglobal lib_debug;
Xif (!isnum(lib_debug) || lib_debug>0) print "ss(p) defined";
END_OF_FILE
if test 879 -ne `wc -c <'lib/sumsq.cal'`; then
echo shar: \"'lib/sumsq.cal'\" unpacked with wrong size!
fi
# end of 'lib/sumsq.cal'
fi
if test -f 'lib/unitfrac.cal' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'lib/unitfrac.cal'\"
else
echo shar: Extracting \"'lib/unitfrac.cal'\" \(849 characters\)
sed "s/^X//" >'lib/unitfrac.cal' <<'END_OF_FILE'
X/*
X * Copyright (c) 1992 David I. Bell
X * Permission is granted to use, distribute, or modify this source,
X * provided that this copyright notice remains intact.
X *
X * Represent a fraction as sum of distinct unit fractions.
X * The output is the unit fractions themselves, and in square brackets,
X * the number of digits in the numerator and denominator of the value left
X * to be found. Numbers larger than 3.5 become very difficult to calculate.
X */
X
Xdefine unitfrac(x)
X{
X local d, di, n;
X
X if (x <= 0)
X quit "Non-positive argument";
X d = 2;
X do {
X n = int(1 / x) + 1;
X if (n > d)
X d = n;
X di = 1/d;
X print ' [': digits(num(x)): '/': digits(den(x)): ']',, di;
X x -= di;
X d++;
X } while ((num(x) > 1) || (x == di) || (x == 1));
X print ' [1/1]',, x;
X}
X
X
Xglobal lib_debug;
Xif (!isnum(lib_debug) || lib_debug>0) print "unitfrac(x) defined";
END_OF_FILE
if test 849 -ne `wc -c <'lib/unitfrac.cal'`; then
echo shar: \"'lib/unitfrac.cal'\" unpacked with wrong size!
fi
# end of 'lib/unitfrac.cal'
fi
if test -f 'lib/varargs.cal' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'lib/varargs.cal'\"
else
echo shar: Extracting \"'lib/varargs.cal'\" \(547 characters\)
sed "s/^X//" >'lib/varargs.cal' <<'END_OF_FILE'
X/*
X * Copyright (c) 1992 David I. Bell
X * Permission is granted to use, distribute, or modify this source,
X * provided that this copyright notice remains intact.
X *
X * Example program to use 'varargs'.
X *
X * Program to sum the cubes of all the specified numbers.
X */
X
Xdefine sc()
X{
X local s, i;
X
X s = 0;
X for (i = 1; i <= param(0); i++) {
X if (!isnum(param(i))) {
X print "parameter",i,"is not a number";
X continue;
X }
X s += param(i)^3;
X }
X return s;
X}
X
Xglobal lib_debug;
Xif (!isnum(lib_debug) || lib_debug>0) print "sc(a, b, ...) defined";
END_OF_FILE
if test 547 -ne `wc -c <'lib/varargs.cal'`; then
echo shar: \"'lib/varargs.cal'\" unpacked with wrong size!
fi
# end of 'lib/varargs.cal'
fi
if test -f 'lint.sed' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'lint.sed'\"
else
echo shar: Extracting \"'lint.sed'\" \(1277 characters\)
sed "s/^X//" >'lint.sed' <<'END_OF_FILE'
X/^[a-z][a-z_]*\.c:$/d
X/name declared but never used or defined: .* \/usr\/include\/malloc.h(/d
X/implicitly declared to return int: _sysconf$/d
X/name used but not defined: _sysconf in /d
X/function returns value which is [a-z][a-z]* ignored: memcpy$/d
X/function returns value which is [a-z][a-z]* ignored: strcpy$/d
X/function returns value which is [a-z][a-z]* ignored: strncpy$/d
X/function returns value which is [a-z][a-z]* ignored: strcat$/d
X/function returns value which is [a-z][a-z]* ignored: memset$/d
X/function returns value which is [a-z][a-z]* ignored: fclose$/d
X/function returns value which is [a-z][a-z]* ignored: fflush$/d
X/function returns value which is [a-z][a-z]* ignored: fprintf$/d
X/function returns value which is [a-z][a-z]* ignored: printf$/d
X/function returns value which is [a-z][a-z]* ignored: sprintf$/d
X/function returns value which is [a-z][a-z]* ignored: vsprintf$/d
X/function returns value which is [a-z][a-z]* ignored: fputc$/d
X/function returns value which is [a-z][a-z]* ignored: fputs$/d
X/function returns value which is [a-z][a-z]* ignored: putchar$/d
X/function returns value which is [a-z][a-z]* ignored: ungetc$/d
X/function returns value which is [a-z][a-z]* ignored: system$/d
X/function returns value which is [a-z][a-z]* ignored: times$/d
END_OF_FILE
if test 1277 -ne `wc -c <'lint.sed'`; then
echo shar: \"'lint.sed'\" unpacked with wrong size!
fi
# end of 'lint.sed'
fi
if test -f 'stdarg.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'stdarg.h'\"
else
echo shar: Extracting \"'stdarg.h'\" \(904 characters\)
sed "s/^X//" >'stdarg.h' <<'END_OF_FILE'
X/*
X * Copyright (c) 1992 David I. Bell
X * Permission is granted to use, distribute, or modify this source,
X * provided that this copyright notice remains intact.
X */
X
X#include "args.h"
X
X#ifndef STDARG_H
X#define STDARG_H
X
X#ifdef VARARGS
X
X#include <varargs.h>
X
X#else /*VARARG*/
X
X#ifdef STDARG
X
X#if defined(__STDC__)
X#include <stdarg.h>
X#else
X%;%;% BOGUS DEFINE! Must use ANSI C when STDARG is defined %;%;%
X#endif
X
X#else /*STDARG*/
X
X/*
X * SIMULATE_STDARG
X *
X * WARNING: This type of stdarg makes assumptions about the stack
X * that may not be true on your system. You may want to
X * define STDARG (if using ANSI C) or VARARGS.
X */
X
Xtypedef char *va_list;
X#define va_start(ap,parmn) (void)((ap) = (char*)(&(parmn) + 1))
X#define va_end(ap) (void)((ap) = 0)
X#define va_arg(ap, type) \
X (((type*)((ap) = ((ap) + sizeof(type))))[-1])
X
X#endif /*STDARG*/
X#endif /*VARARG*/
X
X#endif
X
X/* END CODE */
END_OF_FILE
if test 904 -ne `wc -c <'stdarg.h'`; then
echo shar: \"'stdarg.h'\" unpacked with wrong size!
fi
# end of 'stdarg.h'
fi
if test -f 'string.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'string.h'\"
else
echo shar: Extracting \"'string.h'\" \(529 characters\)
sed "s/^X//" >'string.h' <<'END_OF_FILE'
X/*
X * Copyright (c) 1992 David I. Bell
X * Permission is granted to use, distribute, or modify this source,
X * provided that this copyright notice remains intact.
X */
X
X
Xtypedef struct {
X char *h_list; /* list of strings separated by nulls */
X long h_used; /* characters used so far */
X long h_avail; /* characters available for use */
X long h_count; /* number of strings */
X} STRINGHEAD;
X
X
Xextern char *addstr(), *namestr(), *charstr(), *addliteral();
Xextern long findstr(), stringindex();
X
Xextern void initstr();
X
X/* END CODE */
END_OF_FILE
if test 529 -ne `wc -c <'string.h'`; then
echo shar: \"'string.h'\" unpacked with wrong size!
fi
# end of 'string.h'
fi
if test -f 'symbol.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'symbol.h'\"
else
echo shar: Extracting \"'symbol.h'\" \(1148 characters\)
sed "s/^X//" >'symbol.h' <<'END_OF_FILE'
X/*
X * Copyright (c) 1992 David I. Bell
X * Permission is granted to use, distribute, or modify this source,
X * provided that this copyright notice remains intact.
X */
X
X
X/*
X * Symbol Declarations.
X */
X#define SYM_UNDEFINED 0 /* undefined symbol */
X#define SYM_PARAM 1 /* paramater symbol */
X#define SYM_LOCAL 2 /* local symbol */
X#define SYM_GLOBAL 3 /* global symbol */
X
X
Xtypedef struct global GLOBAL;
Xstruct global {
X int g_len; /* length of symbol name */
X char *g_name; /* global symbol name */
X VALUE g_value; /* global symbol value */
X GLOBAL *g_next; /* next symbol in hash chain */
X};
X
X
X/*
X * Routines to search for global symbols.
X */
Xextern GLOBAL *addglobal(), *findglobal();
X
X
X/*
X * Routines to return names of variables.
X */
Xextern char *localname(), *globalname(), *paramname();
X
X
X/*
X * Other routines.
X */
Xextern long addlocal(), findlocal(), addparam(), findparam();
Xextern void initlocals();
Xextern void initglobals();
Xextern void initfunctions();
Xextern int writeglobals();
Xextern int symboltype(); /* return the type of a variable name */
Xextern void showglobals(); /* show the value of all global variables */
X
X/* END CODE */
END_OF_FILE
if test 1148 -ne `wc -c <'symbol.h'`; then
echo shar: \"'symbol.h'\" unpacked with wrong size!
fi
# end of 'symbol.h'
fi
if test -f 'version.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'version.c'\"
else
echo shar: Extracting \"'version.c'\" \(531 characters\)
sed "s/^X//" >'version.c' <<'END_OF_FILE'
X/*
X * Copyright (c) 1992 David I. Bell
X * Permission is granted to use, distribute, or modify this source,
X * provided that this copyright notice remains intact.
X *
X * version - determine the version of calc
X */
X
X#include <stdio.h>
X
X#define MAJOR_VER 1 /* major version */
X#define MINOR_VER 24 /* minor version */
X#define PATCH_LEVEL 7 /* patch level */
X
Xvoid
Xversion(stream)
X FILE *stream; /* stream to write version on */
X{
X fprintf(stream, "calc version: %d.%d.%d\n",
X MAJOR_VER, MINOR_VER, PATCH_LEVEL);
X}
X
X/* END CODE */
END_OF_FILE
if test 531 -ne `wc -c <'version.c'`; then
echo shar: \"'version.c'\" unpacked with wrong size!
fi
# end of 'version.c'
fi
echo shar: End of archive 1 \(of 21\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 21 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0