Compare commits

...

12 Commits

Author SHA1 Message Date
Landon Curt Noll
f42a003d04 Improve formatting of comments in cal/lucas.cal 2018-01-16 15:33:00 -08:00
Landon Curt Noll
8da0471f07 Release calc version 2.12.6.4
Fixed a man page warning about ./myfile where the leading dot
was mistook for an nroff macro.  Thanks goes to David Haller
<dnh at opensuse dot org> for providing the patch.

Improved gen_v1(h,n) in lucas.cal for cases where h is not a
multiple of 3. Optimized the search for v(1) when h is a
multiple of 3.

Fixed a Makefile problem, reported by Doug Hays <doughays6 at gmail
dot com>, where if a macOS user set BINDIR, LIBDIR, CALC_SHAREDIR
or INCDIR in the top section, their values will be overwritten by
the Darwin specific section.
2018-01-16 15:27:13 -08:00
Landon Curt Noll
1c20261b93 Fixed macro warning about ./myfile 2017-09-07 14:28:54 -07:00
Landon Curt Noll
aeb9a9d473 Prepare for calc version 2.12.6.3 2017-09-06 18:20:35 -07:00
Landon Curt Noll
66883b390d Fixed CHANGES typo 2017-09-06 18:11:35 -07:00
Landon Curt Noll
ea533659ce Release calc version 2.12.6.2 2017-09-06 17:42:41 -07:00
Landon Curt Noll
9e81971f25 Verify that h*2^n-1 is not a multiple of 3 2017-09-06 17:41:56 -07:00
Landon Curt Noll
cbbd866535 Fixed a misleading indent reported by Thomas Walter 2017-09-06 17:40:49 -07:00
Landon Curt Noll
bf23f82c29 Correct comments relating to v(1) search table 2017-06-18 08:11:43 -07:00
Landon Curt Noll
ec5c584785 Fixed typo in lucas.cal comment 2017-06-18 04:11:44 -07:00
Landon Curt Noll
6bbb8c0e42 Update v(1) stats with full 1000000 test sample 2017-06-18 03:50:28 -07:00
Landon Curt Noll
438554b0ed Make a minor speedup to gen_v1(h,n) in lucas.cal 2017-06-14 16:50:58 -07:00
8 changed files with 397 additions and 191 deletions

16
CHANGES
View File

@@ -6,6 +6,22 @@ The following are the changes from calc version 2.12.6.1 to date:
integers >= 1. In the case of both rodseth_xhn(x, h, n) and gen_v1(h, n)
h must be odd.
Fixed an C code indenting issue that was reported by Thomas Walter
<th dot walter42 at gmx dot de> in zfunc.c.
Fixed a man page warning about ./myfile where the leading dot
was mistook for an nroff macro. Thanks goes to David Haller
<dnh at opensuse dot org> for providing the patch.
Improved gen_v1(h,n) in lucas.cal for cases where h is not a
multiple of 3. Optimized the search for v(1) when h is a
multiple of 3.
Fixed a Makefile problem, reported by Doug Hays <doughays6 at gmail
dot com>, where if a macOS user set BINDIR, LIBDIR, CALC_SHAREDIR
or INCDIR in the top section, their values will be overwritten by
the Darwin specific section.
The following are the changes from calc version 2.12.6.0 to 2.12.6.0:

View File

@@ -23,7 +23,7 @@
# READLINE_LIB= -lreadline
# READLINE_EXTRAS= -lhistory -lncurses
#
# Copyright (C) 1999-2017 Landon Curt Noll
# Copyright (C) 1999-2018 Landon Curt Noll
#
# Calc is open software; you can redistribute it and/or modify it under
# the terms of version 2.1 of the GNU Lesser General Public License
@@ -564,14 +564,30 @@ HAVE_UNUSED=
#
# INCDIR= /dev/env/DJDIR/include
#
# If in doubt, set:
# If in doubt, for non-macOS hosts set:
#
# INCDIR= /usr/include
#
# However, if you are on macOS then set:
#
# INCDIR= /usr/local/include
#if 0 /* start of skip for non-Gnu makefiles */
ifeq ($(target),Darwin)
# default INCDIR for macOS
INCDIR= /usr/local/include
else
#endif /* end of skip for non-Gnu makefiles */
# default INCDIR for non-macOS
INCDIR= /usr/include
#INCDIR= /usr/local/include
#INCDIR= /dev/env/DJDIR/include
INCDIR= /usr/include
#if 0 /* start of skip for non-Gnu makefiles */
endif
#endif /* end of skip for non-Gnu makefiles */
# Where to install calc related things
#
@@ -602,23 +618,71 @@ INCDIR= /usr/include
# LIBDIR= /dev/env/DJDIR/lib
# CALC_SHAREDIR= /dev/env/DJDIR/share/calc
#
# If in doubt, set:
# If in doubt, for non-macOS hosts set:
#
# BINDIR= /usr/bin
# LIBDIR= /usr/lib
# CALC_SHAREDIR= /usr/share/calc
#
# However, if you are on macOS then set:
#
# BINDIR= /usr/local/bin
# LIBDIR= /usr/local/lib
# CALC_SHAREDIR= /usr/local/share/calc
#
# NOTE: Starting with macOS El Capitan OS X 10.11, root by default
# could not mkdir under system locations, so macOS must now
# use the /usr/local tree.
#if 0 /* start of skip for non-Gnu makefiles */
ifeq ($(target),Darwin)
# default BINDIR for macOS
BINDIR= /usr/local/bin
else
#endif /* end of skip for non-Gnu makefiles */
# default BINDIR for non-macOS
BINDIR= /usr/bin
#BINDIR= /usr/local/bin
#BINDIR= /dev/env/DJDIR/bin
BINDIR= /usr/bin
#if 0 /* start of skip for non-Gnu makefiles */
endif
ifeq ($(target),Darwin)
# default LIBDIR for macOS
LIBDIR= /usr/local/lib
else
#endif /* end of skip for non-Gnu makefiles */
# default LIBDIR for non-macOS
LIBDIR= /usr/lib
#LIBDIR= /usr/local/lib
#LIBDIR= /dev/env/DJDIR/lib
LIBDIR= /usr/lib
#if 0 /* start of skip for non-Gnu makefiles */
endif
ifeq ($(target),Darwin)
# default CALC_SHAREDIR for macOS
CALC_SHAREDIR= /usr/local/share/calc
else
#endif /* end of skip for non-Gnu makefiles */
# default CALC_SHAREDIR for non-macOS
CALC_SHAREDIR= /usr/share/calc
#CALC_SHAREDIR= /usr/local/lib/calc
#CALC_SHAREDIR= /dev/env/DJDIR/share/calc
CALC_SHAREDIR= /usr/share/calc
#if 0 /* start of skip for non-Gnu makefiles */
endif
#endif /* end of skip for non-Gnu makefiles */
# NOTE: Do not set CALC_INCDIR to /usr/include or /usr/local/include!!!
# Always be sure that the CALC_INCDIR path ends in /calc to avoid
@@ -990,7 +1054,7 @@ EXT=
# The default calc versions
#
VERSION= 2.12.6.1
VERSION= 2.12.6.4
# Names of shared libraries with versions
#
@@ -1263,16 +1327,6 @@ LDCONFIG:=
# DARWIN_ARCH= -arch ppc # PPC binary
# DARWIN_ARCH= -arch x86_64 # native 64-bit binary
DARWIN_ARCH= # native binary
#
# Starting with El Capitan OS X 10.11, root by default could not
# mkdir under system locations, so we now use the /usr/local tree.
#
OPTDIR:= /usr/local
BINDIR:= /${OPTDIR}/bin
LIBDIR:= /${OPTDIR}/lib
CALC_SHAREDIR:= /${OPTDIR}/share
CALC_INCDIR:= /${OPTDIR}/include
SCRIPTDIR:= ${BINDIR}/cscript
endif
##################

View File

@@ -28,6 +28,10 @@
* For a general tutorial on how to find a new largest known prime, see:
*
* http://www.isthe.com/chongo/tech/math/prime/prime-tutorial.pdf
*
* Also see the reference code, available both C and go:
*
* https://github.com/arcetri/goprime
*/
/*
@@ -154,6 +158,12 @@
*
* Finally, one should eliminate all values of 'h*2^n-1' where
* 'h*2^n+1' is divisible by a small primes.
*
* NOTE: Today, for world record sized h*2^n-1 primes, one might
* search for factors < 2^46 or more. By excluding h*2^n-1
* with prime factors < 2^46, where h*2^n-1 is a bit larger
* than the largest known prime, one may exclude about 96.5%
* of candidates that have "small" prime factors.
*/
pprod256 = 0; /* product of "primes up to 256" / "primes up to 46" */
@@ -739,7 +749,7 @@ rodseth_xhn(x, h, n)
* We can show that X > 2. See the comments in the rodseth_xhn(x,h,n) above.
*
* Some values of X satisfy more often than others. For example a large sample
* of odd h, h odd multiple of 3 and large n (some around 1e4, some near 1e6,
* of h*2^n-1, h odd multiple of 3, and large n (some around 1e4, some near 1e6,
* others near 3e7) where the sample size was 66 973 365, here is the count of
* the smallest value of X that satisfies conditions in Ref4, condition 1:
*
@@ -805,82 +815,155 @@ rodseth_xhn(x, h, n)
*
* The above distribution was found to hold fairly well over many values of
* odd h that are also a multiple of 3 and for many values of n where h < 2^n.
* For example for in a sample size of 835823 numbers of the form h*2^n-1
* where odd h >= 12996351 is a multiple of 3, n >= 12996351, these are the
* smallest v(1) values that were found:
*
* smallest percentage
* v(1) used
* -------------------
* 3 40.000%
* 5 25.683%
* 9 11.693%
* 11 10.452%
* 15 4.806%
* 17 2.348%
* 21 1.656%
* 29 1.281%
* 27 0.6881%
* 35 0.4536%
* 39 0.3121%
* 41 0.1760%
* 31 0.1414%
* 45 0.1173%
* 51 0.05576%
* 55 0.03300%
* 49 0.03185%
* 59 0.02090%
* 69 0.00980%
* 65 0.009367%
* 71 0.007205%
* 57 0.006341%
* 85 0.004611%
* 81 0.004179%
* 95 0.002882%
* 99 0.001873%
* 77 0.001153%
* 53 0.0007205%
* 67 0.0005764%
* 125 0.0005764%
* 105 0.0005764%
* 87 0.0004323%
* 111 0.0004323%
* 101 0.0002882%
* 83 0.0001441%
* 127 0.0001196%
* For example for in a sample size of 1000000 numbers of the form h*2^n-1
* where h is an odd multiple of 3, 12996351 <= h <= 13002351,
* 4331116 <= n <= 4332116, these are the smallest v(1) values that were found:
*
* When h * 2^n-1 is prime and h is an odd multiple of 3, a smallest v(1) that
* is even is extremely rate. Of the list of 127287 known primes of the form
* h*2^n-1 when h was a multiple of 3, none has an smallest v(1) that was even.
* smallest percentage
* v(1) used
* -------- ---------
* 3 40.0000 %
* 5 25.6833 %
* 9 11.6924 %
* 11 10.4528 %
* 15 4.8048 %
* 17 2.3458 %
* 21 1.3734 %
* 29 1.0527 %
* 20 0.8595 %
* 27 0.5758 %
* 35 0.4420 %
* 36 0.2433 %
* 39 0.1779 %
* 41 0.0885 %
* 45 0.0571 %
* 32 0.0337 %
* 51 0.0289 %
* 44 0.0205 %
* 49 0.0176 %
* 56 0.0137 %
* 59 0.0108 %
* 57 0.0053 %
* 65 0.0047 %
* 55 0.0045 %
* 69 0.0031 %
* 71 0.0024 %
* 66 0.0011 %
* 95 0.0008 %
* 81 0.0008 %
* 77 0.0006 %
* 72 0.0005 %
* 99 0.0004 %
* 80 0.0003 %
* 74 0.0003 %
* 84 0.0002 %
* 67 0.0002 %
* 87 0.0001 %
* 104 0.0001 %
* 129 0.0001 %
*
* About 1 out of 835000 cases when h is a multiple of 3 use v(1) > 127 as the
* smallest value of v(1).
* However, a case can be made for considering only odd values for v(1)
* candidates. When h * 2^n-1 is prime and h is an odd multiple of 3,
* a smallest v(1) that is even is extremely rate. Of the list of 146553
* known primes of the form h*2^n-1 when h is an odd a multiple of 3,
* none has an smallest v(1) that was even.
*
* See:
*
* https://github.com/arcetri/verified-prime
*
* for that list of 146553 known primes of the form h*2^n-1.
*
* That same example for in a sample size of 1000000 numbers of the
* form h*2^n-1 where h is an odd multiple of 3, 12996351 <= h <= 13002351,
* 4331116 <= n <= 4332116, these are the smallest odd v(1) values that were
* found:
*
* smallest percentage
* odd v(1) used
* -------- ---------
* 3 40.0000 %
* 5 25.6833 %
* 9 11.6924 %
* 11 10.4528 %
* 15 4.8048 %
* 17 2.3458 %
* 21 1.6568 %
* 29 1.6174 %
* 35 0.4529 %
* 27 0.3546 %
* 39 0.3470 %
* 41 0.2159 %
* 45 0.1173 %
* 31 0.0661 %
* 51 0.0619 %
* 55 0.0419 %
* 59 0.0250 %
* 49 0.0170 %
* 69 0.0110 %
* 65 0.0098 %
* 71 0.0078 %
* 85 0.0048 %
* 81 0.0044 %
* 95 0.0038 %
* 99 0.0021 %
* 125 0.0009 %
* 57 0.0007 %
* 111 0.0005 %
* 77 0.0003 %
* 165 0.0003 %
* 155 0.0002 %
* 129 0.0002 %
* 101 0.0002 %
* 53 0.0001 %
*
* Moreover when evaluating odd candidates for v(1), one may cache Jacobi
* symbol evaluations to reduce the number of Jacobi symbol evaluations to
* a minimum. For example, if one tests 5 and finds that the 2nd case fails:
*
* jacobi(5+2, h*2^n-1) != -1
*
* Then if one is later testing 9, the Jacobi symbol value for the first
* 1st case:
*
* jacobi(7-2, h*2^n-1)
*
* is already known.
*
* Without Jacobi symbol value caching, it requires on average
* 4.851377 Jacobi symbol evaluations. With Jacobi symbol value caching
* cacheing, an averare of 4.348820 Jacobi symbol evaluations is needed.
*
* Given this information, when odd h is a multiple of 3 we try, in order,
* these sorted values of X:
* these odd values of X:
*
* 3, 5, 9, 11, 15, 17, 21, 27, 29, 31, 35, 39, 41, 45, 49, 51, 53, 55,
* 57, 59, 65, 67, 69, 71, 77, 81, 83, 85, 87, 95, 99, 101, 105, 111, 125
* 3, 5, 9, 11, 15, 17, 21, 29, 27, 35, 39, 41, 31, 45, 51, 55, 49, 59,
* 69, 65, 71, 57, 85, 81, 95, 99, 77, 53, 67, 125, 111, 105, 87, 129,
* 101, 83, 165, 155, 149, 141, 121, 109
*
* And stop on the first value of X where:
*
* jacobi(X-2, h*2^n-1) == 1
* jacobi(X+2, h*2^n-1) == -1
*
* If no value in that list works, we start simple search starting with X = 12/
* Less than 1 case out of 1000000 will not be satisifed by the above list.
* If no value in that list works, we start simple search starting with X = 167
* and incrementing by 2 until a value of X is found.
*
* The x_tbl[] matrix contains those common values of X to try in order.
* If all x_tbl_len fail to satisfy Ref4 condition 1, then we begin a
* linear search at next_x until we find a proper X value.
* The x_tbl[] matrix contains those values of X to try in order.
* If all x_tbl_len fail to satisfy Ref4 condition 1 (this happens less than
* 1 in 1000000 cases), then we begin a linear search of odd values starting at
* next_x until we find a proper X value.
*/
x_tbl_len = 35;
x_tbl_len = 42;
mat x_tbl[x_tbl_len];
x_tbl = {
3, 5, 9, 11, 15, 17, 21, 27, 29, 31, 35, 39, 41, 45, 49, 51, 53, 55,
57, 59, 65, 67, 69, 71, 77, 81, 83, 85, 87, 95, 99, 101, 105, 111, 125
3, 5, 9, 11, 15, 17, 21, 29, 27, 35, 39, 41, 31, 45, 51, 55, 49, 59,
69, 65, 71, 57, 85, 81, 95, 99, 77, 53, 67, 125, 111, 105, 87, 129,
101, 83, 165, 155, 149, 141, 121, 109
};
next_x = 127;
next_x = 167; /* must be 2 more than the largest value in x_tbl[] */
/*
* gen_v1 - compute the v(1) for a given h*2^n-1 if we can
@@ -938,12 +1021,22 @@ next_x = 127;
*
* u(2) = v(h) (NOTE: some call this u(2))
*
* so we simply return
* so we can always return
*
* v(1) = alpha^1 + alpha^(-1)
* = (2+sqrt(3)) + (2-sqrt(3))
* = 4
*
* In 40% of the cases when h is not a multiple of 3, 3 is a valid value
* for v(1). We can test if 3 is a valid value for v(1) in this case:
*
* if jacobi(1, h*2^n-1) == 1 and jacobi(5, h*2^n-1) == -1, then
* v(1) = 3
* else
* v(1) = 4
*
* HOTE: The above "if then else" works only of h is not a multiple of 3.
*
***
*
* Case 2: (h mod 3 == 0)
@@ -1039,13 +1132,18 @@ next_x = 127;
* n n as in h*2^n-1 (must be >= 1)
*
* output:
* returns v(1), or -1 is there is no quick way
* returns v(1), or
* -1 when h*2^n-1 is a multiple of 3
*/
define
gen_v1(h, n)
{
local x; /* potential v(1) to test */
local i; /* x_tbl index */
local v1m2; /* X-2 1st case */
local v1p2; /* X+2 2nd case */
local testval; /* h*2^n-1 - value we are testing if prime */
local mat cached_v1[next_x]; /* cached Jacobi symbol values or 0 */
/*
* check arg types
@@ -1066,18 +1164,36 @@ gen_v1(h, n)
quit "bad args: n must be an integer >= 1";
}
/*
* pretest: Verify that h*2^n-1 is not a multiple of 3
*/
if (((h % 3 == 1) && (n % 2 == 0)) || ((h % 3 == 2) && (n % 2 == 1))) {
/* no need to test h*2^n-1, it is not prime */
return -1;
}
/*
* check for Case 1: (h mod 3 != 0)
*/
if (h % 3 != 0) {
/* v(1) is easy to compute */
return 4;
if (rodseth_xhn(3, h, n) == 1) {
/* 40% of the time, 3 works when h mod 3 != 0 */
return 3;
} else {
/* otherwise 4 always works when h mod 3 != 0 */
return 4;
}
}
/*
* What follow is Case 2: (h mod 3 == 0)
*/
/*
* clear cache
*/
matfill(cached_v1, 0);
/*
* We will look for x that satisfies conditions in Ref4, condition 1:
*
@@ -1089,26 +1205,51 @@ gen_v1(h, n)
* to the next odd value, the now jacobi(X-2, h*2^n-1)
* does not need to be re-evaluted.
*/
testval = h*2^n-1;
for (i=0; i < x_tbl_len; ++i) {
/*
* test Ref4 condition 1:
* obtain the next test candidate
*/
x = x_tbl[i];
if (rodseth_xhn(x, h, n) == 1) {
/*
* found a x that satisfies Ref4 condition 1
*/
ldebug("gen_v1", "h= " + str(h) + " n= " + str(n) +
" v1= " + str(x) + " using tbl[ " +
str(i) + " ]");
return x;
/*
* Check x for condition 1 part 1
*
* jacobi(x-2, h*2^n-1) == 1
*/
v1m2 = x-2;
if (cached_v1[v1m2] == 0) {
cached_v1[v1m2] = jacobi(v1m2, testval);
}
if (cached_v1[v1m2] != 1) {
continue;
}
/*
* Check x for condition 1 part 2
*
* jacobi(x+2, h*2^n-1) == -1
*/
v1p2 = x+2;
if (cached_v1[v1p2] == 0) {
cached_v1[v1p2] = jacobi(v1p2, testval);
}
if (cached_v1[v1p2] != -1) {
continue;
}
/*
* found a x that satisfies Ref4 condition 1
*/
ldebug("gen_v1", "h= " + str(h) + " n= " + str(n) +
" v1= " + str(x) + " using tbl[ " +
str(i) + " ]");
return x;
}
/*
* We are in that rare case (about 1 in 835 000) where none of the
* We are in that rare case (less than 1 in 1 000 000) where none of the
* common X values satisfy Ref4 condition 1. We start a linear search
* of odd vules at next_x from here on.
*/

View File

@@ -657,8 +657,8 @@ searches in succession:
.sp 1
.in +5n
.nf
./myfile
./myfile.cal
\a./myfile
\a./myfile.cal
${LIBDIR}/myfile
${LIBDIR}/myfile.cal
${CUSTOMCALDIR}/myfile

View File

@@ -348,7 +348,7 @@ EXT=
# The default calc versions
#
VERSION= 2.12.6.1
VERSION= 2.12.6.4
# Names of shared libraries with versions
#
@@ -628,16 +628,6 @@ LDCONFIG:=
# DARWIN_ARCH= -arch ppc # PPC binary
# DARWIN_ARCH= -arch x86_64 # native 64-bit binary
DARWIN_ARCH= # native binary
#
# Starting with El Capitan OS X 10.11, root by default could not
# mkdir under system locations, so we now use the /usr/local tree.
#
OPTDIR:= /usr/local
BINDIR:= /${OPTDIR}/bin
LIBDIR:= /${OPTDIR}/lib
CALC_SHAREDIR:= /${OPTDIR}/share
CALC_INCDIR:= /${OPTDIR}/include
SCRIPTDIR:= ${BINDIR}/cscript
endif
##################

View File

@@ -348,7 +348,7 @@ EXT=
# The default calc versions
#
VERSION= 2.12.6.1
VERSION= 2.12.6.4
# Names of shared libraries with versions
#

View File

@@ -45,7 +45,7 @@ static char *program;
#define MAJOR_VER 2 /* major library version */
#define MINOR_VER 12 /* minor library version */
#define MAJOR_PATCH 6 /* major software level under library version */
#define MINOR_PATCH 1 /* minor software level or 0 if not patched */
#define MINOR_PATCH 4 /* minor software level or 0 if not patched */
/*

175
zfunc.c
View File

@@ -1029,93 +1029,98 @@ zgcd(ZVALUE z1, ZVALUE z2, ZVALUE *res)
needw = FALSE;
}
g = *a0 * w;
if (h < BASEB) g &= (1 << h) - 1;
else g &= BASE1;
if (h < BASEB) {
g &= (1 << h) - 1;
} else {
g &= BASE1;
}
} else {
g = 1;
}
else g = 1;
} else
} else {
g = (HALF) *a0 * w;
a = a0;
b = b0;
i = n;
if (g > 1) { /* a - g * b case */
f = 0;
while (i--) {
f = (FULL) *a - g * *b++ - f;
*a++ = (HALF) f;
f >>= BASEB;
f = -f & BASE1;
}
if (f) {
i = m - n;
while (i-- && f) {
f = *a - f;
*a++ = (HALF) f;
f >>= BASEB;
f = -f & BASE1;
}
}
while (m && !*a0) { /* Removing trailing zeros */
m--;
a0++;
}
if (f) { /* a - g * b < 0 */
while (m > 1 && a0[m-1] == BASE1) m--;
*a0 = - *a0;
a = a0;
i = m;
while (--i) {
a++;
*a = ~*a;
}
}
} else { /* abs(a - b) case */
while (i && *a++ == *b++) i--;
q = n - i;
if (m == n) { /* a and b same length */
if (i) { /* a not equal to b */
while (m && a0[m-1] == b0[m-1]) m--;
if (a0[m-1] < b0[m-1]) {
/* Swapping since a < b */
a = a0;
a0 = b0;
b0 = a;
k = j;
}
a = a0 + q;
b = b0 + q;
i = m - q;
f = 0;
while (i--) {
f = (FULL) *a - *b++ - f;
*a++ = (HALF) f;
f >>= BASEB;
f = -f & BASE1;
}
}
} else { /* a has more digits than b */
a = a0 + q;
b = b0 + q;
i = n - q;
f = 0;
while (i--) {
f = (FULL) *a - *b++ - f;
*a++ = (HALF) f;
f >>= BASEB;
f = -f & BASE1;
}
if (f) { while (!*a) *a++ = BASE1;
(*a)--;
}
}
a0 += q;
m -= q;
while (m && !*a0) { /* Removing trailing zeros */
m--;
a0++;
}
}
while (m && !a0[m-1]) m--; /* Removing leading zeros */
}
a = a0;
b = b0;
i = n;
if (g > 1) { /* a - g * b case */
f = 0;
while (i--) {
f = (FULL) *a - g * *b++ - f;
*a++ = (HALF) f;
f >>= BASEB;
f = -f & BASE1;
}
if (f) {
i = m - n;
while (i-- && f) {
f = *a - f;
*a++ = (HALF) f;
f >>= BASEB;
f = -f & BASE1;
}
}
while (m && !*a0) { /* Removing trailing zeros */
m--;
a0++;
}
if (f) { /* a - g * b < 0 */
while (m > 1 && a0[m-1] == BASE1) m--;
*a0 = - *a0;
a = a0;
i = m;
while (--i) {
a++;
*a = ~*a;
}
}
} else { /* abs(a - b) case */
while (i && *a++ == *b++) i--;
q = n - i;
if (m == n) { /* a and b same length */
if (i) { /* a not equal to b */
while (m && a0[m-1] == b0[m-1]) m--;
if (a0[m-1] < b0[m-1]) {
/* Swapping since a < b */
a = a0;
a0 = b0;
b0 = a;
k = j;
}
a = a0 + q;
b = b0 + q;
i = m - q;
f = 0;
while (i--) {
f = (FULL) *a - *b++ - f;
*a++ = (HALF) f;
f >>= BASEB;
f = -f & BASE1;
}
}
} else { /* a has more digits than b */
a = a0 + q;
b = b0 + q;
i = n - q;
f = 0;
while (i--) {
f = (FULL) *a - *b++ - f;
*a++ = (HALF) f;
f >>= BASEB;
f = -f & BASE1;
}
if (f) { while (!*a) *a++ = BASE1;
(*a)--;
}
}
a0 += q;
m -= q;
while (m && !*a0) { /* Removing trailing zeros */
m--;
a0++;
}
}
while (m && !a0[m-1]) m--; /* Removing leading zeros */
}
if (m == 1) { /* a has one digit */
v = *a0;