home *** CD-ROM | disk | FTP | other *** search
- :gdoc
- :frontm
- :titlep
- :title.Big Integer Package
- :author.Richard G. Larson
- :address
- :aline.170 N. Scoville Ave
- :aline. Oak Park, IL 60302
- :eaddress
- :date.28 June 1985
- :copyright 1985 "Richard G. Larson".
- :etitlep
- :toc
- :set tocnum 2
- :abstract
- :p.Datatypes which represent arbitrary precision integers are described.
- A set of functions written in C
- to create and manipulate arbitrary precision integers is described.
- This package is designed to be used with the CI C86 compiler,
- but effort has been made to make it transportable to other C compilers.
- :p.Permission is hereby granted to copy this manual and the
- associated programs for all non commercial purposes, provided that
- the copyright notice and this notice are also copied.
- This material may not be sold,
- nor may it be used in any program which is sold, without written
- permission from the author.
- :body
- :h1.Introduction.
- :p
- An arbitrary precision integer is represented as a variable size
- 2's-complement number.
- It is stored in a structure which includes a
- maximum size for the structure
- (in digits; a digit is an unsigned short), the current size,
- and the digits of the current number.
- The only limitations on the maximum size are the fact that the
- number of digits must be an integer, and the fact that the C library
- functions may limit the size of a single memory allocation.
- The type BIGINT is defined to be one of these structures.
- The type BIGINTP is defined to be a pointer to a BIGINT.
- Normally, all manipulation of arbitrary precision integers
- is done with variables of type BIGINTP.
- :p
- Functions (some of which are implemented as macros) are provided for
- the allocation of storage for integers, for copying integers,
- for conversion to and from ASCII strings, for conversion to and
- from longs,
- and for various arithmetic operations and comparisons
- on integers.
- :p
- The arbitrary precision functions are provided in libraries:
- BIARTHSN.LIB for small model programs to be used with
- an 8087 numeric coprocessor,
- BIARTHSS.LIB for small model programs to be used without
- an 8087,
- and BIARTHBN.LIB for big model programs to be used with
- an 8087.
- The C and ASM source for the functions is provided in BIARITH.ARC.
- In addition, two other files are provided:
- BIGINT.H, which defines the arbitrary precision integer structures
- and gives the necessary macro definitions,
- and SYSSTD.H, which contains some basic constant and type definitions.
- These files should be #included in any program using the library.
- This manual is provided in both a printable form (in BIGINT.LST)
- and with ReadiWriter formatting commands (in BIGINT.DOC).
- The C source files of the sample programs from the chapter Programming
- Examples are provided (in FACTOR.C and PRIME.C).
- :h1.Library Functions.
- In general, the parameters of the library functions are of type BIGINTP.
- The comparison functions return bool (TRUE/FALSE) values.
- Functions which perform operations are called with a pointer
- to the destination operand, in which the result is to be placed,
- and pointers to the source operands.
- These functions return a pointer to the destination operand
- if the operation was successfully performed,
- or NULL if the function was unable to perform the operation
- (usually because the destination did not have adequate space).
- The functions are all designed to return NULL if any
- parameter is NULL:
- this often will allow you to safely compose functions.
- (See the chapter entitled Programming Examples for samples of such usage.)
- In some cases, if the function returns NULL, the values of the source
- operands may have been changed.
- All operands are assumed to be expressed with the minimum number of
- digits necessary to give a valid 2's-complement representation;
- the answer is always returned in this minimum form.
- :p
- All function and macro names begin with "bi".
- In addition, the names of some internal functions and identifiers
- begin with "_bi".
- The user should avoid using names which begin with "_bi".
- :h2.bialloc, Allocate Space for a Big Integer
- :h3.Synopsis
- :xmp
-
- #include "bigint.h"
- BIGINTP bialloc(m)
- int m;
- :exmp
- :h3.Function/Returns/Notes
- :p
- Allocates space for an arbitrary precision integer with maximum size m digits,
- and initializes the field giving the maximum size.
- If m < 2, allocates space for a two digit number.
- Does not initialize the value of the arbitrary precision integer:
- using the value of an uninitialized arbitrary precision
- integer may have disasterous effects.
- Returns a pointer to the allocated arbitrary precision integer, or NULL if the
- function was unable to allocate sufficient space.
- (With CI-C86, an arbitrary precision
- integer with m digits occupies 4+2*m bytes.)
- Unused arbitrary precision integers may be freed using
- the standard function free().
- :h2.bisize, Current Size of a Big Integer
- :h3.Synopsis
- :xmp
-
- #include "bigint.h"
- int bisize(n)
- BIGINTP n;
- :exmp
- :h3.Function/Returns/Notes
- :p
- Returns the number of digits currently being used in the arbitrary
- precision integer pointed at by n.
- The value returned by bisize() may be used as a parameter for bialloc()
- to allocate an arbitrary precision integer just large enough to hold
- a copy of the integer pointed at by n.
- :p
- NOTE: bisize is implemented as a macro.
- The function bisize must not be declared.
- :h2.bicopy, Copy a Big Integer
- :h3.Synopsis
- :xmp
-
- #include "bigint.h"
- BIGINTP bicopy(p, q)
- BIGINTP p, q;
- :exmp
- :h3.Function/Returns/Notes
- :p
- Copies the arbitrary precision integer pointed at by q
- into the arbitrary precision integer pointed at by p.
- Returns p, or NULL if there was not enough space
- to make the copy.
- :h2.binumstr bistrnum, Conversion To/From String
- :h3.Synopsis
- :xmp
-
- #include "bigint.h"
- BIGINTP bistrnum(p,s)
- BIGINTP p;
- char *s;
-
- #include "bigint.h"
- char *binumstr(s,p)
- char *s;
- BIGINTP p;
- :exmp
- :h3.Function/Returns/Notes
- :p
- bistrnum places the number represented by the ASCII string
- pointed at by s into the arbitrary precision integer pointed at by p.
- Returns the pointer p, or NULL if there was not sufficient
- space in the arbitrary precision integer pointed at by p.
- Initial non numeric characters are skipped.
- Conversion continues until the first non digit is found,
- or the end of the string is reached.
- If the string contains no digits, 0 is put into the the integer
- pointed at by p.
- :p
- binumstr puts the ASCII string representing the number
- contained in the arbitrary precision integer pointed at by p into the
- string pointed at by s.
- The resulting ASCII string contains only decimal digits,
- and if the number is negative, an initial '-'.
- The string contains no blanks.
- It is terminated with the EOS character.
- The function returns s, or NULL if the function was unable to
- allocate sufficient temporary storage for scratch work.
- The programmer must make certain that the string pointed
- at by s contains sufficient space for the resulting number:
- the function cannot check this.
- :h2.binumlng bilngnum, Convert To/From Long
- :h3.Synopsis
- :xmp
-
- #include "bigint.h"
- long binumlng(p)
- BIGINTP p;
-
- #include "bigint.h"
- BIGINTP bilngnum(p,n)
- BIGINTP p;
- long n;
- :exmp
- :h3.Function/Returns/Notes
- :p
- binumlng converts the arbitrary precision integer pointed at by p to a long,
- and returns the long.
- If the number contained in the arbitrary precision integer
- will not fit into a long,
- the function returns the least significant portion of the
- 2's complement representation.
- :p
- bilngnum places the long n
- into the arbitrary precision integer pointed at by p.
- Returns p, or NULL if the arbitrary precision integer is not large enough.
- Note that the arbitrary precision integer must always be capable of holding
- at least two digits, even if the specific long would fit into
- a smaller arbitrary precision integer.
- Note that bialloc() always returns a pointer to a sufficiently
- large integer to hold a long.
- :h2.binumdbl, Convert To Double
- :h3.Synopsis
- :xmp
-
- #include "bigint.h"
- double binumdbl(p)
- BIGINTP p;
- :exmp
- :h3.Function/Returns/Notes
- :p
- binumdbl converts the arbitrary precision integer pointed at by p to a
- double,
- and returns the double.
- If the number contained in the arbitrary precision integer
- is to big to be represented as a double,
- the function returns infinity.
- :h2.bineg, Negate a Big Integer
- :h3.Synopsis
- :xmp
-
- #include "bigint.h"
- BIGINTP bineg(d, s)
- BIGINTP d, s;
- :exmp
- :h3.Function/Returns/Notes
- :p
- bineg puts the negative of the arbitrary precision
- integer pointed at by s into the arbitrary precision integer pointed at by d.
- Returns d, or NULL if the arbitrary precision integer
- pointed at by d is not large enough.
- :h2.biabs, Absolute Value of a Big Integer
- :h3.Synopsis
- :xmp
-
- #include "bigint.h"
- BIGINTP biabs(d, s)
- BIGINTP d, s;
- :exmp
- :h3.Function/Returns/Notes
- :p
- biabs puts the absolute value of the arbitrary precision integer
- pointed at by s into the arbitrary precision integer pointed at by d.
- Returns d, or NULL if the arbitrary precision integer pointed at by d
- is not large enough.
- :p
- NOTE: biabs is implemented as a macro using bineg and bicopy.
- The function biabs must not be declared.
- If it is used, the functions bineg and bicopy should be declared.
- :h2.biadd bisub, Add/Subtract Big Integers
- :h3.Synopsis
- :xmp
-
- #include "bigint.h"
- BIGINTP biadd(d, s1, s2)
- BIGINTP d, s1, s2;
-
- #include "bigint.h"
- BIGINTP bisub(d, s1, s2)
- BIGINTP d, s1, s2;
- :exmp
- :h3.Function/Returns/Notes
- :p
- biadd puts the sum of the arbitrary precision integers pointed at by s1 and s2
- into the arbitrary precision integer pointed at by d.
- Returns d, or NULL if there was not enough space in
- the arbitrary precision integer pointed at by d to do the sum.
- :p
- bisub puts the arbitrary precision integer pointed at by s2
- subtracted from the arbitrary precision integer
- pointed at by s1, into the arbitrary precision integer pointed at by d.
- Returns d, or NULL if there was not have enough space to do the subtraction.
- (NULL return can be caused by lack of space in the number
- pointed at by d, or by s2.)
- :h2.bimul, Multiply Big Integers
- :h3.Synopsis
- :xmp
-
- #include "bigint.h"
- BIGINTP bimul(d, s1, s2)
- BIGINTP d, s1, s2;
- :exmp
- :h3.Function/Returns/Notes
- :p
- bimul puts the product of the arbitrary precision integers
- pointed at by s1 and s2
- into the arbitrary precision integer pointed at by d.
- Returns d, or NULL if there was not enough space to do the multiplication.
- (NULL return can be caused by lack of space in any operand.)
- :h2.biquo, Quotient and Remainder of Big Integers
- :h3.Synopsis
- :xmp
-
- #include "bigint.h"
- BIGINTP bimul(d, s1, s2)
- BIGINTP d, s1, s2;
- :exmp
- :h3.Function/Returns/Notes
- :p
- biquo puts the integer quotient q of the arbitrary precision integers
- pointed at by s1 and s2
- into the arbitrary precision integer pointed at by d,
- and replaces the contents of the arbitrary precision integer
- pointed at by s1 with the remainder r.
- Returns d, or NULL if there was not enough space to do the division,
- or if division by 0 is attempted.
- If a is the integer pointed at by s1, and b is the integer pointed at by s2,
- then we have
- :xmp
- a = q*b + r
- :exmp
- with the sign of r the same as that of a,
- and the absolute value of r less than the absolute value of b.
- The sign of q is determined by the rules of algebra.
- :h2.bisqrt, Square Root of Big Integer
- :h3.Synopsis
- :xmp
-
- #include "bigint.h"
- BIGINTP bisqrt(d, s)
- BIGINTP d, s;
- :exmp
- :h3.Function/Returns/Notes
- :p
- bisqrt puts the floor of the square root of the arbitrary precision
- integer pointed at by s
- into the arbitrary precision integer pointed at by d.
- Returns d, or NULL if there was not enough space to do the computation,
- or if the square root of a negative number is computed.
- :h2.bilt bile bigt bige bieq bine, Numeric Comparison
- :h3.Synopsis
- :xmp
-
- #include "sysstd.h"
- #include "bigint.h"
-
- bool bilt(p, q)
- BIGINTP p, q;
-
- bool bile(p, q)
- BIGINTP p, q;
-
- bool bigt(p, q)
- BIGINTP p, q;
-
- bool bige(p, q)
- BIGINTP p, q;
-
- bool bieq(p, q)
- BIGINTP p, q;
-
- bool bine(p, q)
- BIGINTP p, q;
- :exmp
- :h3.Function/Returns/Notes
- :p
- bilt (bile, bigt, bige, bieq, bine) returns TRUE if
- the arbitrary precision integer
- pointed at by the first argument is less than (respectively
- less than or equal to,
- greater than, greater than or equal to, equal to, not equal to)
- the arbitrary precision integer pointed at by the second argument,
- and otherwise returns FALSE.
- :p
- NOTE: bile, bigt, bige are implemented as macros using bilt.
- The functions bile, bigt, bige must not be declared.
- If they are used, the function bilt should be declared.
- bine is implemented as a macro using bieq.
- The function bine must not be declared.
- If it is used, the function bieq should be declared.
- :h2.bilt0 bile0 bigt0 bige0 bieq0 bine0, 0-Comparison
- :h3.Synopsis
- :xmp
-
- #include "sysstd.h"
- #include "bigint.h"
-
- bool bilt0(p)
- BIGINTP p;
-
- bool bilet0(p)
- BIGINTP p;
-
- bool bigt0(p)
- BIGINTP p;
-
- bool bige0(p)
- BIGINTP p;
-
- bool bieq0(p)
- BIGINTP p;
-
- bool bine0(p)
- BIGINTP p;
- :exmp
- :h3.Function/Returns/Notes
- :p
- bilt0 (bile0, bigt0, bige0, bieq0, bine0) returns TRUE if its argument
- is less than 0 (respectively
- less than or equal to 0, greater than 0, greater than or equal to 0,
- equal to 0, not equal to 0),
- and otherwise returns FALSE.
- :p
- NOTE: The functions bilt0, bile0, bigt0, bige0, bieq0, and bine0
- are implemented as macros, and must not be declared.
- :h2.bieven biodd, Parity
- :h3.Synopsis
- :xmp
-
- #include "sysstd.h"
- #include "bigint.h"
-
- bool bieven(p)
- BIGINTP p;
-
- bool biodd(p)
- BIGINTP p;
- :exmp
- :h3.Function/Returns/Notes
- :p
- bieven returns TRUE if its argument is an even integer,
- and otherwise returns FALSE.
- :p
- biodd returns TRUE if its argument is an odd integer,
- and otherwise returns FALSE.
- :p
- NOTE: The functions bieven and biodd
- are implemented as macros, and must not be declared.
- :h1.Programming Examples.
- :p
- :h2.Prime Factorization
- :p
- Here is the standard small computer prime factorization program.
- You should note how the big integer package insulates you from
- specific questions of data representation.
- Also note the examples of function composition.
- :xmp
-
- /*
- * A demonstration program for the big integer package
- * which reads and factors integers.
- * R. G. Larson
- * 21 June 1984
- */
- #include "stdio.h"
- #include "sysstd.h"
- #include "bigint.h"
-
- #define STRSIZE 300 /* max size of ASCII string rep of number */
- #define NUMSIZE 65 /* max number of digits in number */
-
- main ()
- {
- BIGINTP bialloc(), bistrnum(), bilngnum(),
- bicopy(), bineg(), bimul(), biadd();
- bool bilt(), bieq();
-
- BIGINTP d, n, one, two, three, five, tmp, incr[8];
- char s[STRSIZE];
- int i;
-
- /* misc small constants */
- one = bilngnum(bialloc(2), 1L);
- two = bilngnum(bialloc(2), 2L);
- three = bilngnum(bialloc(2), 3L);
- five = bilngnum(bialloc(2), 5L);
-
- /* increments for the mod 30 trial divisor loop */
- incr[0] = bilngnum(bialloc(2), 4L);
- incr[1] = bilngnum(bialloc(2), 2L);
- incr[2] = bilngnum(bialloc(2), 4L);
- incr[3] = bilngnum(bialloc(2), 2L);
- incr[4] = bilngnum(bialloc(2), 4L);
- incr[5] = bilngnum(bialloc(2), 6L);
- incr[6] = bilngnum(bialloc(2), 2L);
- incr[7] = bilngnum(bialloc(2), 6L);
-
- tmp = bialloc(NUMSIZE);
- n = bialloc(NUMSIZE);
- d = bialloc(NUMSIZE);
-
- printf ("Enter number to factor: ");
- fgets (s, STRSIZE, stdin);
- /* n = abs(input) */
- if (!biabs(n, bistrnum(tmp, s)))
- abort("Input Error");
- while (bine0(n)) {
-
- trydiv (n, two);
- trydiv (n, three);
- trydiv (n, five);
- bilngnum (d, 7L);
- while (bile(bimul(tmp, d, d), n))
- for (i = 0; i < 8; i++) {
- trydiv (n, d);
- bicopy(d, biadd(tmp, d, incr[i]));
- }
- if (bine(n, one))
- putans (n, 1);
- printf ("Number factored.\n\n");
-
- printf ("Enter number to factor: ");
- fgets (s, STRSIZE, stdin);
- /* n = abs(input) */
- if (!biabs(n, bistrnum(tmp, s)))
- abort("Input Error");
- }
- }
-
- void trydiv (n, d)
- BIGINTP n, d;
- {
- BIGINTP bialloc(), bicopy(), biquo();
- static BIGINTP x, y;
- static bool first_time = TRUE;
- int exp = 0;
-
- if (first_time) {
- x = bialloc(NUMSIZE);
- y = bialloc(NUMSIZE);
- first_time = FALSE;
- }
- bicopy(x, n);
- biquo(y, x, d);
- while (bieq0(x)) {
- exp++;
- bicopy(n, y);
- bicopy(x, y);
- biquo(y, x, d);
- }
- if (exp)
- putans (d, exp);
- }
-
- void putans (d, e)
- BIGINTP d;
- int e;
- {
- char *binumstr();
- char s[STRSIZE];
-
- binumstr(s, d);
- printf ("Factor: %s ^ %d\n", s, e);
- }
- :exmp
- :h2.Primality Testing
- :p
- This program factors out small divisors from a number,
- and then applies the strong pseudoprime test to the remaining factor
- twenty times.
- If it fails the strong pseudoprime test once, the number is composite.
- If it passes it twenty times, it is almost certainly prime.
- :xmp
-
- /*
- * A program which removes small prime factors, and then
- * applies the strong pseudo prime test to the remaining factor
- * R. G. Larson
- * 23 June 1985
- */
- #include "stdio.h"
- #include "sysstd.h"
- #include "bigint.h"
-
- #define STRSIZE 300 /* max size of ASCII string rep of number */
- #define NUMSIZE 65 /* max number of digits in number */
- #define DIVLIM 10000 /* limit for small divisors */
-
- extern BIGINTP bialloc(), bimul(), biquo(), bicopy(), bilngnum(),
- bicopy(), bisub(), bistrnum(), bineg(), biadd();
- extern bool bilt(), bieq();
- extern char *binumstr();
-
- void sqmod (l, n)
- BIGINTP l, n;
- /*
- * Sets l to l**2 (mod n)
- */
- {
- BIGINTP tmp1, tmp2;
- int s;
-
- s = bisize(n);
- tmp1 = bialloc(2 * s + 2);
- tmp2 = bialloc(s + 2);
- bimul(tmp1, l, l);
- /* l = tmp1 (mod n) */
- biquo(tmp2, tmp1, n);
- bicopy(l, tmp1);
- free(tmp1);
- free(tmp2);
- }
-
- void expmod (l, a, e, n)
- BIGINTP l, a, e, n;
- /*
- * Sets l = a**e (mod n)
- */
- {
- static bool first_time = TRUE;
- static BIGINTP two;
-
- BIGINTP atmp, etmp, tmp1, tmp2;
- int s;
-
- if (first_time) {
- first_time = FALSE;
- two = bilngnum(bialloc(2), (long) 2);
- }
-
- s = bisize(n);
- atmp = bialloc(s + 2);
- etmp = bialloc(s + 2);
- tmp1 = bialloc(2 * s + 2);
- tmp2 = bialloc(s + 2);
- bicopy(atmp, a);
- bicopy(etmp, e);
- bilngnum(l, (long) 1);
- while (bigt0(etmp)) {
- if (biodd(etmp)) {
- bimul(tmp1, l, atmp);
- biquo(tmp2, tmp1, n);
- bicopy(l, tmp1);
- }
- sqmod(atmp, n);
- biquo(etmp, bicopy(tmp2, etmp), two);
- }
- free(atmp);
- free(etmp);
- free(tmp1);
- free(tmp2);
- }
-
- bool prime (n, a)
- BIGINTP n, a;
- /*
- * Test if n passes strong pseudo prime test with powers of a.
- */
- {
- static bool first_time = TRUE;
- static BIGINTP one, two;
-
- BIGINTP k, l, tmp, minus_one;
- int e, s;
-
- if (first_time) {
- first_time = FALSE;
- one = bilngnum(bialloc(2), (long) 1);
- two = bilngnum(bialloc(2), (long) 2);
- }
-
- s = bisize(n);
- tmp = bialloc(s + 2);
- k = bialloc(s + 2);
- l = bialloc(s + 2);
- minus_one = bialloc(s + 2);
- bisub(k, n, one);
- bicopy(minus_one, k); /* n - 1 */
- e = 0;
- while (bieven(k)) {
- e++;
- biquo(k, bicopy(tmp, k), two);
- }
- expmod(l, a, k, n);
- if (bieq(l, one) | bieq(l, minus_one)) {
- free(tmp);
- free(k);
- free(l);
- free(minus_one);
- return (TRUE);
- }
- /* here l = a ** (odd part of n-1) , and not +/-1 */
- for (e--; e > 0; e--) {
- sqmod(l, n);
- if (bieq(l, minus_one)) {
- free(tmp);
- free(k);
- free(l);
- free(minus_one);
- return (TRUE);
- }
- if (bieq(l, one)) {
- free(tmp);
- free(k);
- free(l);
- free(minus_one);
- return (FALSE);
- }
- }
- free(tmp);
- free(k);
- free(l);
- free(minus_one);
- return (FALSE);
- }
-
- bool primetest(n)
- BIGINTP n;
- /*
- * Does strong pseudo prime test on n
- */
- {
- static bool first_time = TRUE;
- static BIGINTP na;
- static int a[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 27, 0};
-
- int i;
-
- if (first_time) {
- first_time = FALSE;
- na = bialloc(2);
- }
- for (i = 0; a[i]; i++) {
- bilngnum(na, (long) a[i]);
- if (!prime(n, na))
- return (FALSE);
- }
- return (TRUE);
- }
-
- void trydiv (n, d)
- BIGINTP n, d;
- {
- static BIGINTP x = NULL,
- y = NULL;
- static int xymax = 0;
- int exp = 0;
-
- if (bisize(n) + 2 > xymax) {
- xymax = bisize(n) + 2;
- if (x)
- free(x);
- x = bialloc(xymax);
- if (y)
- free(y);
- y = bialloc(xymax);
- }
- bicopy(x, n);
- biquo(y, x, d);
- while (bieq0(x)) {
- exp++;
- bicopy(n, y);
- bicopy(x, y);
- biquo(y, x, d);
- }
- if (exp)
- putans (d, exp);
- }
-
- void putans (d, e)
- BIGINTP d;
- int e;
- {
- char s[STRSIZE];
-
- binumstr(s, d);
- printf ("Factor: %s ^ %d\n", s, e);
- }
-
- main ()
- {
- /* the increments for the mod 30 trial divisors: */
- static int incr[] = {4, 2, 4, 2, 4, 6, 2, 6};
-
- BIGINTP nd, n, one, two, three, five, tmp;
- char s[STRSIZE];
- long d;
- int i;
- bool test;
-
- /* misc small constants */
- one = bilngnum(bialloc(2), 1L);
- two = bilngnum(bialloc(2), 2L);
- three = bilngnum(bialloc(2), 3L);
- five = bilngnum(bialloc(2), 5L);
-
- tmp = bialloc(NUMSIZE);
- n = bialloc(NUMSIZE);
- nd = bialloc(NUMSIZE);
-
- printf ("Enter number to test: ");
- fgets (s, STRSIZE, stdin);
- /* n = abs(input) */
- if (!biabs(n, bistrnum(tmp, s)))
- abort("Input Error");
-
- while (bine0(n)) {
- trydiv (n, two);
- trydiv (n, three);
- trydiv (n, five);
- d = 7L;
- while ((test = bile(bilngnum(tmp, (long) d * d), n)) &&
- (d <= DIVLIM))
- for (i = 0; i < 8; i++) {
- bilngnum(nd, d);
- trydiv (n, nd);
- d += (long) incr[i];
- }
- if (bieq(n, one))
- printf ("Number factored.\n\n");
- else if (!test) {
- putans(n, 1);
- printf ("Number factored.\n\n");
- }
- else {
- binumstr(s, n);
- printf ("Remaining factor: %s ", s);
- if (primetest(n))
- printf ("is probably prime.\n\n");
- else
- printf ("is composite.\n\n");
- }
-
- printf ("Enter number to test: ");
- fgets (s, STRSIZE, stdin);
- /* n = abs(input) */
- if (!biabs(n, bistrnum(tmp, s)))
- abort("Input Error");
- }
- }
- :exmp
- :h1.Installation Notes.
- :p
- The libraries BIARTHSN.LIB, BIARTHSS.LIB, and BIARTHBN.LIB
- have been compiled with Computer Innovations' C86 compiler, version
- 2.20J.
- :p
- In addition to the code for the
- multi-precision integer arithmetic package, the libraries also include
- code which
- replaces two modules in the standard CI-C86 libraries.
- The modules ZLDIVMOD and ZLMUL will be linked into the final EXE file
- instead of the corresponding modules from the CI-C86 Version 2.20
- library.
- If you are using another version of the CI-C86 libraries,
- you should compare the source code of these modules (in BIARITH.ARC)
- with the source code of the corresponding CI-C86 module:
- these modules contain internal functions with non standard linkage
- conventions.
- These linkage conventions could differ in different versions.
- Note that the BIARITH version of ZLDIVMOD requires an 8087.
- If in doubt, you can remove ZLDIVMOD and ZLMUL from the library.
- However, you will pay a severe speed penalty if you use the CI-C86
- version of ZLDIVMOD.
- :p
- Some functions in BIARITH.ARC are provided in both a C and an ASM file.
- In this case, the ASM file is a faster version of the C file.
- You should use the ASM version, if possible.
- Using the two replacements for the CI-C86 library modules and the
- three assembly language functions provided, instead of the CI-C86
- modules and the C versions of the functions speeded
- up the program PRIME given in section 3.2 by more than a factor of 3.
- :p
- If you need another version of the library,
- you will need to recreate it from the source in
- BIARITH.ARC.
- All of the C files are written in "generic" C.
- They should be usable to create versions of the libraries for
- other compilers.
- The ASM files for the replacements for the modules
- in the C86 library are also provided.
- :egdoc
- i