home *** CD-ROM | disk | FTP | other *** search
-
- Arbitrary Precision Math Library
-
- The Arbitrary Precision Math Library is a series of routines that
- allows the user to perform math to any level of accuracy that is
- desired. These APM entities ("APM" == "Arbitrary Precision Math") can
- be initialized from character strings or from long integers, and they
- can be converted back into character strings by a routine that allows
- simple formatting. With the exception of the routines that do
- division, the results of APM operations are guaranteed to contain
- enough precision to hold exact values. The APM routines will
- automatically allocate enough space in their results to hold the
- proper number of digits.
-
- The APM math is done on a new data type called "APM". This is
- actually a pointer to a structure, but the contents of the structure
- should never be manipulated: all operations on APM entities are done
- through a functional interface.
-
- APM items can be represented in any of 36 bases: 2 through 36 and
- 10000. The latter is quite useful: numbers that are represented in
- bases that are powers of 10 are quite easy to accurately convert to
- and from character strings containing their decimal representation,
- and 10000 is the largest power of 10 that fits into a short integer
- (16 bits). The base must fit into a short integer since calculations
- internal to the APM routines need up to twice as much storage as is
- needed to hold the base, and the largest unit we can deal with easily
- is a long integer (2 shorts). It turns out that speed improves and
- memory usage decreases as the magnitude of the base increases, so base
- 10000 is a win in both counts. I have done some informal benchmarks
- in which base 10000 is 6 to 10 times faster than base 10 for numbers
- with 15 - 20 decimal digits of precision.
-
- Although there is a multitude of bases, there is as yet no provision
- for conversion from one base to another, except for the special case
- of converting between base-10 character strings and base-10000 APM
- values. All the input APM parameters to any given APM routine must be
- of the same base.
-
- The caller must initialize all APM values before the routines can
- operate on them (including the values intended to contain results of
- calculations). Once this initialization is done, the user never needs
- to worry about resizing the APM values, as this is handled inside the
- APM routines and is totally invisible to the user.
-
- The result of a APM operation cannot be one of the other APM operands.
- If you want this to be the case, you must put the result into a
- temporary variable and then assign it to the appropriate operand.
-
- All of the routines set the value of a global integer called
- "apm_errno" to an error status: 0 means the operation succeeded, > 0
- means there was a warning but that there still is a result, and < 0
- means there was an error which prohibited the operation from
- completing. Except where otherwise noted, the routines return this
- same status value.
-
- The caller has the option of registering a handler for errors and
- warnings. If this has been done, the handler will be invoked as each
- APM routine returns, and it will be passed appropriate information as
- to the status of the call to this APM routine. With a registered
- error handler it is not necessary for the caller to check the error
- code after each call to a APM routine.
-
- For ease of debugging, each APM routine is actually a macro that saves
- the file name and line number and then calls a function of a slightly
- different name. This allows the error handler to report the exact
- location of the APM operation which caused the error. The macros you
- will use have names of the form "apmRoutineName". To get the
- corresponding actual function name (say, when using a debugger),
- replace all capital letters with an underbar ("_") followed by its
- lower-case counterpart. For example, for a hypothetical routine
- called "apmRoutineName", the actual function will be named
- "apm_routine_name". You should never explicitly call the actual
- function.
-
- You should avoid using symbols that start with the characters "APM_"
- and "apm_", as they may clash with symbols that already exist in the
- APM Library.
-
- There is one routine for each basic arithmetic operation such as
- adding, subtracting, etc. This can become cumbersome when the result
- of a complicated expression is desired. Therefore, I have added a
- routine that will perform a series of operations in the manner of an
- RPN ("Reverse Polish Notation") calculator. See the routine 'apmCalc'
- (below) for more details.
-
- In my original version of this library, I discovered that a great deal
- of system overhead was wasted allocating and deallocating APM values.
- So, I adopted what has turned out to be a noticibly faster allocation
- scheme: newly allocated APM values are stored in a list. When the
- user disposes of one of these, it isn't really freed: its entry in the
- list is marked as unused. Subsequent attempts to allocate a new APM
- value will make use of any existing entries in this list that are
- marked as unused instead of allocating a new entry. Only when there
- are no unused entries in the list will a new entry be allocated.
- There is a routine that can be called which will perform a garbage
- collection: i.e., it actually frees all unused APM entries (see
- 'apmGarbageCollect', below).
-
- A file called apm.h must be included in all programs that use the APM
- routines. It defines the "APM" data type, the error codes, the
- apm_errno variable, and several other things.
-
- This software was written in as portable a manner as possible. I have
- gotten it running successfully under several environments: on a Sun
- 3/xxx using SunOS 3.5 and 4.0, on an IBM RT running under AIX, under
- MSDOS on an IBM PC using Microsoft C version 5.1 and Turbo C version
- 1.5 (or was it version 2.0?). There are two makefiles: the one called
- "Makefile" is the unix version ... it works under SunOS 3.5 and I
- presume it would be easy to alter it to work under other unix
- environments; the one called "makefile.msc" will build the library
- under MSDOS using Microsoft C version 5.1 ... it is meant to run with
- the make program "PC/MAKE".
-
- I'm sure that some of you will find ways of enhancing and speeding up
- the routines in this library. Time permitting, I will be doing that
- as well. I urge you to post your bug fixes and changes to the net and
- mail them to me at my address below, so they might be incorporated
- into a later version of this library. Some suggested areas of
- enhancement and optimization are:
-
- 1) Somehow speeding up the memory allocation scheme.
-
- 2) Some sort of floating-point/APM conversion. I left this out
- because of the widely varying floating-point formats that
- exist on the various machines these routines can and might run
- on, and because I intended APM to *replace* floating-point,
- not to work in conjunction with it.
-
- 3) Base conversion.
-
- 4) Roots, powers, logarithms, trig functions, exponential functions,
- etc.
-
- 5) More productions in the makefiles ("install", "rdist", etc.).
-
- 6) A fancy installation script.
-
- 7) Writing a man page for all this.
-