mirror of
https://github.com/lcn2/calc.git
synced 2025-08-19 01:13:27 +03:00
Compare commits
23 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
c8705c1198 | ||
|
e555a718c0 | ||
|
b29fcf2dd5 | ||
|
4f86703843 | ||
|
07d8bf0f3e | ||
|
b4cd692bae | ||
|
83c898cc2b | ||
|
c585d7aa78 | ||
|
f42a003d04 | ||
|
8da0471f07 | ||
|
1c20261b93 | ||
|
aeb9a9d473 | ||
|
66883b390d | ||
|
ea533659ce | ||
|
9e81971f25 | ||
|
cbbd866535 | ||
|
bf23f82c29 | ||
|
ec5c584785 | ||
|
6bbb8c0e42 | ||
|
438554b0ed | ||
|
61ba4bc5c8 | ||
|
0145883396 | ||
|
f91bfaab70 |
82
CHANGES
82
CHANGES
@@ -1,4 +1,83 @@
|
||||
The following are the changes from calc version 2.12.6.0 to date:
|
||||
The following are the changes from calc version 2.12.6.6 to date:
|
||||
|
||||
For historical purposes, in lucas.cal, gen_v1(1, n) always returns 4.
|
||||
|
||||
Fixed some compiler warnings, thanks to a report by Mike
|
||||
<michael dot d dot ince at gmail dot com>.
|
||||
|
||||
Added work around for a gcc warning bug, thanks to a report by Mike
|
||||
<michael dot d dot ince at gmail dot com>.
|
||||
|
||||
Fixed errors in various help files such as:
|
||||
|
||||
mat randbit seed srandom types
|
||||
|
||||
Removed the MAXSTRING symbol because it was no longer used by calc.
|
||||
|
||||
Increased HIST_SIZE (depth of the history stack) from 10k to 32k.
|
||||
|
||||
Increased TTYSIZE (reallocation size for terminal buffers) from 100 to 8191.
|
||||
|
||||
Increased MAXDEPTH (maximum depth of input stack) from 10 to 255.
|
||||
|
||||
Increased interactive input buffer size from 1024 to 256k. This has the
|
||||
effect of increasing the maximum length of an input line from a tty.
|
||||
This helps with an interactive bug that was reported by Ruslan Kabatsayev
|
||||
(b7 dot 10110111 at gmail dot com).
|
||||
|
||||
The calc man page indicates that -d also disables the printing of the
|
||||
leading tilde.
|
||||
|
||||
Added information to "help command" about how to silence messages
|
||||
while reading calc resource files.
|
||||
|
||||
Fixed an error message buffer overflow thanks to a report by
|
||||
Frank Peters <nlp at northernlightsphoto dot biz>.
|
||||
|
||||
Replaced all use of the C funcion sprintf() with snprintf().
|
||||
Replaced all use of the C funcion vsprintf() with vsnprintf().
|
||||
Replaced all DONT_HAVE_VSPRINTF with DONT_HAVE_VSNPRINTF.
|
||||
Replaced all Makefile var ${HAVE_VSPRINTF} with ${HAVE_VSNPRINTF}.
|
||||
|
||||
|
||||
The following are the changes from calc version 2.12.6.4 to 2.12.6.5:
|
||||
|
||||
Fixed warning about undefined operations involving the qlink(q)
|
||||
macro by replacing that macro with an inline-function. Thanks goes
|
||||
to David Haller <dnh at opensuse dot org> for this fix.
|
||||
|
||||
NOTE for Windows 10 users: Pavel Nemec <pane at seznam dot cz>
|
||||
reported that calc version 2.12.6.4 has been successfully
|
||||
compiled, installed and running on Windows 10. See README.WINDOWS
|
||||
for more details.
|
||||
|
||||
|
||||
The following are the changes from calc version 2.12.6.1 to 2.12.6.3:
|
||||
|
||||
Improved gen_v1(h,n) in lucas.cal to use an even faster search method.
|
||||
|
||||
Improved are checking in lucas.cal. In particular both h and n must be
|
||||
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:
|
||||
|
||||
Added the makefile variable ${COMMON_ADD} that will add flags
|
||||
to all compile and link commands. The ${COMMON_ADD} flags are
|
||||
@@ -68,7 +147,6 @@ The following are the changes from calc version 2.12.6.0 to date:
|
||||
|
||||
Fixed a number of typos in the CHANGES file.
|
||||
|
||||
|
||||
The following are the changes from calc version 2.12.5.4 to 2.12.5.6:
|
||||
|
||||
Recompile to match current RHEL7.2 libc and friends.
|
||||
|
128
Makefile.ship
128
Makefile.ship
@@ -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
|
||||
@@ -90,29 +90,29 @@ TERMCONTROL=
|
||||
#TERMCONTROL= -DUSE_SGTTY
|
||||
#TERMCONTROL= -DUSE_WIN32
|
||||
|
||||
# If your system does not have a vsprintf() function, you could be in trouble.
|
||||
# If your system does not have a vsnprintf() function, you could be in trouble.
|
||||
#
|
||||
# vsprintf(string, format, ap)
|
||||
# vsnprintf(string, size, format, ap)
|
||||
#
|
||||
# This function works like sprintf except that the 3rd arg is a va_list
|
||||
# strarg (or varargs) list. Some old systems do not have vsprintf().
|
||||
# If you do not have vsprintf(), then calc will try sprintf() and hope
|
||||
# This function works like spnrintf except that the 4th arg is a va_list
|
||||
# strarg (or varargs) list. Some old systems do not have vsnprintf().
|
||||
# If you do not have vsnprintf(), then calc will try snprintf() and hope
|
||||
# for the best.
|
||||
#
|
||||
# A similar problem occurs if your system does not have a vsnprintf()
|
||||
# function. This function is like the vsprintf() function except that
|
||||
# function. This function is like the vsnprintf() function except that
|
||||
# there is an extra second argument that controls the maximum size
|
||||
# string that is produced.
|
||||
#
|
||||
# If HAVE_VSPRINTF is empty, this Makefile will run the have_stdvs.c and/or
|
||||
# have_varvs.c program to determine if vsprintf() is supported. If
|
||||
# HAVE_VSPRINTF is set to -DDONT_HAVE_VSPRINTF then calc will hope that
|
||||
# sprintf() will work.
|
||||
# If HAVE_VSNPRINTF is empty, this Makefile will run the have_stdvs.c and/or
|
||||
# have_varvs.c program to determine if vsnprintf() is supported. If
|
||||
# HAVE_VSNPRINTF is set to -DDONT_HAVE_VSNPRINTF then calc will hope that
|
||||
# snprintf() will work.
|
||||
#
|
||||
# If in doubt, leave HAVE_VSPRINTF empty.
|
||||
# If in doubt, leave HAVE_VSNPRINTF empty.
|
||||
#
|
||||
HAVE_VSPRINTF=
|
||||
#HAVE_VSPRINTF= -DDONT_HAVE_VSPRINTF
|
||||
HAVE_VSNPRINTF=
|
||||
#HAVE_VSNPRINTF= -DDONT_HAVE_VSNPRINTF
|
||||
|
||||
# Determine the byte order of your machine
|
||||
#
|
||||
@@ -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.0
|
||||
VERSION= 2.12.6.8
|
||||
|
||||
# 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
|
||||
|
||||
##################
|
||||
@@ -3491,7 +3545,7 @@ args.h: have_stdvs.c have_varvs.c have_string.h have_unistd.h have_string.h
|
||||
${Q} echo '' >> args.h
|
||||
${Q} echo '' >> args.h
|
||||
${Q} ${RM} -f have_stdvs.o have_stdvs${EXT}
|
||||
-${Q} ${LCC} ${ICFLAGS} ${HAVE_VSPRINTF} have_stdvs.c -c \
|
||||
-${Q} ${LCC} ${ICFLAGS} ${HAVE_VSNPRINTF} have_stdvs.c -c \
|
||||
>/dev/null 2>&1; ${TRUE}
|
||||
-${Q} ${LCC} ${ILDFLAGS} have_stdvs.o -o have_stdvs${EXT} \
|
||||
>/dev/null 2>&1; ${TRUE}
|
||||
@@ -3500,10 +3554,10 @@ args.h: have_stdvs.c have_varvs.c have_string.h have_unistd.h have_string.h
|
||||
else \
|
||||
${TRUE}; \
|
||||
fi
|
||||
-${Q} if [ ! -f have_args.sh ] && [ X"${HAVE_VSPRINTF}" = X ]; then \
|
||||
-${Q} if [ ! -f have_args.sh ] && [ X"${HAVE_VSNPRINTF}" = X ]; then \
|
||||
${RM} -f have_stdvs.o have_stdvs${EXT} have_varvs.o; \
|
||||
${RM} -f have_varvs${EXT}; \
|
||||
${LCC} ${ICFLAGS} ${HAVE_VSPRINTF} have_varvs.c -c \
|
||||
${LCC} ${ICFLAGS} ${HAVE_VSNPRINTF} have_varvs.c -c \
|
||||
2>/dev/null; \
|
||||
${LCC} ${ILDFLAGS} have_varvs.o -o have_varvs${EXT} 2>/dev/null; \
|
||||
if ./have_varvs${EXT} >>args.h 2>/dev/null; then \
|
||||
@@ -3519,8 +3573,8 @@ args.h: have_stdvs.c have_varvs.c have_string.h have_unistd.h have_string.h
|
||||
else \
|
||||
echo 'exit 1' > have_args.sh; \
|
||||
echo "Unable to determine what type of variable args and"; \
|
||||
echo "what type of vsprintf() should be used. Set or change"; \
|
||||
echo "the Makefile variable HAVE_VSPRINTF."; \
|
||||
echo "what type of vsnprintf() should be used. Set or change"; \
|
||||
echo "the Makefile variable HAVE_VSNPRINTF."; \
|
||||
fi
|
||||
${Q} sh ./have_args.sh
|
||||
${Q} echo '' >> args.h
|
||||
@@ -4106,7 +4160,7 @@ env:
|
||||
@echo 'HAVE_UNUSED=${HAVE_UNUSED}'; echo ''
|
||||
@echo 'HAVE_URANDOM_H=${HAVE_URANDOM_H}'; echo ''
|
||||
@echo 'HAVE_USTAT=${HAVE_USTAT}'; echo ''
|
||||
@echo 'HAVE_VSPRINTF=${HAVE_VSPRINTF}'; echo ''
|
||||
@echo 'HAVE_VSNPRINTF=${HAVE_VSNPRINTF}'; echo ''
|
||||
@echo 'HELPDIR=${HELPDIR}'; echo ''
|
||||
@echo 'HELP_PASSDOWN=${HELP_PASSDOWN}'; echo ''
|
||||
@echo 'H_SRC=${H_SRC}'; echo ''
|
||||
|
@@ -10,6 +10,21 @@ NOTE: The main developers do not have access to a Windoz based platform.
|
||||
Of course you are welcome to send us any patches that fix your
|
||||
Windoz build environment.
|
||||
|
||||
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
=-= compiling with Windows Subsystem for Linux (WSL) =-Cygwin =-=
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
|
||||
It has been reported that calc version 2.12.6.4 has been successfully
|
||||
compiled, installed and running on Windows 10 on 2018 Jan 21.
|
||||
|
||||
We were told:
|
||||
|
||||
"The Windows Subsystem for Linux (WSL) is a new Windows 10 feature that
|
||||
enables you to run native Linux command-line tools directly on Windows"
|
||||
|
||||
https://docs.microsoft.com/cs-cz/windows/wsl/about
|
||||
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
=-= compiling with Cygwin =-=
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
|
446
cal/lucas.cal
446
cal/lucas.cal
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* lucas - perform a Lucas primality test on h*2^n-1
|
||||
*
|
||||
* Copyright (C) 1999,2017 Landon Curt Noll
|
||||
* Copyright (C) 1999,2017,2018 Landon Curt Noll
|
||||
*
|
||||
* Calc is open software; you can redistribute it and/or modify it under
|
||||
* the terms of the version 2.1 of the GNU Lesser General Public License
|
||||
@@ -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" */
|
||||
@@ -243,8 +253,8 @@ pprod256 = 0; /* product of "primes up to 256" / "primes up to 46" */
|
||||
* do make this so.
|
||||
*
|
||||
* input:
|
||||
* h the h as in h*2^n-1
|
||||
* n the n as in h*2^n-1
|
||||
* h h as in h*2^n-1 (must be >= 1)
|
||||
* n n as in h*2^n-1 (must be >= 1)
|
||||
*
|
||||
* returns:
|
||||
* 1 => h*2^n-1 is prime
|
||||
@@ -267,13 +277,17 @@ lucas(h, n)
|
||||
* check arg types
|
||||
*/
|
||||
if (!isint(h)) {
|
||||
ldebug("lucas", "h is non-int");
|
||||
quit "FATAL: bad args: h must be an integer";
|
||||
}
|
||||
if (h < 1) {
|
||||
quit "FATAL: bad args: h must be an integer >= 1";
|
||||
}
|
||||
if (!isint(n)) {
|
||||
ldebug("lucas", "n is non-int");
|
||||
quit "FATAL: bad args: n must be an integer";
|
||||
}
|
||||
if (n < 1) {
|
||||
quit "FATAL: bad args: n must be an integer >= 1";
|
||||
}
|
||||
|
||||
/*
|
||||
* reduce h if even
|
||||
@@ -359,41 +373,53 @@ lucas(h, n)
|
||||
return 1; /* 239 is prime */
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that h*2^n-1 is not a multiple of 3
|
||||
*
|
||||
* The case for h*2^n-1 == 3 is handled above.
|
||||
*/
|
||||
if (((h % 3 == 1) && (n % 2 == 0)) || ((h % 3 == 2) && (n % 2 == 1))) {
|
||||
/* no need to test h*2^n-1, it is a multiple of 3 */
|
||||
ldebug("lucas","not-prime: != 3 and is a multiple of 3");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Avoid any numbers divisible by small primes
|
||||
*/
|
||||
/*
|
||||
* check for 3 <= prime factors < 29
|
||||
* pfact(28)/2 = 111546435
|
||||
* check for 5 <= prime factors < 31
|
||||
* pfact(30)/6 = 1078282205
|
||||
*/
|
||||
testval = h*2^n - 1;
|
||||
if (gcd(testval, 111546435) > 1) {
|
||||
/* a small 3 <= prime < 29 divides h*2^n-1 */
|
||||
ldebug("lucas","not-prime: 3<=prime<29 divides h*2^n-1");
|
||||
if (gcd(testval, 1078282205) > 1) {
|
||||
/* a small 5 <= prime < 31 divides h*2^n-1 */
|
||||
ldebug("lucas",\
|
||||
"not-prime: a small 5<=prime<31 divides h*2^n-1");
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* check for 29 <= prime factors < 47
|
||||
* pfact(46)/pfact(28) = 5864229
|
||||
* check for 31 <= prime factors < 53
|
||||
* pfact(52)/pfact(30) = 95041567
|
||||
*/
|
||||
if (gcd(testval, 58642669) > 1) {
|
||||
/* a small 29 <= prime < 47 divides h*2^n-1 */
|
||||
ldebug("lucas","not-prime: 29<=prime<47 divides h*2^n-1");
|
||||
if (gcd(testval, 95041567) > 1) {
|
||||
/* a small 31 <= prime < 53 divides h*2^n-1 */
|
||||
ldebug("lucas","not-prime: 31<=prime<53 divides h*2^n-1");
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* check for prime 47 <= factors < 257, if h*2^n-1 is large
|
||||
* 2^282 > pfact(256)/pfact(46) > 2^281
|
||||
* check for prime 53 <= factors < 257, if h*2^n-1 is large
|
||||
* 2^276 > pfact(256)/pfact(52) > 2^275
|
||||
*/
|
||||
bits = highbit(testval);
|
||||
if (bits >= 281) {
|
||||
if (bits >= 275) {
|
||||
if (pprod256 <= 0) {
|
||||
pprod256 = pfact(256)/pfact(46);
|
||||
pprod256 = pfact(256)/pfact(52);
|
||||
}
|
||||
if (gcd(testval, pprod256) > 1) {
|
||||
/* a small 47 <= prime < 257 divides h*2^n-1 */
|
||||
/* a small 53 <= prime < 257 divides h*2^n-1 */
|
||||
ldebug("lucas",\
|
||||
"not-prime: 47<=prime<257 divides h*2^n-1");
|
||||
"not-prime: 53<=prime<257 divides h*2^n-1");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -409,7 +435,9 @@ lucas(h, n)
|
||||
* generate a test for h*2^n-1. The legacy function,
|
||||
* legacy_gen_v1() used by the Amdahl 6 could have returned
|
||||
* -1. The new gen_v1() based on the method outlined in Ref4
|
||||
* will never return -1.
|
||||
* will never return -1 if h*2^n-1 is not a multiple of 3.
|
||||
* Because the "multiple of 3" case is handled above, the
|
||||
* call below to gen_v1() will never return -1.
|
||||
*/
|
||||
v1 = gen_v1(h, n);
|
||||
if (v1 < 0) {
|
||||
@@ -484,9 +512,9 @@ lucas(h, n)
|
||||
* See the function gen_v1() for details on the value of v(1).
|
||||
*
|
||||
* input:
|
||||
* h - h as in h*2^n-1
|
||||
* n - n as in h*2^n-1
|
||||
* v1 - gen_v1(h,n) (see function below)
|
||||
* h - h as in h*2^n-1 (must be >= 1)
|
||||
* n - n as in h*2^n-1 (must be >= 1)
|
||||
* v1 - gen_v1(h,n) (must be >= 3) (see function below)
|
||||
*
|
||||
* returns:
|
||||
* u(2) - initial value for Lucas test on h*2^n-1
|
||||
@@ -499,6 +527,8 @@ gen_u2(h, n, v1)
|
||||
local r; /* low value: v(n) */
|
||||
local s; /* high value: v(n+1) */
|
||||
local hbits; /* highest bit set in h */
|
||||
local oldh; /* pre-reduced h */
|
||||
local oldn; /* pre-reduced n */
|
||||
local i;
|
||||
|
||||
/*
|
||||
@@ -507,24 +537,45 @@ gen_u2(h, n, v1)
|
||||
if (!isint(h)) {
|
||||
quit "bad args: h must be an integer";
|
||||
}
|
||||
if (h < 0) {
|
||||
quit "bad args: h must be an integer >= 1";
|
||||
}
|
||||
if (!isint(n)) {
|
||||
quit "bad args: n must be an integer";
|
||||
}
|
||||
if (n < 1) {
|
||||
quit "bad args: n must be an integer >= 1";
|
||||
}
|
||||
if (!isint(v1)) {
|
||||
quit "bad args: v1 must be an integer";
|
||||
}
|
||||
if (v1 <= 0) {
|
||||
quit "bogus arg: v1 is <= 0";
|
||||
if (v1 < 3) {
|
||||
quit "bogus arg: v1 must be an integer >= 3";
|
||||
}
|
||||
|
||||
/*
|
||||
* reduce h if even
|
||||
*
|
||||
* we will force h to be odd by moving powers of two over to 2^n
|
||||
*/
|
||||
oldh = h;
|
||||
oldn = n;
|
||||
shiftdown = fcnt(h,2); /* h % 2^shiftdown == 0, max shiftdown */
|
||||
if (shiftdown > 0) {
|
||||
h >>= shiftdown;
|
||||
n += shiftdown;
|
||||
}
|
||||
|
||||
/*
|
||||
* enforce the h > 0 and n >= 2 rules
|
||||
*/
|
||||
if (h <= 0 || n < 1) {
|
||||
print " ERROR: h=":oldh, "n=":oldn, "reduced h=":h, "n=":n;
|
||||
quit "reduced args violate the rule: 0 < h < 2^n";
|
||||
}
|
||||
hbits = highbit(h);
|
||||
if (hbits >= n) {
|
||||
print " ERROR: h=":oldh, "n=":oldn, "reduced h=":h, "n=":n;
|
||||
quit "reduced args violate the rule: 0 < h < 2^n";
|
||||
}
|
||||
|
||||
@@ -599,8 +650,8 @@ gen_u2(h, n, v1)
|
||||
* See the function gen_u2() for details.
|
||||
*
|
||||
* input:
|
||||
* h - h as in h*2^n-1
|
||||
* n - n as in h*2^n-1
|
||||
* h - h as in h*2^n-1 (must be >= 1)
|
||||
* n - n as in h*2^n-1 (must be >= 1)
|
||||
* v1 - gen_v1(h,n) (see function below)
|
||||
*
|
||||
* returns:
|
||||
@@ -638,9 +689,9 @@ gen_u0(h, n, v1)
|
||||
* x > 2
|
||||
*
|
||||
* input:
|
||||
* x - potential v(1) value
|
||||
* h - h as in h*2^n-1
|
||||
* n - n as in h*2^n-1
|
||||
* x potential v(1) value
|
||||
* h h as in h*2^n-1 (h must be odd >= 1)
|
||||
* n n as in h*2^n-1 (must be >= 1)
|
||||
*
|
||||
* returns:
|
||||
* 1 if v(1) == x for h*2^n-1
|
||||
@@ -657,9 +708,18 @@ rodseth_xhn(x, h, n)
|
||||
if (!isint(h)) {
|
||||
quit "bad args: h must be an integer";
|
||||
}
|
||||
if (iseven(h)) {
|
||||
quit "bad args: h must be an odd integer";
|
||||
}
|
||||
if (h < 1) {
|
||||
quit "bad args: h must be an integer >= 1";
|
||||
}
|
||||
if (!isint(n)) {
|
||||
quit "bad args: n must be an integer";
|
||||
}
|
||||
if (n < 1) {
|
||||
quit "bad args: n must be an integer >= 1";
|
||||
}
|
||||
if (!isint(x)) {
|
||||
quit "bad args: x must be an integer";
|
||||
}
|
||||
@@ -703,9 +763,9 @@ 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 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:
|
||||
* 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:
|
||||
*
|
||||
* count X
|
||||
* ----------
|
||||
@@ -763,45 +823,161 @@ rodseth_xhn(x, h, n)
|
||||
* 1 161
|
||||
* 1 155
|
||||
*
|
||||
* It is important that we select the smallest possible v(1). While testing
|
||||
* various values of X for V(1) is fast, using larger than necessary values
|
||||
* of V(1) of can slow down calculating V(h).
|
||||
*
|
||||
* The above distribution was found to hold fairly well over many values of
|
||||
* odd h that are a multiple of 3 and for many values of n where h < 2^n.
|
||||
* 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 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:
|
||||
*
|
||||
* 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 %
|
||||
*
|
||||
* 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 values of X:
|
||||
* these odd values of X:
|
||||
*
|
||||
* 3, 5, 9, 11, 15, 17, 21, 29, 20, 27, 35, 36, 39, 41, 45, 32, 51, 44,
|
||||
* 56, 49, 59, 57, 65, 55, 69, 71, 77, 81, 66, 95, 80, 67, 84, 99, 72,
|
||||
* 74, 87, 90, 104, 101, 105, 109, 116, 111, 92
|
||||
* 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 = 120
|
||||
* and incrementing by 1 until a value of X is found.
|
||||
* 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.
|
||||
*
|
||||
* IMPORTANT NOTE: Using this table will not find the smallest possible v(1)
|
||||
* for a given h and n. This is not a problem because using
|
||||
* a larger value of v(1) does not impact the primality test.
|
||||
* Furthermore after lucas(h, n) generates a few u(n) terms,
|
||||
* the values will wrap (due to computing mod h*2^n-1).
|
||||
* Finally on average, about 1/4 of the values of X work as
|
||||
* v(1) for a given n when h is a multiple of 3. Skipping
|
||||
* rarely used v(1) will not doom gen_v1() to a long search.
|
||||
* 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 = 45;
|
||||
x_tbl_len = 42;
|
||||
mat x_tbl[x_tbl_len];
|
||||
x_tbl = {
|
||||
3, 5, 9, 11, 15, 17, 21, 29, 20, 27, 35, 36, 39, 41, 45, 32, 51, 44,
|
||||
56, 49, 59, 57, 65, 55, 69, 71, 77, 81, 66, 95, 80, 67, 84, 99, 72,
|
||||
74, 87, 90, 104, 101, 105, 109, 116, 111, 92
|
||||
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 = 120;
|
||||
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
|
||||
@@ -859,12 +1035,22 @@ next_x = 120;
|
||||
*
|
||||
* 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)
|
||||
@@ -956,17 +1142,22 @@ next_x = 120;
|
||||
***
|
||||
*
|
||||
* input:
|
||||
* h h as in h*2^n-1
|
||||
* n n as in h*2^n-1
|
||||
* h h as in h*2^n-1 (h must be odd >= 1)
|
||||
* 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
|
||||
@@ -974,58 +1165,131 @@ gen_v1(h, n)
|
||||
if (!isint(h)) {
|
||||
quit "bad args: h must be an integer";
|
||||
}
|
||||
if (iseven(h)) {
|
||||
quit "bad args: h must be an odd integer";
|
||||
}
|
||||
if (h < 1) {
|
||||
quit "bad args: h must be an integer >= 1";
|
||||
}
|
||||
if (!isint(n)) {
|
||||
quit "bad args: n must be an integer";
|
||||
}
|
||||
if (n < 1) {
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Common Mersenne number case:
|
||||
*
|
||||
* For Mersenne numbers:
|
||||
*
|
||||
* 2^n-1
|
||||
*
|
||||
* we can use, 40% of the time, v(1) == 3. However nearly all code that
|
||||
* implements the Lucas-Lehmer test uses v(1) == 4. Whenever for
|
||||
* h != 0 mod 3, and particular the Mersenne number case of when h == 1:
|
||||
*
|
||||
* 1*2^n-1
|
||||
*
|
||||
* v(1) == 4 always works. For this reason, we return 4 when h == 1.
|
||||
*/
|
||||
if (h == 1) {
|
||||
/* v(1) == 4 always works for the Mersenne number case */
|
||||
return 4;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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:
|
||||
*
|
||||
* jacobi(X-2, h*2^n-1) == 1 part 1
|
||||
* jacobi(X+2, h*2^n-1) == -1 part 2
|
||||
*
|
||||
* NOTE: If we wanted to be super optimial, we would cache
|
||||
* jacobi(X+2, h*2^n-1) that that when we increment X
|
||||
* 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 2 300 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
|
||||
* at next_x from here on.
|
||||
*
|
||||
* However, we also need to keep in mind that when x+2 >= 257, we
|
||||
* need to verify that gcd(x-2, h*2^n-1) == 1 and
|
||||
* and to verify that gcd(x+2, h*2^n-1) == 1.
|
||||
* of odd vules at next_x from here on.
|
||||
*/
|
||||
x = next_x;
|
||||
while (rodseth_xhn(x, h, n) != 1) {
|
||||
++x;
|
||||
x += 2;
|
||||
}
|
||||
/* finally found a v(1) value */
|
||||
ldebug("gen_v1", "h= " + str(h) + " n= " + str(n) +
|
||||
@@ -1457,8 +1721,8 @@ legacy_d_qval[7] = 19; legacy_v1_qval[7] = 74; /* a=38 b=1 r=2 */
|
||||
***
|
||||
*
|
||||
* input:
|
||||
* h h as in h*2^n-1
|
||||
* n n as in h*2^n-1
|
||||
* h h as in h*2^n-1 (must be >= 1)
|
||||
* n n as in h*2^n-1 (must be >= 1)
|
||||
*
|
||||
* output:
|
||||
* returns v(1), or -1 is there is no quick way
|
||||
@@ -1470,6 +1734,22 @@ legacy_gen_v1(h, n)
|
||||
local val_mod; /* h*2^n-1 mod 'D' */
|
||||
local i;
|
||||
|
||||
/*
|
||||
* check arg types
|
||||
*/
|
||||
if (!isint(h)) {
|
||||
quit "bad args: h must be an integer";
|
||||
}
|
||||
if (h < 1) {
|
||||
quit "bad args: h must be an integer >= 1";
|
||||
}
|
||||
if (!isint(n)) {
|
||||
quit "bad args: n must be an integer";
|
||||
}
|
||||
if (n < 1) {
|
||||
quit "bad args: n must be an integer >= 1";
|
||||
}
|
||||
|
||||
/*
|
||||
* check for case 1
|
||||
*/
|
||||
|
19
calc.c
19
calc.c
@@ -104,6 +104,8 @@ main(int argc, char **argv)
|
||||
int c; /* option */
|
||||
int index;
|
||||
int maxindex;
|
||||
/* fix gcc warning bug */
|
||||
int unusedint = 0;
|
||||
char *cp;
|
||||
char *endcp;
|
||||
char *bp;
|
||||
@@ -278,7 +280,9 @@ main(int argc, char **argv)
|
||||
exit(6);
|
||||
}
|
||||
calc_debug = cp;
|
||||
(void) strtol(cp, &endcp, 10);
|
||||
/* fix gcc warning bug */
|
||||
unusedint =
|
||||
strtol(cp, &endcp, 10);
|
||||
cp = endcp;
|
||||
if (*cp != '\0' &&
|
||||
*cp != ' ' && *cp != ':') {
|
||||
@@ -310,7 +314,9 @@ main(int argc, char **argv)
|
||||
exit(9);
|
||||
}
|
||||
resource_debug = cp;
|
||||
(void) strtol(cp, &endcp, 10);
|
||||
/* fix gcc warning bug */
|
||||
unusedint =
|
||||
strtol(cp, &endcp, 10);
|
||||
cp = endcp;
|
||||
if (*cp != '\0' &&
|
||||
*cp != ' ' && *cp != ':') {
|
||||
@@ -340,7 +346,8 @@ main(int argc, char **argv)
|
||||
exit(12);
|
||||
}
|
||||
user_debug = cp;
|
||||
(void) strtol(cp, &endcp, 10);
|
||||
/* unusedint avoids gcc warning bug */
|
||||
unusedint = strtol(cp, &endcp, 10);
|
||||
cp = endcp;
|
||||
if (*cp != '\0' && *cp != ' ') {
|
||||
fprintf(stderr, "Bad syntax in"
|
||||
@@ -721,8 +728,10 @@ main(int argc, char **argv)
|
||||
printf("main: run_state = %s\n", run_state_name(run_state));
|
||||
|
||||
/*
|
||||
* all done
|
||||
* All done! - Jessica Noll, Age 2
|
||||
*/
|
||||
/* fix gcc warning bug */
|
||||
unusedint++;
|
||||
libcalc_call_me_last();
|
||||
return (run_state == RUN_EXIT_WITH_ERROR ||
|
||||
run_state == RUN_ZERO) ? 1 : 0;
|
||||
@@ -766,7 +775,7 @@ calc_interrupt(char *fmt, ...)
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(calc_err_msg, MAXERROR, fmt, ap);
|
||||
va_end(ap);
|
||||
calc_err_msg[MAXERROR] = '\0';
|
||||
calc_err_msg[MAXERROR] = '\0'; /* paranoia */
|
||||
fprintf(stderr, "%s\n\n", calc_err_msg);
|
||||
funcname = NULL;
|
||||
if (calc_use_scanerr_jmpbuf != 0) {
|
||||
|
1
calc.h
1
calc.h
@@ -65,7 +65,6 @@
|
||||
|
||||
#define SYMBOLSIZE 256 /* maximum symbol name size */
|
||||
#define MAXLABELS 100 /* maximum number of user labels in function */
|
||||
#define MAXSTRING 1024 /* maximum size of string constant */
|
||||
#define MAXSTACK 2048 /* maximum depth of evaluation stack */
|
||||
#define MAXFILES 20 /* maximum number of opened files */
|
||||
#define PROMPT1 "> " /* default normal prompt*/
|
||||
|
43
calc.man
43
calc.man
@@ -1,5 +1,5 @@
|
||||
.\"
|
||||
.\" Copyright (C) 1999-2007,2014 Landon Curt Noll
|
||||
.\" Copyright (C) 1999-2007,2014,2018 Landon Curt Noll
|
||||
.\"
|
||||
.\" Calc is open software; you can redistribute it and/or modify it under
|
||||
.\" the terms of the version 2.1 of the GNU Lesser General Public License
|
||||
@@ -138,7 +138,7 @@ calc -d "read qtime; qtime(2)"
|
||||
.fi
|
||||
.in -5n
|
||||
.sp 1
|
||||
will just say:
|
||||
will just print:
|
||||
.sp 1
|
||||
.in +5n
|
||||
.nf
|
||||
@@ -148,6 +148,41 @@ It's nearly ten past six.
|
||||
.sp 1
|
||||
This flag disables the reporting of missing calc
|
||||
startup resource files.
|
||||
.sp 1
|
||||
|
||||
This flag also disables the printing the leading tilde. For example:
|
||||
.sp 1
|
||||
.in +5n
|
||||
.nf
|
||||
calc 2/3
|
||||
.fi
|
||||
.in -5n
|
||||
.sp 1
|
||||
will print:
|
||||
.sp 1
|
||||
.in +5n
|
||||
.nf
|
||||
~0.66666666666666666667
|
||||
.fi
|
||||
.in -5n
|
||||
.sp 1
|
||||
.sp 1
|
||||
whereas:
|
||||
.sp 1
|
||||
.in +5n
|
||||
.nf
|
||||
calc -d 2/3
|
||||
.fi
|
||||
.in -5n
|
||||
.sp 1
|
||||
will just print:
|
||||
.sp 1
|
||||
.in +5n
|
||||
.nf
|
||||
0.66666666666666666667
|
||||
.fi
|
||||
.in -5n
|
||||
.sp 1
|
||||
|
||||
.TP
|
||||
.BR -D " calc_debug[:resource_debug[:user_debug]]"
|
||||
@@ -657,8 +692,8 @@ searches in succession:
|
||||
.sp 1
|
||||
.in +5n
|
||||
.nf
|
||||
./myfile
|
||||
./myfile.cal
|
||||
\a./myfile
|
||||
\a./myfile.cal
|
||||
${LIBDIR}/myfile
|
||||
${LIBDIR}/myfile.cal
|
||||
${CUSTOMCALDIR}/myfile
|
||||
|
9
custom.c
9
custom.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* custom - interface for custom software and hardware interfaces
|
||||
*
|
||||
* Copyright (C) 1999-2006 Landon Curt Noll
|
||||
* Copyright (C) 1999-2006,2018 Landon Curt Noll
|
||||
*
|
||||
* Calc is open software; you can redistribute it and/or modify it under
|
||||
* the terms of the version 2.1 of the GNU Lesser General Public License
|
||||
@@ -180,6 +180,7 @@ customhelp(char *name)
|
||||
#if defined(CUSTOM)
|
||||
|
||||
char *customname; /* a string of the form: custom/name */
|
||||
size_t snprintf_len; /* malloced snprintf buffer length */
|
||||
|
||||
/*
|
||||
* firewall
|
||||
@@ -191,12 +192,14 @@ customhelp(char *name)
|
||||
/*
|
||||
* form the custom help name
|
||||
*/
|
||||
customname = (char *)malloc(sizeof("custhelp")+1+strlen(name)+1);
|
||||
snprintf_len = sizeof("custhelp")+1+strlen(name)+1;
|
||||
customname = (char *)malloc(snprintf_len+1);
|
||||
if (customname == NULL) {
|
||||
math_error("bad malloc of customname");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
sprintf(customname, "custhelp/%s", name);
|
||||
snprintf(customname, snprintf_len, "custhelp/%s", name);
|
||||
customname[snprintf_len] = '\0'; /* paranoia */
|
||||
|
||||
/*
|
||||
* give help directly to the custom file
|
||||
|
@@ -2,7 +2,7 @@
|
||||
#
|
||||
# custom - makefile for calc custom routines
|
||||
#
|
||||
# Copyright (C) 1999-2006,2014,2017 Landon Curt Noll
|
||||
# Copyright (C) 1999-2006,2014,2017-2018 Landon Curt Noll
|
||||
#
|
||||
# Calc is open software; you can redistribute it and/or modify it under
|
||||
# the terms of the version 2.1 of the GNU Lesser General Public License
|
||||
@@ -348,7 +348,7 @@ EXT=
|
||||
|
||||
# The default calc versions
|
||||
#
|
||||
VERSION= 2.12.6.0
|
||||
VERSION= 2.12.6.8
|
||||
|
||||
# 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
|
||||
|
||||
##################
|
||||
|
@@ -2,7 +2,7 @@
|
||||
#
|
||||
# custom - makefile for calc custom routines
|
||||
#
|
||||
# Copyright (C) 1999-2006,2014,2017 Landon Curt Noll
|
||||
# Copyright (C) 1999-2006,2014,2017-2018 Landon Curt Noll
|
||||
#
|
||||
# Calc is open software; you can redistribute it and/or modify it under
|
||||
# the terms of the version 2.1 of the GNU Lesser General Public License
|
||||
@@ -348,7 +348,7 @@ EXT=
|
||||
|
||||
# The default calc versions
|
||||
#
|
||||
VERSION= 2.12.6.0
|
||||
VERSION= 2.12.6.8
|
||||
|
||||
# Names of shared libraries with versions
|
||||
#
|
||||
|
@@ -173,8 +173,6 @@ STATIC struct infoname sys_info[] = {
|
||||
(FULL)MAXSCANCOUNT},
|
||||
{"MAXSTACK", "max depth of evaluation stack", NULL,
|
||||
(FULL)MAXSTACK},
|
||||
{"MAXSTRING", "max size of string constant", NULL,
|
||||
(FULL)MAXSTRING},
|
||||
{"MAXUFULL", "largest FULL value", NULL,
|
||||
(FULL)MAXUFULL},
|
||||
{"MAXULONG", "largest unsigned long val", NULL,
|
||||
|
10
file.c
10
file.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* file - file I/O routines callable by users
|
||||
*
|
||||
* Copyright (C) 1999-2007 David I. Bell and Landon Curt Noll
|
||||
* Copyright (C) 1999-2007,2018 David I. Bell and Landon Curt Noll
|
||||
*
|
||||
* Primary author: David I. Bell
|
||||
*
|
||||
@@ -143,6 +143,7 @@ file_init(void)
|
||||
* stat the descriptor to see what we have
|
||||
*/
|
||||
if (fstat(i, &sbuf) >= 0) {
|
||||
size_t snprintf_len; /* malloced snprintf length */
|
||||
fp = (FILE *) fdopen(i,"r+"); /*guess mode*/
|
||||
if (fp) {
|
||||
strcpy(files[idnum].mode, "r+");
|
||||
@@ -161,12 +162,15 @@ file_init(void)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
tname = (char *)malloc(sizeof("descriptor[19]"));
|
||||
snprintf_len =
|
||||
sizeof("descriptor[12345678901234567890]") + 1;
|
||||
tname = (char *)malloc(snprintf_len+1);
|
||||
if (tname == NULL) {
|
||||
math_error("Out of memory for init_file");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
sprintf(tname, "descriptor[%d]", i);
|
||||
snprintf(tname, snprintf_len, "descriptor[%d]", i);
|
||||
tname[snprintf_len] = '\0'; /* paranoia */
|
||||
files[idnum].name = tname;
|
||||
files[idnum].id = idnum;
|
||||
files[idnum].fp = fp;
|
||||
|
20
func.c
20
func.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* func - built-in functions implemented here
|
||||
*
|
||||
* Copyright (C) 1999-2007 David I. Bell, Landon Curt Noll and Ernest Bowen
|
||||
* Copyright (C) 1999-2007,2018 David I. Bell, Landon Curt Noll & Ernest Bowen
|
||||
*
|
||||
* Primary author: David I. Bell
|
||||
*
|
||||
@@ -6022,12 +6022,15 @@ f_strerror(int count, VALUE **vals)
|
||||
/* firewall - return generic error string if it is not assigned */
|
||||
if (i >= nexterrnum || (i > E__HIGHEST && i < E_USERDEF)
|
||||
|| (i < E__BASE && strerror(i) == NULL)) {
|
||||
cp = (char *) malloc(sizeof("Error 1234567890")+1);
|
||||
size_t snprintf_len; /* malloced snprintf buffer length */
|
||||
snprintf_len = sizeof("Unknown error 12345678901234567890")+1;
|
||||
cp = (char *) malloc(snprintf_len+1);
|
||||
if (cp == NULL) {
|
||||
math_error("Out of memory for strerror");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
sprintf(cp, "Unknown error %ld", i);
|
||||
snprintf(cp, snprintf_len, "Unknown error %ld", i);
|
||||
cp[snprintf_len] = '\0'; /* paranoia */
|
||||
result.v_str = makestring(cp);
|
||||
return result;
|
||||
}
|
||||
@@ -7550,6 +7553,8 @@ f_putenv(int count, VALUE **vals)
|
||||
* parse args
|
||||
*/
|
||||
if (count == 2) {
|
||||
size_t snprintf_len; /* malloced snprintf buffer length */
|
||||
|
||||
/* firewall */
|
||||
if (vals[0]->v_type != V_STR || vals[1]->v_type != V_STR) {
|
||||
math_error("Non-string argument for putenv");
|
||||
@@ -7557,14 +7562,17 @@ f_putenv(int count, VALUE **vals)
|
||||
}
|
||||
|
||||
/* convert putenv("foo","bar") into putenv("foo=bar") */
|
||||
putenv_str = (char *)malloc(vals[0]->v_str->s_len + 1 +
|
||||
vals[1]->v_str->s_len + 1);
|
||||
snprintf_len = vals[0]->v_str->s_len + 1 +
|
||||
vals[1]->v_str->s_len + 1;
|
||||
putenv_str = (char *)malloc(snprintf_len+1);
|
||||
if (putenv_str == NULL) {
|
||||
math_error("Cannot allocate string in putenv");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
sprintf(putenv_str, "%s=%s", vals[0]->v_str->s_str,
|
||||
snprintf(putenv_str, snprintf_len,
|
||||
"%s=%s", vals[0]->v_str->s_str,
|
||||
vals[1]->v_str->s_str);
|
||||
putenv_str[snprintf_len] = '\0'; /* paranoia */
|
||||
|
||||
|
||||
} else {
|
||||
|
88
have_stdvs.c
88
have_stdvs.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* have_stdvs - try <stdarg.h> to see if it really works with vsprintf()
|
||||
* have_stdvs - try <stdarg.h> to see if it really works with vsnprintf()
|
||||
*
|
||||
* Copyright (C) 1999,2014 Landon Curt Noll
|
||||
* Copyright (C) 1999,2014,2018 Landon Curt Noll
|
||||
*
|
||||
* Calc is open software; you can redistribute it and/or modify it under
|
||||
* the terms of the version 2.1 of the GNU Lesser General Public License
|
||||
@@ -25,16 +25,16 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* On some systems that have both <stdarg.h> and <varargs.h>, vsprintf()
|
||||
* On some systems that have both <stdarg.h> and <varargs.h>, vsnprintf()
|
||||
* does not work well under one type of include file.
|
||||
*
|
||||
* Some systems (such as UMIPS) have bugs in the <stdarg.h> implementation
|
||||
* that show up in vsprintf(), so we may have to try to use sprintf()
|
||||
* as if it were vsprintf() and hope for the best.
|
||||
* that show up in vsnprintf(), so we may have to try to use snprintf()
|
||||
* as if it were vsnprintf() and hope for the best.
|
||||
*
|
||||
* This program will output #defines and exits 0 if vsprintf() (or sprintf())
|
||||
* produces the results that we expect. This program exits 1 if vsprintf()
|
||||
* (or sprintf()) produces unexpected results while using the <stdarg.h>
|
||||
* This program will output #defines and exits 0 if vsnprintf() (or snprintf())
|
||||
* produces the results that we expect. This program exits 1 if vsnprintf()
|
||||
* (or snprintf()) produces unexpected results while using the <stdarg.h>
|
||||
* include file.
|
||||
*/
|
||||
|
||||
@@ -57,39 +57,24 @@
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#undef VSPRINTF_SIZE_T
|
||||
#undef VSNPRINTF_SIZE_T
|
||||
#if defined(FORCE_STDC) || (defined(__STDC__) && __STDC__ != 0) || \
|
||||
defined(__cplusplus)
|
||||
# define VSPRINTF_SIZE_T size_t
|
||||
# define VSNPRINTF_SIZE_T size_t
|
||||
#else
|
||||
# define VSPRINTF_SIZE_T long
|
||||
# define VSNPRINTF_SIZE_T long
|
||||
#endif
|
||||
|
||||
char buf[BUFSIZ];
|
||||
char buf[BUFSIZ+1];
|
||||
|
||||
|
||||
void
|
||||
try_this(char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
#if !defined(DONT_HAVE_VSPRINTF)
|
||||
vsprintf(buf, fmt, ap);
|
||||
#else
|
||||
sprintf(buf, fmt, ap);
|
||||
#endif
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
try_nthis(char *fmt, VSPRINTF_SIZE_T size, ...)
|
||||
try_nthis(char *fmt, VSNPRINTF_SIZE_T size, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, size);
|
||||
#if !defined(DONT_HAVE_VSPRINTF)
|
||||
#if !defined(DONT_HAVE_VSNPRINTF)
|
||||
vsnprintf(buf, size, fmt, ap);
|
||||
#else
|
||||
snprintf(buf, size, fmt, ap);
|
||||
@@ -106,36 +91,12 @@ main(void)
|
||||
*/
|
||||
buf[0] = '\0';
|
||||
|
||||
/*
|
||||
* test variable args and vsprintf/sprintf
|
||||
*/
|
||||
try_this("@%d:%s:%d@", 1, "hi", 2);
|
||||
if (strcmp(buf, "@1:hi:2@") != 0) {
|
||||
#if !defined(DONT_HAVE_VSPRINTF)
|
||||
/* <stdarg.h> with vsprintf() didn't work */
|
||||
#else
|
||||
/* <stdarg.h> with sprintf() simulating vsprintf() didn't work */
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
try_this("%s %d%s%d%d %s",
|
||||
"Landon Noll 1st coproved that", 2, "^", 21701, -1, "was prime");
|
||||
if (strcmp(buf,
|
||||
"Landon Noll 1st coproved that 2^21701-1 was prime") != 0) {
|
||||
#if !defined(DONT_HAVE_VSPRINTF)
|
||||
/* <stdarg.h> with vsprintf() didn't work */
|
||||
#else
|
||||
/* <stdarg.h> with sprintf() simulating vsprintf() didn't work */
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* test variable args and vsnprintf/snprintf
|
||||
*/
|
||||
try_nthis("@%d:%s:%d@", sizeof(buf)-1, 1, "hello", 5);
|
||||
if (strcmp(buf, "@1:hello:5@") != 0) {
|
||||
#if !defined(DONT_HAVE_VSPRINTF)
|
||||
#if !defined(DONT_HAVE_VSNPRINTF)
|
||||
/* <stdarg.h> with vsnprintf() didn't work */
|
||||
#else
|
||||
/* <stdarg.h> with snprintf() simulating vsnprintf() didn't work */
|
||||
@@ -146,7 +107,7 @@ main(void)
|
||||
"Landon Noll 1st proved that", 2, "^", 23209, -1, "was prime");
|
||||
if (strcmp(buf,
|
||||
"Landon Noll 1st proved that 2^23209-1 was prime") != 0) {
|
||||
#if !defined(DONT_HAVE_VSPRINTF)
|
||||
#if !defined(DONT_HAVE_VSNPRINTF)
|
||||
/* <stdarg.h> with vsnprintf() didn't work */
|
||||
#else
|
||||
/* <stdarg.h> with snprintf() simulating vsnprintf() didn't work */
|
||||
@@ -158,7 +119,7 @@ main(void)
|
||||
* report the result
|
||||
*/
|
||||
puts("/* what type of variable args do we have? */");
|
||||
#if defined(DONT_HAVE_VSPRINTF)
|
||||
#if defined(DONT_HAVE_VSNPRINTF)
|
||||
puts("/*");
|
||||
puts(" * SIMULATE_STDARG");
|
||||
puts(" *");
|
||||
@@ -179,22 +140,21 @@ main(void)
|
||||
puts("#define STDARG /* use <stdarg.h> */");
|
||||
puts("#include <stdarg.h>");
|
||||
#endif
|
||||
puts("\n/* should we use vsprintf() and vsnprintf()? */");
|
||||
#if !defined(DONT_HAVE_VSPRINTF)
|
||||
puts("#define HAVE_VSPRINTF /* yes */");
|
||||
puts("\n/* should we use vsnprintf() and vsnprintf()? */");
|
||||
#if !defined(DONT_HAVE_VSNPRINTF)
|
||||
puts("#define HAVE_VSNPRINTF /* yes */");
|
||||
#else
|
||||
puts("/*");
|
||||
puts(" * Hack aleart!!!");
|
||||
puts(" *");
|
||||
puts(" * Systems that do not have vsprintf() need something. In some");
|
||||
puts(" * cases the sprintf function will deal correctly with the");
|
||||
puts(" * va_alist 3rd arg. Same gors for a lack of an vsnprintf()");
|
||||
puts(" * Systems that do not have vsnprintf() need something. In some");
|
||||
puts(" * cases the snprintf function will deal correctly with the");
|
||||
puts(" * va_alist 4th arg. Same gors for a lack of an vsnprintf()");
|
||||
puts(" * function. In either case we use the #defines below and");
|
||||
puts(" * hope for the best!");
|
||||
puts(" */");
|
||||
puts("#define vsprintf sprintf");
|
||||
puts("#define vsnprintf snprintf");
|
||||
puts("#undef HAVE_VSPRINTF");
|
||||
puts("#undef HAVE_VSNPRINTF");
|
||||
#endif
|
||||
/* exit(0); */
|
||||
return 0;
|
||||
|
93
have_varvs.c
93
have_varvs.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* have_varvs - try <varargs.h> to see if it really works with vsprintf()
|
||||
* have_varvs - try <varargs.h> to see if it really works with vsnprintf()
|
||||
*
|
||||
* Copyright (C) 1999 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 the version 2.1 of the GNU Lesser General Public License
|
||||
@@ -26,12 +26,12 @@
|
||||
|
||||
/*
|
||||
* Some systems have bugs in the <varargs.h> implementation that show up in
|
||||
* vsprintf(), so we may have to try to use sprintf() as if it were vsprintf()
|
||||
* and hope for the best.
|
||||
* vsnprintf(), so we may have to try to use snprintf() as if it were
|
||||
* vsnprintf() and hope for the best.
|
||||
*
|
||||
* This program will output #defines and exits 0 if vsprintf() (or sprintf())
|
||||
* produces the results that we expect. This program exits 1 if vsprintf()
|
||||
* (or sprintf()) produces unexpected results while using the <stdarg.h>
|
||||
* This program will output #defines and exits 0 if vsnprintf() (or snprintf())
|
||||
* produces the results that we expect. This program exits 1 if vsnprintf()
|
||||
* (or snprintf()) produces unexpected results while using the <stdarg.h>
|
||||
* include file.
|
||||
*/
|
||||
|
||||
@@ -48,43 +48,27 @@
|
||||
# include <string.h>
|
||||
#endif
|
||||
|
||||
#undef VSPRINTF_SIZE_T
|
||||
#undef VSNPRINTF_SIZE_T
|
||||
#if defined(FORCE_STDC) || (defined(__STDC__) && __STDC__ != 0) || \
|
||||
defined(__cplusplus)
|
||||
# define VSPRINTF_SIZE_T size_t
|
||||
# define VSNPRINTF_SIZE_T size_t
|
||||
#else
|
||||
# define VSPRINTF_SIZE_T long
|
||||
# define VSNPRINTF_SIZE_T long
|
||||
#endif
|
||||
|
||||
char buf[BUFSIZ];
|
||||
char buf[BUFSIZ+1];
|
||||
|
||||
#if !defined(STDARG) && !defined(SIMULATE_STDARG)
|
||||
#include <varargs.h>
|
||||
|
||||
void
|
||||
try_this(char *fmt, ...)
|
||||
try_nthis(char *fmt, VSNPRINTF_SIZE_T size, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap);
|
||||
|
||||
#if !defined(DONT_HAVE_VSPRINTF)
|
||||
vsprintf(buf, fmt, ap);
|
||||
#else
|
||||
sprintf(buf, fmt, ap);
|
||||
#endif
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
try_nthis(char *fmt, VSPRINTF_SIZE_T size, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap);
|
||||
|
||||
#if !defined(DONT_HAVE_VSPRINTF)
|
||||
#if !defined(DONT_HAVE_VSNPRINTF)
|
||||
vsnprintf(buf, size, fmt, ap);
|
||||
#else
|
||||
snprintf(buf, size, fmt, ap);
|
||||
@@ -96,13 +80,7 @@ try_nthis(char *fmt, VSPRINTF_SIZE_T size, ...)
|
||||
#else
|
||||
|
||||
void
|
||||
try_this(char *a, int b, char *c, int d)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
try_nthis(char *a, VSPRINTF_SIZE_T size, int b, char *c, int d)
|
||||
try_nthis(char *a, VSNPRINTF_SIZE_T size, int b, char *c, int d)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -118,36 +96,12 @@ main(void)
|
||||
*/
|
||||
buf[0] = '\0';
|
||||
|
||||
/*
|
||||
* test variable args and vsprintf/sprintf
|
||||
*/
|
||||
try_this("@%d:%s:%d@", 1, "hi", 2);
|
||||
if (strcmp(buf, "@1:hi:2@") != 0) {
|
||||
#if !defined(DONT_HAVE_VSPRINTF)
|
||||
/* <varargs.h> with vsprintf() didn't work */
|
||||
#else
|
||||
/* <varargs.h> with sprintf() simulating vsprintf() didn't work */
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
try_this("%s %d%s%d%d %s",
|
||||
"Landon Noll 1st proved that", 2, "^", 23209, -1, "was prime");
|
||||
if (strcmp(buf,
|
||||
"Landon Noll 1st proved that 2^23209-1 was prime") != 0) {
|
||||
#if !defined(DONT_HAVE_VSPRINTF)
|
||||
/* <varargs.h> with vsprintf() didn't work */
|
||||
#else
|
||||
/* <varargs.h> with sprintf() simulating vsprintf() didn't work */
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* test variable args and vsnprintf/snprintf
|
||||
*/
|
||||
try_nthis("@%d:%s:%d@", sizeof(buf)-1, 1, "hello", 5);
|
||||
if (strcmp(buf, "@1:hello:5@") != 0) {
|
||||
#if !defined(DONT_HAVE_VSPRINTF)
|
||||
#if !defined(DONT_HAVE_VSNPRINTF)
|
||||
/* <varargs.h> with vsnprintf() didn't work */
|
||||
#else
|
||||
/* <varargs.h> with snprintf() simulating vsnprintf() didn't work */
|
||||
@@ -158,7 +112,7 @@ main(void)
|
||||
"Landon Noll 1st proved that", 2, "^", 23209, -1, "was prime");
|
||||
if (strcmp(buf,
|
||||
"Landon Noll 1st proved that 2^23209-1 was prime") != 0) {
|
||||
#if !defined(DONT_HAVE_VSPRINTF)
|
||||
#if !defined(DONT_HAVE_VSNPRINTF)
|
||||
/* <varargs.h> with vsnprintf() didn't work */
|
||||
#else
|
||||
/* <varargs.h> with snprintf() simulating vsnprintf() didn't work */
|
||||
@@ -172,22 +126,21 @@ main(void)
|
||||
puts("/* what type of variable args do we have? */");
|
||||
puts("#define VARARGS /* use <varargs.h> */");
|
||||
puts("#include <varargs.h>");
|
||||
puts("\n/* should we use vsprintf() and vsnprintf()? */");
|
||||
#if !defined(DONT_HAVE_VSPRINTF)
|
||||
puts("#define HAVE_VSPRINTF /* yes */");
|
||||
puts("\n/* should we use vsnprintf() and vsnprintf()? */");
|
||||
#if !defined(DONT_HAVE_VSNPRINTF)
|
||||
puts("#define HAVE_VSNPRINTF /* yes */");
|
||||
#else
|
||||
puts("/*");
|
||||
puts(" * Hack aleart!!!");
|
||||
puts(" *");
|
||||
puts(" * Systems that do not have vsprintf() need something. In some");
|
||||
puts(" * cases the sprintf function will deal correctly with the");
|
||||
puts(" * va_alist 3rd arg. Same gors for a lack of an vsnprintf()");
|
||||
puts(" * Systems that do not have vsnprintf() need something. In some");
|
||||
puts(" * cases the snprintf() function will deal correctly with the");
|
||||
puts(" * va_alist 4th arg. Same gors for a lack of an vsnprintf()");
|
||||
puts(" * function. In either case we use the #defines below and");
|
||||
puts(" * hope for the best!");
|
||||
puts(" */");
|
||||
puts("#define vsprintf sprintf");
|
||||
puts("#define vsnprintf snprintf");
|
||||
puts("#undef HAVE_VSPRINTF");
|
||||
puts("#undef HAVE_VSNPRINTF");
|
||||
#endif
|
||||
/* exit(0); */
|
||||
return 0;
|
||||
|
17
help.c
17
help.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* help - display help for calc
|
||||
*
|
||||
* Copyright (C) 1999-2007,2014 Landon Curt Noll
|
||||
* Copyright (C) 1999-2007,2014,2018 Landon Curt Noll
|
||||
*
|
||||
* Calc is open software; you can redistribute it and/or modify it under
|
||||
* the terms of the version 2.1 of the GNU Lesser General Public License
|
||||
@@ -183,6 +183,7 @@ givehelp(char *type)
|
||||
FILE *stream; /* help file stream */
|
||||
char *helppath; /* path to the help file */
|
||||
char *c;
|
||||
size_t snprintf_len; /* malloced snprintf buffer length */
|
||||
|
||||
/*
|
||||
* check permissions to see if we are allowed to help
|
||||
@@ -247,18 +248,21 @@ givehelp(char *type)
|
||||
*/
|
||||
#if defined(CUSTOM)
|
||||
if (sizeof(CUSTOMHELPDIR) > sizeof(HELPDIR)) {
|
||||
helppath = (char *)malloc(sizeof(CUSTOMHELPDIR)+1+strlen(type));
|
||||
snprintf_len = sizeof(CUSTOMHELPDIR)+1+strlen(type) + 1;
|
||||
} else {
|
||||
helppath = (char *)malloc(sizeof(HELPDIR)+1+strlen(type));
|
||||
snprintf_len = sizeof(HELPDIR)+1+strlen(type) + 1;
|
||||
}
|
||||
helppath = (char *)malloc(snprintf_len+1);
|
||||
#else /* CUSTOM */
|
||||
helppath = (char *)malloc(sizeof(HELPDIR)+1+strlen(type));
|
||||
snprintf_len = sizeof(HELPDIR)+1+strlen(type) + 1;
|
||||
helppath = (char *)malloc(snprintf_len+1);
|
||||
#endif /* CUSTOM */
|
||||
if (helppath == NULL) {
|
||||
fprintf(stderr, "malloc failure in givehelp()\n");
|
||||
return;
|
||||
}
|
||||
sprintf(helppath, "%s/%s", HELPDIR, type);
|
||||
snprintf(helppath, snprintf_len, "%s/%s", HELPDIR, type);
|
||||
helppath[snprintf_len] = '\0'; /* paranoia */
|
||||
stream = fopen(helppath, "r");
|
||||
if (stream != NULL) {
|
||||
|
||||
@@ -274,7 +278,8 @@ givehelp(char *type)
|
||||
*/
|
||||
} else {
|
||||
|
||||
sprintf(helppath, "%s/%s", CUSTOMHELPDIR, type);
|
||||
snprintf(helppath, snprintf_len, "%s/%s", CUSTOMHELPDIR, type);
|
||||
helppath[snprintf_len] = '\0'; /* paranoia */
|
||||
stream = fopen(helppath, "r");
|
||||
if (stream == NULL) {
|
||||
|
||||
|
27
help/command
27
help/command
@@ -88,6 +88,31 @@ Command sequence
|
||||
If the -m mode disallows opening of files for reading,
|
||||
this command will be disabled.
|
||||
|
||||
To read a calc resource file without printing various
|
||||
messages about defined functions, the "resource_debug"
|
||||
config should be set to zero. For example:
|
||||
|
||||
read lucas;
|
||||
|
||||
will, by default, print messages such as:
|
||||
|
||||
lucas(h,n) defined
|
||||
gen_u2(h,n,v1) defined
|
||||
gen_u0(h,n,v1) defined
|
||||
rodseth_xhn(x,h,n) defined
|
||||
gen_v1(h,n) defined
|
||||
ldebug(funct,str) defined
|
||||
legacy_gen_v1(h,n) defined
|
||||
|
||||
When "resource_debug" is zero, such messages are silenced.
|
||||
|
||||
config("resource_debug", 0),;
|
||||
read lucas;
|
||||
|
||||
To silence such messages on the calc command line, try:
|
||||
|
||||
calc -p -D :0 'read -once lucas; lucas(1, 23209);'
|
||||
|
||||
|
||||
write calc commands
|
||||
-------------------
|
||||
@@ -350,7 +375,7 @@ Command sequence
|
||||
statement flow control and declaration statements
|
||||
usage how to invoke the calc command and calc -options
|
||||
|
||||
## Copyright (C) 1999-2006 Landon Curt Noll
|
||||
## Copyright (C) 1999-2006,2018 Landon Curt Noll
|
||||
##
|
||||
## Calc is open software; you can redistribute it and/or modify it under
|
||||
## the terms of the version 2.1 of the GNU Lesser General Public License
|
||||
|
8
help/mat
8
help/mat
@@ -54,13 +54,13 @@ DESCRIPTION
|
||||
The elements of the matrix are stored internally as a linear array
|
||||
in which locations are arranged in order of increasing indices.
|
||||
For example, in order of location, the six element of A = mat [2,3]
|
||||
are
|
||||
are:
|
||||
|
||||
A[0,0], A[0,1], A[0,2], A[1,0], A[1,,1], A[1,2].
|
||||
A[0,0], A[0,1], A[0,2], A[1,0], A[1,1], and A[1,2].
|
||||
|
||||
These elements may also be specified using the double-bracket operator
|
||||
with a single integer index as in A[[0]], A[[1]], ..., A[[5]].
|
||||
If p is assigned the value &A[0.0], the address of A[[i]] for 0 <= i < 6
|
||||
If p is assigned the value &A[0,0], the address of A[[i]] for 0 <= i < 6
|
||||
is p + i as long as A exists and a new value is not assigned to A.
|
||||
|
||||
When a matrix is created, each element is initially assigned the
|
||||
@@ -414,7 +414,7 @@ SEE ALSO
|
||||
det, inverse, isident, test, config, search, rsearch, reverse, copy,
|
||||
blkcpy, dp, cp, randperm, sort
|
||||
|
||||
## Copyright (C) 1999-2006 Landon Curt Noll
|
||||
## Copyright (C) 1999-2006,2018 Landon Curt Noll
|
||||
##
|
||||
## Calc is open software; you can redistribute it and/or modify it under
|
||||
## the terms of the version 2.1 of the GNU Lesser General Public License
|
||||
|
@@ -1,5 +1,5 @@
|
||||
NAME
|
||||
randbit - additive 55 shuffle pseudo-random number generator
|
||||
randbit - subtractive 100 shuffle pseudo-random number generator
|
||||
|
||||
SYNOPSIS
|
||||
randbit([x])
|
||||
@@ -42,7 +42,7 @@ LINK LIBRARY
|
||||
SEE ALSO
|
||||
seed, srand, randbit, isrand, random, srandom, israndom
|
||||
|
||||
## Copyright (C) 1999 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 the version 2.1 of the GNU Lesser General Public License
|
||||
|
11
help/seed
11
help/seed
@@ -18,14 +18,7 @@ DESCRIPTION
|
||||
It should be pointed out that the information collected by seed
|
||||
is almost certainly non-chaotic. This function is likely not
|
||||
suitable for applications (such as cryptographic applications)
|
||||
where the unpredictability of seeds is critical. For such critical
|
||||
applications, LavaRnd should be used. See the URL:
|
||||
|
||||
http://www.LavaRnd.org/
|
||||
|
||||
for information about seeding a pseudo-random number generator
|
||||
(such as rand() or random()) with the cryptographic hash of the
|
||||
digitization of chaotic system.
|
||||
where the unpredictability of seeds is critical.
|
||||
|
||||
Given the above warning, this builtin function produces a seed that is
|
||||
suitable for most applications that desire a different pseudo-random
|
||||
@@ -51,7 +44,7 @@ LINK LIBRARY
|
||||
SEE ALSO
|
||||
seed, srand, randbit, isrand, rand, random, srandom, israndom
|
||||
|
||||
## Copyright (C) 1999 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 the version 2.1 of the GNU Lesser General Public License
|
||||
|
@@ -332,13 +332,13 @@ LIMITS
|
||||
iq >= 2^16
|
||||
|
||||
LINK LIBRARY
|
||||
RAND *zsrandom(ZVALUE *pseed, MATRIX *pmat55)
|
||||
RAND *zsetrandom(RAND *state)
|
||||
RANDOM *zsrandom(ZVALUE *pseed, MATRIX *pmat55)
|
||||
RANDOM *zsetrandom(RAND *state)
|
||||
|
||||
SEE ALSO
|
||||
seed, srand, randbit, isrand, random, srandom, israndom
|
||||
|
||||
## Copyright (C) 1999 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 the version 2.1 of the GNU Lesser General Public License
|
||||
|
17
help/types
17
help/types
@@ -1,6 +1,6 @@
|
||||
Builtin types
|
||||
|
||||
The calculator has the following built-in types.
|
||||
The calculator has the following built-in types:
|
||||
|
||||
null value
|
||||
This is the undefined value type. The function 'null'
|
||||
@@ -101,7 +101,20 @@ Builtin types
|
||||
using the result of the 'files' function. Such copies are
|
||||
indistinguishable from each other.
|
||||
|
||||
## Copyright (C) 1999 Landon Curt Noll
|
||||
The calculator also has a number of special types that as used
|
||||
by some special builtin functions:
|
||||
|
||||
rand
|
||||
A subtractive 100 shuffle pseudo-random number generator
|
||||
state. This state is used by functions such as isrand()
|
||||
and srand().
|
||||
|
||||
random
|
||||
A Blum-Blum-Shub pseudo-random number generator state.
|
||||
This state is used by functions such as israndom() and
|
||||
srandom().
|
||||
|
||||
## Copyright (C) 1999,2018 Landon Curt Noll
|
||||
##
|
||||
## Calc is open software; you can redistribute it and/or modify it under
|
||||
## the terms of the version 2.1 of the GNU Lesser General Public License
|
||||
|
2
hist.h
2
hist.h
@@ -36,7 +36,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef HIST_SIZE
|
||||
#define HIST_SIZE (1024*10)
|
||||
#define HIST_SIZE (1024*32)
|
||||
#endif
|
||||
|
||||
|
||||
|
15
input.c
15
input.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* input - nested input source file reader
|
||||
*
|
||||
* Copyright (C) 1999-2007,2014 David I. Bell
|
||||
* Copyright (C) 1999-2007,2014,2018 David I. Bell
|
||||
*
|
||||
* Calc is open software; you can redistribute it and/or modify it under
|
||||
* the terms of the version 2.1 of the GNU Lesser General Public License
|
||||
@@ -59,8 +59,8 @@ E_FUNC FILE *f_open(char *name, char *mode);
|
||||
E_FUNC FILE *curstream(void);
|
||||
|
||||
|
||||
#define TTYSIZE 100 /* reallocation size for terminal buffers */
|
||||
#define MAXDEPTH 10 /* maximum depth of input */
|
||||
#define TTYSIZE 8191 /* reallocation size for terminal buffers */
|
||||
#define MAXDEPTH 255 /* maximum depth of input */
|
||||
#define IS_READ 1 /* reading normally */
|
||||
#define IS_REREAD 2 /* reread current character */
|
||||
#define chartoint(ch) ((ch) & 0xff) /* make sure char is not negative */
|
||||
@@ -410,6 +410,7 @@ homeexpand(char *name)
|
||||
char *after; /* after the ~user or ~ */
|
||||
char *username; /* extracted username */
|
||||
size_t fullpath_len; /* length of fullpath */
|
||||
size_t snprintf_len; /* malloced snprintf buffer length */
|
||||
|
||||
/* firewall */
|
||||
if (name[0] != HOMECHAR)
|
||||
@@ -466,11 +467,13 @@ homeexpand(char *name)
|
||||
/*
|
||||
* build the fullpath given the home directory
|
||||
*/
|
||||
fullpath = (char *)malloc(strlen(home2)+strlen(after)+1);
|
||||
snprintf_len = strlen(home2)+strlen(after) + 1;
|
||||
fullpath = (char *)malloc(snprintf_len+1);
|
||||
if (fullpath == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
sprintf(fullpath, "%s%s", home2, after);
|
||||
snprintf(fullpath, snprintf_len, "%s%s", home2, after);
|
||||
fullpath[snprintf_len] = '\0'; /* paranoia */
|
||||
return fullpath;
|
||||
#endif /* Windoz free systems */
|
||||
}
|
||||
@@ -789,7 +792,7 @@ ttychar(void)
|
||||
{
|
||||
int ch; /* current char */
|
||||
int len; /* length of current command */
|
||||
STATIC char charbuf[1024];
|
||||
STATIC char charbuf[256*1024];
|
||||
|
||||
/*
|
||||
* If we have more to read from the saved command line, then do that.
|
||||
|
@@ -83,7 +83,7 @@ math_error(char *fmt, ...)
|
||||
#endif
|
||||
vsnprintf(calc_err_msg, MAXERROR, fmt, ap);
|
||||
va_end(ap);
|
||||
calc_err_msg[MAXERROR] = '\0';
|
||||
calc_err_msg[MAXERROR] = '\0'; /* paranoia */
|
||||
|
||||
/*
|
||||
* if we should longjmp, so do
|
||||
|
4
qmath.h
4
qmath.h
@@ -254,7 +254,9 @@ E_FUNC NUMBER *swap_HALF_in_NUMBER(NUMBER *dest, NUMBER *src, BOOL all);
|
||||
#define qhighbit(q) (zhighbit((q)->num))
|
||||
#define qlowbit(q) (zlowbit((q)->num))
|
||||
#define qdivcount(q1, q2) (zdivcount((q1)->num, (q2)->num))
|
||||
#define qlink(q) ((q)->links++, (q))
|
||||
/* operation on #q may be undefined, so replace with an inline-function */
|
||||
/* was: #define qlink(q) ((q)->links++, (q)) */
|
||||
static inline NUMBER* qlink(NUMBER* q) { if(q) { (q)->links++; } return q; }
|
||||
|
||||
#define qfree(q) {if (--((q)->links) <= 0) qfreenum(q);}
|
||||
|
||||
|
3
sha1.c
3
sha1.c
@@ -684,7 +684,7 @@ sha1_print(HASH *state)
|
||||
* the last full update or finalization. Thus it
|
||||
* may NOT be the actual hash value.
|
||||
*/
|
||||
sprintf(buf,
|
||||
snprintf(buf, DEBUG_SIZE,
|
||||
"sha1: 0x%08x%08x%08x%08x%08x data: %d octets",
|
||||
(int)state->h_union.h_sha1.digest[0],
|
||||
(int)state->h_union.h_sha1.digest[1],
|
||||
@@ -692,6 +692,7 @@ sha1_print(HASH *state)
|
||||
(int)state->h_union.h_sha1.digest[3],
|
||||
(int)state->h_union.h_sha1.digest[4],
|
||||
(int)state->h_union.h_sha1.datalen);
|
||||
buf[DEBUG_SIZE] = '\0'; /* paranoia */
|
||||
math_str(buf);
|
||||
} else {
|
||||
math_str("sha1 hash state");
|
||||
|
10
token.c
10
token.c
@@ -718,7 +718,7 @@ scanerror(int skip, char *fmt, ...)
|
||||
if (name) {
|
||||
snprintf(calc_err_msg, MAXERROR, "\"%s\", line %ld: ",
|
||||
name, linenumber());
|
||||
calc_err_msg[MAXERROR] = '\0'; /* firewall */
|
||||
calc_err_msg[MAXERROR] = '\0'; /* paranoia */
|
||||
len = strlen(calc_err_msg);
|
||||
if (len < MAXERROR) {
|
||||
vsnprintf(calc_err_msg+len, MAXERROR-len, fmt, ap);
|
||||
@@ -727,7 +727,7 @@ scanerror(int skip, char *fmt, ...)
|
||||
vsnprintf(calc_err_msg, MAXERROR, fmt, ap);
|
||||
}
|
||||
va_end(ap);
|
||||
calc_err_msg[MAXERROR] = '\0';
|
||||
calc_err_msg[MAXERROR] = '\0'; /* paranoia */
|
||||
|
||||
/* print error message if allowed */
|
||||
if (calc_print_scanerr_msg != 0) {
|
||||
@@ -782,7 +782,7 @@ scanerror(int skip, char *fmt, ...)
|
||||
default:
|
||||
snprintf(calc_err_msg, MAXERROR,
|
||||
"Unknown skip token for scanerror\n");
|
||||
calc_err_msg[MAXERROR] = '\0';
|
||||
calc_err_msg[MAXERROR] = '\0'; /* paranoia */
|
||||
if (calc_print_scanerr_msg != 0) {
|
||||
fprintf(stderr, "%s\n\n", calc_err_msg);
|
||||
}
|
||||
@@ -823,7 +823,7 @@ warning(char *fmt, ...)
|
||||
if (name) {
|
||||
snprintf(calc_warn_msg, MAXERROR, "\"%s\", line %ld: ",
|
||||
name, linenumber());
|
||||
calc_warn_msg[MAXERROR] = '\0'; /* firewall */
|
||||
calc_warn_msg[MAXERROR] = '\0'; /* paranoia */
|
||||
len = strlen(calc_warn_msg);
|
||||
if (len < MAXERROR) {
|
||||
vsnprintf(calc_warn_msg+len, MAXERROR-len, fmt, ap);
|
||||
@@ -832,7 +832,7 @@ warning(char *fmt, ...)
|
||||
vsnprintf(calc_warn_msg, MAXERROR, fmt, ap);
|
||||
}
|
||||
va_end(ap);
|
||||
calc_warn_msg[MAXERROR] = '\0';
|
||||
calc_warn_msg[MAXERROR] = '\0'; /* paranoia */
|
||||
|
||||
/* print the warning if allowed */
|
||||
if (calc_print_scanwarn_msg != 0) {
|
||||
|
2
value.c
2
value.c
@@ -2944,7 +2944,7 @@ printestr(VALUE *vp)
|
||||
bp = vp->v_nblock->blk;
|
||||
}
|
||||
i = bp->datalen;
|
||||
math_fmt("%ld,%d)", i, bp->blkchunk);
|
||||
math_fmt("%ld,%d)", i, (int) bp->blkchunk);
|
||||
cp = bp->data;
|
||||
if (i > 0) {
|
||||
math_str("={");
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* version - determine the version of calc
|
||||
*
|
||||
* Copyright (C) 1999-2017 David I. Bell and Landon Curt Noll
|
||||
* Copyright (C) 1999-2018 David I. Bell and Landon Curt Noll
|
||||
*
|
||||
* Primary author: David I. Bell
|
||||
*
|
||||
@@ -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 0 /* minor software level or 0 if not patched */
|
||||
#define MINOR_PATCH 8 /* minor software level or 0 if not patched */
|
||||
|
||||
|
||||
/*
|
||||
@@ -120,6 +120,7 @@ version(void)
|
||||
snprintf(verbuf, BUFSIZ,
|
||||
"%d.%d.%d.%d", calc_major_ver, calc_minor_ver,
|
||||
calc_major_patch, calc_minor_patch);
|
||||
verbuf[BUFSIZ] = '\0'; /* paranoia */
|
||||
|
||||
/*
|
||||
* save the versions string into a newly malloced buffer
|
||||
|
@@ -1,5 +1,5 @@
|
||||
TERMCONTROL=-DUSE_WIN32
|
||||
HAVE_VSPRINTF=-UDONT_HAVE_VSPRINTF
|
||||
HAVE_VSNPRINTF=-UDONT_HAVE_VSNPRINTF
|
||||
BYTE_ORDER=-DLITTLE_ENDIAN
|
||||
LONG_BITS=32
|
||||
HAVE_FPOS=-DHAVE_NO_FPOS
|
||||
|
175
zfunc.c
175
zfunc.c
@@ -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;
|
||||
|
Reference in New Issue
Block a user