Compare commits

...

36 Commits

Author SHA1 Message Date
Landon Curt Noll
769ac51f8c Release v2.14.0.10 2021-12-01 23:38:56 -08:00
Landon Curt Noll
cdda633369 Update CHANGES file to note previous 2 commits 2021-12-01 23:34:40 -08:00
Landon Curt Noll
50f349f4d7 Update copyright dates to account for 2021 mods 2021-12-01 23:28:59 -08:00
Landon Curt Noll
ef00e00328 Remove unnecessary spaces inbetween or next to tabs 2021-12-01 23:25:49 -08:00
Landon Curt Noll
bb041098bc Reduce the length of long lines 2021-12-01 23:15:06 -08:00
Landon Curt Noll
f794b8d859 Reduce global status constants
The constants:

	9, 9/10, 10/9, 24, 360, 400

are used by func.c only, so there were moved
from {q,z}math.{c,h} to func.c.

The constants:

	3, 4

are used by zrandom.c only, so there were moved
from {q,z}math.{c,h} to zrandom.c.
2021-12-01 22:50:52 -08:00
Landon Curt Noll
bd990cef1f Added freeglobals() to libcalc_call_me_last() 2021-12-01 21:56:01 -08:00
Landon Curt Noll
febb9d96b3 Convert freeh() call to zfree() call 2021-12-01 21:55:18 -08:00
Landon Curt Noll
13ae9b804e Add missing blank lines 2021-12-01 21:53:46 -08:00
Landon Curt Noll
56cc4897d6 Reapply memory leak fixes to zmod.c
Revert previously applied zmod.c mods and
then apply better mods to fix zmod memory leaks.
2021-12-01 21:48:13 -08:00
Landon Curt Noll
eb940e0a21 Fix paranoia guard in literal string alloc 2021-11-30 03:44:38 -08:00
Landon Curt Noll
f3adb35e36 Add string and symbol guard allocation paranoia 2021-11-30 03:40:40 -08:00
Landon Curt Noll
d1d365d7ba Added initialization paranoia 2021-11-30 03:37:20 -08:00
Landon Curt Noll
af214b166d Reorder zfree ops to assign NULL to ptr after free 2021-11-30 03:36:22 -08:00
Landon Curt Noll
51b933dfff Add initialization paranoia 2021-11-30 03:35:09 -08:00
Landon Curt Noll
c4e5007587 Clarify strlcpy size check 2021-11-30 03:33:48 -08:00
Landon Curt Noll
c838798f04 Fix more memory leaks, improve zfree() action 2021-11-29 01:55:53 -08:00
Landon Curt Noll
23d49a41fe Remove references to externals that are no longer used 2021-11-28 20:52:03 -08:00
Landon Curt Noll
3d300acca1 Improve internal pre-defined constant handling
Improved the way that internal pre-defined constants are managed.
Removed unused internal pre-defined constants.  Added code to
prevent an internal pre-defined constant (that was never
allocated) from being freed.
2021-11-28 20:47:52 -08:00
Landon Curt Noll
8f449ba6d2 Revert local test mistake in Makefile.local 2021-11-27 00:23:54 -08:00
Landon Curt Noll
f4d754b47d Checkpoint in valgrind work 2021-11-27 00:05:28 -08:00
Landon Curt Noll
fde724aa2d Release v2.14.0.9
The following are the changes in this release:

    Due to issues with clang and Apple Silicon, ARCH_CFLAGS is now,
    by default, empty:

	ARCH_CFLAGS=

    If you want to use, say, -march=native, then either change
    the Makefile or make with:

	make all ARCH_CFLAGS='-march=native'

    Added arch and hardware as GNU Makefile computed values.
    As with ${target}, ${arch} and ${hardware} is computed by uname:

	target: uname -a
	arch: uname -p
	hardware: uname -m

    Fixed compiling calc on Apple Silicon with homebrew.  On Apple
    Silicon, HomeBrew installs on into a different location.  The
    Makefile checks if ${hardware} is arm64 and adjusts the location
    of libraries such as readline and history accordingly.
2021-11-24 01:35:01 -08:00
Landon Curt Noll
e411a3e6bf Trim long lines in Makefile 2021-11-24 01:33:00 -08:00
Landon Curt Noll
7db81649b0 Fixed compiling for Apple Silicon arm64 w/HomeBrew 2021-11-24 01:25:49 -08:00
Landon Curt Noll
08fe6f13f4 Release v2.14.0.8
The following are the changes in this release:

    Identical to v2.14.0.7: now declared a stable release.
2021-11-23 00:04:09 -08:00
Landon Curt Noll
e11d159c81 Release v2.14.0.7
The following are the changes in this release:

    Fizzbin is a better word. :-)

    The help and man builtin commands now return an error when a
    help file cannot be opened, such as when there is no help file.

    Added palindrome.cal resource file.  For example, to find the
    largest (highly probable) prime palindrome under 280 decimal
    digits (text tweet limit):

	prevprimepal(1e280)
2021-11-07 20:36:07 -08:00
Landon Curt Noll
dfd66be871 Adjusted calc in prep for 2.14.0.7 release 2021-11-07 20:30:23 -08:00
Landon Curt Noll
27f977b545 Remove unnecessary leading line whitespace before a tab 2021-11-07 20:14:28 -08:00
Landon Curt Noll
2ca6e789ca Add ignore win32 to .gitignore 2021-11-07 20:11:21 -08:00
Landon Curt Noll
ff8f921ebc Fix CHANGES note for palindrome.cal 2021-11-07 18:39:43 -08:00
Landon Curt Noll
005b78227a Minor comment changes to palindrome.cal 2021-11-07 18:36:06 -08:00
Landon Curt Noll
b7a42a9d3d Optimize palindrome.cal
In cal/palindrome.cal:

Improved the performace of nextpal() and nextprimepal()
by adding and using palnextpal().

Improved the performace of prevpal() and prevprimepal()
by adding and using palprevpal().

Test showed that runs that took 0.0530 cpu seconds can
now be done in as little as 0.0327 cpu seconds.
2021-11-07 14:15:19 -08:00
Landon Curt Noll
3d1e938cb6 Remove user_debug references in palindrome.cal 2021-11-07 13:34:58 -08:00
Landon Curt Noll
8b98a7c1f6 Add cal/palindrome.cal resource file 2021-11-06 14:48:45 -07:00
Landon Curt Noll
dbf5acf5e8 Improved help error messages
The help and man commands now issue an error message when
the help file cannot be opened: say because there is a
help command typo and there is no such help file.
2021-11-06 12:47:19 -07:00
Landon Curt Noll
5fe5ab1c4b Minor help improvement
Fizzbin is better than gleet.
2021-11-06 12:44:16 -07:00
81 changed files with 1306 additions and 409 deletions

1
.gitignore vendored
View File

@@ -94,6 +94,7 @@ sample_rand
tags
terminal.h
ver_calc
win32/
# other commonly excluded patterns
#

134
CHANGES
View File

@@ -1,4 +1,56 @@
The following are the changes from calc version 2.14.0.0 to date:
The following are the changes from calc version 2.14.0.9 to date:
Due to issues with clang and Apple Silicon, ARCH_CFLAGS is now,
by default, empty:
ARCH_CFLAGS=
If you want to use, say, -march=native, then either change
the Makefile or make with:
make all ARCH_CFLAGS='-march=native'
Added arch and hardware as GNU Makefile computed values.
As with ${target}, ${arch} and ${hardware} is computed by uname:
target: uname -a
arch: uname -p
hardware: uname -m
Fixed compiling calc on Apple Silicon with homebrew. On Apple
Silicon, HomeBrew installs on into a different location. The
Makefile checks if ${hardware} is arm64 and adjusts the location
of libraries such as readline and history accordingly.
Pluged a number of memory leaks.
Fixed a few cases where v_subtype was not properly initialuzed.
Improved the way that internal pre-defined constants are managed.
Removed unused internal pre-defined constants. Added code to
prevent an internal pre-defined constant (that was never allocated)
from being freed.
Remove unnecessary spaces inbetween or next to tabs.
Update copright dates to account for 2021 modifications.
The following are the changes from calc version 2.14.0.7 to 2.14.0.8:
Fizzbin is a better word. :-)
The help and man builtin commands now return an error when a
help file cannot be opened, such as when there is no help file.
Added palindrome.cal resource file. For example, to find the
largest (highly probable) prime palindrome under 280 decimal
digits (text tweet limit):
prevprimepal(1e280)
The following are the changes from calc version 2.14.0.0 to 2.14.0.6:
The :-separated default CALCRC value has been reversed.
The default CALCRC was:
@@ -828,7 +880,7 @@ The following are the changes from calc version 2.12.5.4 to 2.12.5.6:
Rewrote gen_v1() in the lucas.cal resource file using the method
based on a paper:
"A note on primality tests for N = h*2^n-1", by Oystein J. Rodseth,
"A note on primality tests for N = h*2^n-1", by Oystein J. Rodseth,
Department of Mathematics, University of Bergen, BIT Numerical
Mathematics. 34 (3): pp 451-454.
@@ -887,13 +939,13 @@ The following are the changes from calc version 2.12.5.3 to 2.12.5.3:
macOS (Darwin) users who installed calc version 2.12.5.2
should, after installing version 2.12.5.3:
rm -rf /opt/calc
rm -rf /opt/calc
The following are the changes from calc version 2.12.5.1 to 2.12.5.2:
NOTE: calc version 2.12.5.2, for macOS (Darwin) users,
installed under /opt/calc. We neglected to mention this
installed under /opt/calc. We neglected to mention this
AND /usr/local would have been a better choice. Sorry!
Fixed in calc version 2.12.5.3.
@@ -966,7 +1018,7 @@ The following are the changes from calc version 2.12.4.14 to 2.12.5.0:
For Apple OS X / Darwin target:
MACOSX_DEPLOYMENT_TARGET is no longer defined
MACOSX_DEPLOYMENT_TARGET is no longer defined
using clang compiler
By default, -install-name is used when forming shared libs.
@@ -1010,9 +1062,9 @@ The following are the changes from calc version 2.12.4.14 to 2.12.5.0:
for mul2, sq2, and pow2. However, it has been shown that this
code is not correct. Suggestions for a replacement are welcome!
calc -u 'read alg_config; config("user_debug", 2),; best_mul2();'
calc -u 'read alg_config; config("user_debug", 2),; best_sq2();'
calc -u 'read alg_config; config("user_debug", 2),; best_pow2();'
calc -u 'read alg_config; config("user_debug", 2),; best_mul2();'
calc -u 'read alg_config; config("user_debug", 2),; best_sq2();'
calc -u 'read alg_config; config("user_debug", 2),; best_pow2();'
Fixed a number of pedantic compiler warnings.
@@ -1179,7 +1231,7 @@ The following are the changes from calc version 2.12.4.6 to version 2.12.4.10:
With the exception of 3 source files, we became "picky" about
line lengths and other issues reported by the picky tool:
cal/test8900.cal
cal/test8900.cal
cal/set8700.line
help/errorcodes.sed
@@ -1235,7 +1287,7 @@ The following are the changes from calc version 2.12.4.0 to 2.12.4.2:
Added prep makefile rule to make is easier to compile calc without
an optimizer. By doing:
make clobber prep
make clobber prep
one may build a calc binary that is easier to debug.
@@ -1392,7 +1444,7 @@ The following are the changes from calc version 2.12.1.1 to 2.12.2.2:
what was calc-something.tar.gz is now calc-something.tar.bz2.
To "uncompress" use:
bunzip2 calc-something.tar.bz2
bunzip2 calc-something.tar.bz2
On some systems, one may untar directly by:
@@ -1457,7 +1509,7 @@ The following are the changes from calc version 2.12.1.10 to 2.12.2:
Renamed the following variables related to calc error processing:
int calc_jmp ==> int calc_use_matherr_jmpbuf
jmp_buf calc_jmp_buf ==> jmp_buf calc_matherr_jmpbuf
jmp_buf calc_jmp_buf ==> jmp_buf calc_matherr_jmpbuf
int post_init ==> int calc_use_scanerr_jmpbuf
jmp_buf jmpbuf ==> jmpbuf calc_scanerr_jmpbuf
@@ -1472,7 +1524,7 @@ The following are the changes from calc version 2.12.1.10 to 2.12.2:
Parse/scan errors will not be printed if calc_print_scanerr_msg
is zero. By default:
int calc_print_scanerr_msg = 1;
int calc_print_scanerr_msg = 1;
This variable is declared in the lib_calc.h include file. Storage
comes from libcalc.
@@ -1480,7 +1532,7 @@ The following are the changes from calc version 2.12.1.10 to 2.12.2:
Parse/scan warnings will not be printed if calc_print_scanwarn_msg
is zero. By default:
int calc_print_scanwarn_msg = 1;
int calc_print_scanwarn_msg = 1;
This variable is declared in the lib_calc.h include file. Storage
comes from libcalc.
@@ -1516,16 +1568,16 @@ The following are the changes from calc version 2.12.1.10 to 2.12.2:
Replaced the concept of compiler sets in the Makefile with
host target section in the Makefile. Initial host targets are:
Linux
Linux
Darwin
FreeBSD
(default) <<== Target does not match any previous target name
Simple
NOTE: If your target is not supported below and the default target
NOTE: If your target is not supported below and the default target
is not suitable for your needs, please send to the:
calc-contrib at asthe dot com
calc-contrib at asthe dot com
Email address an "ifeq ($(target),YOUR_TARGET_NAME)"
... "endif" set of lines from the Makefile so that
@@ -1670,7 +1722,7 @@ The following are the changes from calc version 2.12.1.8 to 2.12.1.9:
comments. Improved calc comment documentation in "help unexpected"
to help other avoid similar mistakes. Calc comments are of the form:
/* c style comments */
/* c style comments */
/*
* multi-line
* comments
@@ -1684,7 +1736,7 @@ The following are the changes from calc version 2.12.1.8 to 2.12.1.9:
Documented these help commands in "help help":
help ->
help ->
help *
help .
help %
@@ -1865,7 +1917,7 @@ The following are the changes from calc version 2.12.0 to 2.12.0.8:
Added the builtin function fpathopen() to open a file while
searching along a path:
; fd2 = fpathopen("tmp/date", "r", ".:~:~sc:/tmp:/var/tmp:/var")
; fd2 = fpathopen("tmp/date", "r", ".:~:~sc:/tmp:/var/tmp:/var")
; print fd2
"/var/tmp/date"
@@ -1915,12 +1967,12 @@ The following are the changes from calc version 2.12.0 to 2.12.0.8:
level. When comparing with older source, one may use the -b argument
of the diff command to ignore changes in amount of white space:
diff -b -r -u calc-2.11.11 calc-2.12.0
diff -b -r -u calc-2.11.11 calc-2.12.0
The read, write, and help commands use the value of global string
variable if the symbol name starts with a $. For example:
global x = "lucas.cal";
global x = "lucas.cal";
read $x; /* same as read lucas.cal or read "lucas.cal" */
Added dotest.cal resource. Based on a design by Ernest Bowen
@@ -2030,7 +2082,7 @@ The following are the changes from calc version 2.12.0 to 2.12.0.8:
Changed the default values for the following config() parameters:
config("mul2") == 1780
config("mul2") == 1780
config("sq2") == 3388
config("pow2") == 176
@@ -2125,10 +2177,10 @@ The following are the changes from calc version 2.12.0 to 2.12.0.8:
value is TRUE by default. Examples of variable name collisions
include when:
* both local and static variables have the same name
* both local and global variables have the same name
* both function parameter and local variables have the same name
* both function parameter and global variables have the same name
* both local and static variables have the same name
* both local and global variables have the same name
* both function parameter and local variables have the same name
* both function parameter and global variables have the same name
Fix of a bug which causes some static variables not to be correctly
unscoped when their identifiers are used in a global declaration.
@@ -2148,7 +2200,7 @@ The following are the changes from calc version 2.12.0 to 2.12.0.8:
Changed the definition of the function ssq() to enable list arguments
to be processed in the same way as in sum(). For example:
ssq(1,2, list(3,4,list(5,6)), list(), 7, 8)
ssq(1,2, list(3,4,list(5,6)), list(), 7, 8)
returns the value of 1^2 + 2^2 + ... + 8^2 == 204.
@@ -2156,7 +2208,7 @@ The following are the changes from calc version 2.12.0 to 2.12.0.8:
various ways of evaluating sums, sums of squares, etc, for large
lists and matrices. For example:
read sumtimes
read sumtimes
doalltimes(1e6)
Calc now ignores carriage returns (\r), vertical tabs (\v), and
@@ -2195,7 +2247,7 @@ The following are the changes from calc version 2.11.10.1 to 2.11.11:
Fixed a bug reported by the sourceforge user: cedars where:
ln(exp(6)) == 3 /* WRONG!!! */
ln(exp(6)) == 3 /* WRONG!!! */
incorrectly returned 1. This bug was fixed by Ernest Bowen
<ebowen at une dot edu dot au>. The regression test
@@ -2300,7 +2352,7 @@ The following are the changes from calc version 2.11.10 to 2.11.10:
Fixed -d so that:
calc -d 2/3
calc -d 2/3
will print 0.66666666666666666667 without the leading tilde as
advertised in the man page.
@@ -2320,7 +2372,7 @@ The following are the changes from calc version 2.11.10 to 2.11.10:
Added custom function:
custom("pmodm127", q)
custom("pmodm127", q)
to compute 2^(2^127-1) mod q. While currently slower than just
doing pmod(2,2^127-1,q), it is added to give an example of a
@@ -2411,7 +2463,7 @@ The following are the changes from calc version 2.11.8.0 to 2.11.8.1:
configuration (calc -n or config("all", "newstd")) is now the default
calc configuration. The flag:
calc -O
calc -O
was added to get the old classic calc configuration. The flag command
line flag, -n, now does nothing. Use of -n is deprecated and may go
@@ -2424,7 +2476,7 @@ The following are the changes from calc version 2.11.8.0 to 2.11.8.1:
and oldstd -n & newstd classic cfg default
--------------------------------------------------------
epsilon 1e-20 1e-10 1e-20 1e-20
quo 2 2 2 2
quo 2 2 2 2
outround 2 24 2 24
leadzero 0 1 0 1
fullzero 0 1 0 0
@@ -2588,16 +2640,16 @@ The following are the changes from calc version 2.11.5.5 to 2.11.5.9:
Now using version numbers of one of these forms:
x.y.z.w
x.y.z
x.y
x.y.z.w
x.y.z
x.y
Changed the READLINE_LIB Makefile variable to not link with -lreadline
by default. If you do have readline, we recommend that you use it.
If you can install the GNU readline:
http://freshmeat.net/projects/gnureadline/
http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html
http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html
we recommend it. But if not, you should set the USE_READLINE,
READLINE_LIB, and READLINE_INCLUDE Makefile variables to empty.
@@ -2669,7 +2721,7 @@ The following are the changes from calc version 2.11.5t4.1 to 2.11.5t4.4:
Added subject requirements for the calc-tester-request and
calc-bugs-mail Email aliases. See:
http://www.isthe.com/chongo/tech/comp/calc/email.html
http://www.isthe.com/chongo/tech/comp/calc/email.html
for details.
@@ -2836,7 +2888,7 @@ The following are the changes from calc version 2.11.5t2 to 2.11.5t2.1:
Applied a bug fix from Ernest Bowen <ernie at turing dot une dot
edu dot au> dealing with one-line "static" declaration like:
static a = 1, b;
static a = 1, b;
Added regression test 8310 to test for the static bug fix.
@@ -2949,7 +3001,7 @@ The following are the changes from calc version 2.11.5t0 to 2.11.5t1.1:
Configuration values that used to return "true" or "false" now return
1 (a true value) or 0 (a false value). Thus one can do:
if (config("tab")) { ... } else { ... }
if (config("tab")) { ... } else { ... }
The configuration values that now return 1 or 0 are:

View File

@@ -87,7 +87,7 @@ Installing calc from the bzip2-ed tarball in 4 easy steps:
BINDIR Where to install calc binary files.
LIBDIR Where to install calc link library (*.a) files.
CALC_SHAREDIR Where to install calc help, .cal, startup, and
config files.
config files.
You may want to change the default installation locations for
these values, which are based on the 4 values listed above:
@@ -108,13 +108,13 @@ Installing calc from the bzip2-ed tarball in 4 easy steps:
For example, if:
BINDIR= /usr/bin
BINDIR= /usr/bin
LIBDIR= /usr/lib
CALC_SHAREDIR= /usr/share/calc
and if:
T= /var/tmp/testing
T= /var/tmp/testing
Then the installation locations will be:

View File

@@ -216,7 +216,7 @@ Your program must handle parse/scan errors in one of two ways:
/* report the parse/scan */
if (calc_use_scanerr_jmpbuf == 0) {
printf("parse error: %s\n", calc_err_msg);
}
}
/* initialize calc after the longjmp */
initialize();
@@ -622,7 +622,7 @@ call. This is not required, but is does bring things to a closure.
The function libcalc_call_me_last() takes no args and returns void. You
need call libcalc_call_me_last() only once.
## Copyright (C) 1999 David I. Bell and Landon Curt Noll
## Copyright (C) 1999,2021 David I. Bell and 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

View File

@@ -46,6 +46,12 @@
ifeq ($(target),)
target=$(shell uname -s 2>/dev/null)
endif
ifeq ($(arch),)
arch=$(shell uname -p 2>/dev/null)
endif
ifeq ($(hardware),)
hardware=$(shell uname -m 2>/dev/null)
endif
# The shell used by this Makefile
#
@@ -135,15 +141,31 @@ USE_READLINE= -DUSE_READLINE
#READLINE_LIB= -L/usr/gnu/lib -lreadline -lhistory -lncurses
#READLINE_LIB= -L${PREFIX}/lib -lreadline -lhistory -lncurses
ifeq ($(target),Darwin)
# homebrew installs readline & history libs in ${PREFIX}/opt/readline/lib
ifeq ($(hardware),arm64)
# Darwin arm64 homebrew installs readline & history
# libs in /opt/homebrew/opt/readline/lib
READLINE_LIB= -L/opt/homebrew/opt/readline/lib -lreadline -lhistory -lncurses
else
# Assume Darwin non-arm64 is x86_64
# Darwin x86_64 homebrew installs readline & history
# libs in ${PREFIX}/opt/readline/lib
READLINE_LIB= -L${PREFIX}/opt/readline/lib -lreadline -lhistory -lncurses
endif
else
READLINE_LIB= -lreadline -lhistory -lncurses
endif
#
ifeq ($(target),Darwin)
# homebrew installs readline & history *.h under ${PREFIX}/opt/readline/include
ifeq ($(hardware),arm64)
# Darwin arm64 homebrew installs readline & history *.h
# under /opt/homebrew/opt/readline/include
READLINE_INCLUDE= -I${PREFIX}/opt/homebrew/opt/readline/include
else
# Assume Darwin non-arm64 is x86_64
# Darwin x86_64 homebrew installs readline & history *.h
# under ${PREFIX}/opt/readline/include
READLINE_INCLUDE= -I${PREFIX}/opt/readline/include
endif
else
READLINE_INCLUDE=
endif
@@ -361,7 +383,7 @@ update_version:
fi; \
${RM} -f "$$i.tmp"; \
${SED} -e 's/^VERSION=.*/VERSION= '"$$CALC_VERSION"'/' \
$$i > $$i.tmp; \
$$i > $$i.tmp; \
if ${CMP} -s "$$i" "$$i.tmp"; then \
${RM} -f "$$i.tmp"; \
echo "versions already up to date in $$i"; \

View File

@@ -79,6 +79,12 @@ SHELL= /bin/sh
ifeq ($(target),)
target=$(shell uname -s 2>/dev/null)
endif
ifeq ($(arch),)
arch=$(shell uname -p 2>/dev/null)
endif
ifeq ($(hardware),)
hardware=$(shell uname -m 2>/dev/null)
endif
#endif /* end of skip for non-Gnu makefiles */
##############################################################################
@@ -748,9 +754,9 @@ endif
# LIBDIR= ${PREFIX}/lib
# CALC_SHAREDIR= ${PREFIX}/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 ${PREFIX} tree.
# 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 ${PREFIX} tree.
#if 0 /* start of skip for non-Gnu makefiles */
ifeq ($(target),Darwin)
@@ -949,12 +955,12 @@ CATEXT= 1
# If NROFF is non-empty, then
#
# ${NROFF} ${NROFF_ARG} calc.1 > ${CATDIR}/calc.${CATEXT}
# is used to build and install the cat page
# is used to build and install the cat page
#
# else (NROFF is empty)
#
# ${MANMAKE} calc.1 ${CATDIR}
# is used to build and install the cat page
# is used to build and install the cat page
# else
#
# The cat page is not built or installed
@@ -1205,7 +1211,7 @@ EXT=
# The default calc versions
#
VERSION= 2.14.0.6
VERSION= 2.14.0.10
# Names of shared libraries with versions
#
@@ -1280,8 +1286,8 @@ EXTRA_LDFLAGS=
# The ARCH_CFLAGS are ${CC} when compiling C files. They follow
# CCMISC and precede EXTRA_CFLAGS.
#
ARCH_CFLAGS= -march=native
#ARCH_CFLAGS=
ARCH_CFLAGS=
#ARCH_CFLAGS= -march=native
# COMMON_CFLAGS are the common ${CC} flags used for all programs, both
# intermediate and final calc and calc related programs
@@ -5064,7 +5070,7 @@ endif
fi
-${Q} if [ -f calc-static${EXT} ]; then \
if ${CMP} -s calc-static${EXT} \
${T}${BINDIR}/calc-static${EXT}; then \
${T}${BINDIR}/calc-static${EXT}; then \
${TRUE}; \
else \
${RM} -f ${T}${BINDIR}/calc-static.new${EXT}; \
@@ -5117,23 +5123,23 @@ endif
else \
${RM} -f ${T}${LIBDIR}/libcalc${LIB_EXT_VERSION}.new; \
${CP} -f libcalc${LIB_EXT_VERSION} \
${T}${LIBDIR}/libcalc${LIB_EXT_VERSION}.new; \
${T}${LIBDIR}/libcalc${LIB_EXT_VERSION}.new; \
${CHMOD} 0644 ${T}${LIBDIR}/libcalc${LIB_EXT_VERSION}.new; \
${MV} -f ${T}${LIBDIR}/libcalc${LIB_EXT_VERSION}.new \
${T}${LIBDIR}/libcalc${LIB_EXT_VERSION}; \
${T}${LIBDIR}/libcalc${LIB_EXT_VERSION}; \
echo "installed ${T}${LIBDIR}/libcalc${LIB_EXT_VERSION}"; \
${LN} -f -s libcalc${LIB_EXT_VERSION} \
${T}${LIBDIR}/libcalc${LIB_EXT}; \
${T}${LIBDIR}/libcalc${LIB_EXT}; \
echo "installed ${T}${LIBDIR}/libcalc${LIB_EXT}"; \
${RM} -f ${T}${LIBDIR}/libcustcalc${LIB_EXT_VERSION}.new; \
${CP} -f custom/libcustcalc${LIB_EXT_VERSION} \
${T}${LIBDIR}/libcustcalc${LIB_EXT_VERSION}.new; \
${T}${LIBDIR}/libcustcalc${LIB_EXT_VERSION}.new; \
${CHMOD} 0644 ${T}${LIBDIR}/libcustcalc${LIB_EXT_VERSION}.new; \
${MV} -f ${T}${LIBDIR}/libcustcalc${LIB_EXT_VERSION}.new \
${T}${LIBDIR}/libcustcalc${LIB_EXT_VERSION}; \
${T}${LIBDIR}/libcustcalc${LIB_EXT_VERSION}; \
echo "installed ${T}${LIBDIR}/libcustcalc${LIB_EXT_VERSION}"; \
${LN} -f -s libcustcalc${LIB_EXT_VERSION} \
${T}${LIBDIR}/libcustcalc${LIB_EXT}; \
${T}${LIBDIR}/libcustcalc${LIB_EXT}; \
echo "installed ${T}${LIBDIR}/libcalc${LIB_EXT}"; \
if [ -z "${T}" -o "/" = "${T}" ]; then \
if [ ! -z "${LDCONFIG}" ]; then \
@@ -5396,7 +5402,7 @@ calc-symlink:
; do \
if [ -e "${T}$$i" ]; then \
if [ ! -L "$$i" -a "${T}$$i" -ef "$$i" ]; then \
echo "ERROR: ${T}$$i is the same as $$i" 1>&2; \
echo "ERROR: ${T}$$i is the same as $$i" 1>&2; \
else \
if [ -e "$$i" ]; then \
echo ${RM} -f "$$i"; \
@@ -5404,7 +5410,7 @@ calc-symlink:
fi; \
echo ${LN} -s "${T}$$i" "$$i"; \
${LN} -s "${T}$$i" "$$i"; \
fi; \
fi; \
else \
echo "Warning: not found: ${T}$$i" 1>&2; \
fi; \

View File

@@ -275,17 +275,17 @@ CALC_FILES= README alg_config.cal beer.cal bernoulli.cal \
constants.cal deg.cal dms.cal dotest.cal ellip.cal factorial.cal \
factorial2.cal gvec.cal hello.cal hms.cal infinities.cal intfile.cal \
intnum.cal lambertw.cal linear.cal lnseries.cal lucas.cal \
lucas_chk.cal mersenne.cal mfactor.cal mod.cal natnumset.cal pell.cal \
pi.cal pix.cal pollard.cal poly.cal prompt.cal psqrt.cal qtime.cal \
quat.cal randbitrun.cal randmprime.cal randombitrun.cal randomrun.cal \
randrun.cal regress.cal repeat.cal screen.cal seedrandom.cal \
set8700.cal set8700.line smallfactors.cal solve.cal \
specialfunctions.cal statistics.cal strings.cal sumsq.cal sumtimes.cal \
surd.cal test1700.cal test2300.cal test2600.cal test2700.cal \
test3100.cal test3300.cal test3400.cal test3500.cal test4000.cal \
test4100.cal test4600.cal test5100.cal test5200.cal test8400.cal \
test8500.cal test8600.cal test8900.cal toomcook.cal unitfrac.cal \
varargs.cal xx_print.cal zeta2.cal
lucas_chk.cal mersenne.cal mfactor.cal mod.cal natnumset.cal \
palindrome.cal pell.cal pi.cal pix.cal pollard.cal poly.cal prompt.cal \
psqrt.cal qtime.cal quat.cal randbitrun.cal randmprime.cal \
randombitrun.cal randomrun.cal randrun.cal regress.cal repeat.cal \
screen.cal seedrandom.cal set8700.cal set8700.line smallfactors.cal \
solve.cal specialfunctions.cal statistics.cal strings.cal sumsq.cal \
sumtimes.cal surd.cal test1700.cal test2300.cal test2600.cal \
test2700.cal test3100.cal test3300.cal test3400.cal test3500.cal \
test4000.cal test4100.cal test4600.cal test5100.cal test5200.cal \
test8400.cal test8500.cal test8600.cal test8900.cal toomcook.cal \
unitfrac.cal varargs.cal xx_print.cal zeta2.cal
# These calc files are now obsolete and are removed by the install rule.
#
@@ -461,7 +461,7 @@ uninstall:
continue; \
fi; \
if [ -f "${T}${CALC_SHAREDIR}/$$i" ]; then \
${RM} -f "${T}${CALC_SHAREDIR}/$$i"; \
${RM} -f "${T}${CALC_SHAREDIR}/$$i"; \
if [ -f "${T}${CALC_SHAREDIR}/$$i" ]; then \
echo "cannot uninstall ${T}${CALC_SHAREDIR}/$$i"; \
else \

View File

@@ -186,7 +186,7 @@ bernoulli.cal
Calculate the nth Bernoulli number.
NOTE: There is now a bernoulli() builtin function. This file is
left here for backward compatibility and now simply returns
left here for backward compatibility and now simply returns
the builtin function.
@@ -767,7 +767,7 @@ lucas.cal
prove that h*2^n-1 is prime or not prime.
NOTE: Some call this term u(0). The function gen_u0(h, n, v1)
simply calls gen_u2(h, n, v1) for such people. :-)
simply calls gen_u2(h, n, v1) for such people. :-)
gen_v1(h, v)
@@ -879,6 +879,38 @@ natnumset.cal
user-specified bound.
palindrome.cal
digitof(val,place)
copalplace(d,place)
upperhalf(val)
mkpal(val)
mkpalmiddigit(val,digit)
ispal(val)
nextpal(val)
prevpal(val)
nextprimepal(val)
prevprimepal(val)
Functions to form and manipulate palendromes in base 10.
Important functions are:
Find the next / previous palindrome:
nextpal(val)
prevpal(val)
Test if a value is a palindrome:
ispal(val)
Find the next / previous palindrome that is a (highly probable) prime:
nextprimepal(val)
prevprimepal(val)
pell.cal
pellx(D)
@@ -1435,7 +1467,7 @@ sumtimes.cal
the list or matrix to use. The doalltimes() function will run
all of the sumtimes tests. For example:
doalltimes(1e6);
doalltimes(1e6);
surd.cal

View File

@@ -474,7 +474,7 @@ define best_mul2()
*/
while (low+1 < high) {
/* try the mid-point */
/* try the mid-point */
mid = int((low+high)/2);
if (config("user_debug") > 0) {
printf("testing multiply alg1/alg2 ratio for len = %d\n", mid);
@@ -497,7 +497,7 @@ define best_mul2()
low = mid;
high = mid;
if (config("user_debug") > 0) {
printf("\twe are close enough to unity ratio at: %d\n", mid);
printf("\twe are close enough to unity ratio at: %d\n", mid);
}
break;
}
@@ -505,7 +505,7 @@ define best_mul2()
/* bump lower range up if we went over */
if (ratio > 1.0) {
if (config("user_debug") > 2) {
printf("\tmove low from %d up to %d\n",
printf("\tmove low from %d up to %d\n",
low, mid);
}
low = mid;
@@ -513,7 +513,7 @@ define best_mul2()
/* drop higher range down if we went under */
} else {
if (config("user_debug") > 2) {
printf("\tmove high from %d down to %d\n",
printf("\tmove high from %d down to %d\n",
high, mid);
}
high = mid;
@@ -522,7 +522,7 @@ define best_mul2()
/* report on test loop progress */
if (config("user_debug") > 1) {
printf("\tsetting low: %d high: %d diff: %d\n",
low, high, high-low);
low, high, high-low);
}
}
@@ -884,7 +884,7 @@ define best_sq2()
high *= expand;
if (config("user_debug") > 1) {
printf(" expand the next test range by a factor of %d\n",
expand);
expand);
}
/*
@@ -956,7 +956,7 @@ define best_sq2()
*/
while (low+1 < high) {
/* try the mid-point */
/* try the mid-point */
mid = int((low+high)/2);
if (config("user_debug") > 0) {
printf("testing square alg1/alg2 ratio for len = %d\n", mid);
@@ -979,7 +979,7 @@ define best_sq2()
low = mid;
high = mid;
if (config("user_debug") > 0) {
printf("\twe are close enough to unity ratio at: %d\n", mid);
printf("\twe are close enough to unity ratio at: %d\n", mid);
}
break;
}
@@ -987,7 +987,7 @@ define best_sq2()
/* bump lower range up if we went over */
if (ratio > 1.0) {
if (config("user_debug") > 2) {
printf("\tmove low from %d up to %d\n",
printf("\tmove low from %d up to %d\n",
low, mid);
}
low = mid;
@@ -995,7 +995,7 @@ define best_sq2()
/* drop higher range down if we went under */
} else {
if (config("user_debug") > 2) {
printf("\tmove high from %d down to %d\n",
printf("\tmove high from %d down to %d\n",
high, mid);
}
high = mid;
@@ -1004,7 +1004,7 @@ define best_sq2()
/* report on test loop progress */
if (config("user_debug") > 1) {
printf("\tsetting low: %d high: %d diff: %d\n",
low, high, high-low);
low, high, high-low);
}
}
@@ -1385,7 +1385,7 @@ define best_pow2()
printf(" pmod alg1/alg2 ratio = %.3f\n", ratio);
if (ratio > 1.0 && ratio <= 1.02) {
printf(" while alg1 is slightly better than alg2, "
"it is not clearly better\n");
"it is not clearly better\n");
}
}
} while (ratio <= 1.02);
@@ -1420,7 +1420,7 @@ define best_pow2()
high *= expand;
if (config("user_debug") > 1) {
printf(" expand the next test range by a factor of %d\n",
expand);
expand);
}
/*
@@ -1455,7 +1455,7 @@ define best_pow2()
*/
while (low+1 < high) {
/* try the mid-point */
/* try the mid-point */
mid = int((low+high)/2);
if (config("user_debug") > 0) {
printf("testing pow2 alg1/alg2 ratio for len = %d\n", mid);
@@ -1478,7 +1478,7 @@ define best_pow2()
low = mid;
high = mid;
if (config("user_debug") > 0) {
printf("\twe are close enough to unity ratio at: %d\n", mid);
printf("\twe are close enough to unity ratio at: %d\n", mid);
}
break;
}
@@ -1486,7 +1486,7 @@ define best_pow2()
/* bump lower range up if we went over */
if (ratio > 1.0) {
if (config("user_debug") > 2) {
printf("\tmove low from %d up to %d\n",
printf("\tmove low from %d up to %d\n",
low, mid);
}
low = mid;
@@ -1494,7 +1494,7 @@ define best_pow2()
/* drop higher range down if we went under */
} else {
if (config("user_debug") > 2) {
printf("\tmove high from %d down to %d\n",
printf("\tmove high from %d down to %d\n",
high, mid);
}
high = mid;
@@ -1503,7 +1503,7 @@ define best_pow2()
/* report on test loop progress */
if (config("user_debug") > 1) {
printf("\tsetting low: %d high: %d diff: %d\n",
low, high, high-low);
low, high, high-low);
}
}

View File

@@ -40,7 +40,7 @@ define Z(x, eps_term)
/* obtain the error term */
if (isnull(eps_term)) {
eps = epsilon();
eps = epsilon();
} else {
eps = eps_term;
}
@@ -81,7 +81,7 @@ define P(x, eps_term)
/* obtain the error term */
if (isnull(eps_term)) {
eps = epsilon();
eps = epsilon();
} else {
eps = eps_term;
}

View File

@@ -188,7 +188,7 @@ define dms_abs(a)
/* firewall - just absolute value non dms objects */
if (! istype(a, ans)) {
return abs(a);
return abs(a);
}
/* compute degrees */

View File

@@ -157,7 +157,7 @@ define dotest(dotest_file, dotest_code = 0, dotest_maxcond = -1)
* test the close of the line file
*/
printf("%d-: detected %d error condition(s), many of which may be OK\n",
dotest_code, dotest_old_errcount-dotest_errcnt);
dotest_code, dotest_old_errcount-dotest_errcnt);
printf("%d-: closing line file: %d\n", dotest_code, dotest_file);
fclose(dotest_f_file);

View File

@@ -56,7 +56,7 @@ define __CZ__factor_factorial(n,start){
if(start){
if(!isint(start) && start < 0 && start > n)
return newerror("__CZ__factor_factorial(n,start): value of "
"parameter 'start' out of range");
"parameter 'start' out of range");
if(start == n && isprime(n)){
prime_list = mat[1 , 2];
prime_list[0,0] = n;
@@ -64,7 +64,7 @@ define __CZ__factor_factorial(n,start){
}
else if(!isprime(start) && nextprime(start) >n)
return newerror("__CZ__factor_factorial(n,start): value of parameter "
"'start' out of range");
"'start' out of range");
else{
if(!isprime(start)) prime = nextprime(start);
else prime = start;
@@ -225,11 +225,11 @@ define __CZ__multiply_factored_factorial(matrix,stop){
if(!ismat(matrix))
return newerror("__CZ__multiply_factored_factorial(matrix): "
"argument matrix not a matrix ");
"argument matrix not a matrix ");
if(!matrix[0,0])
return
newerror("__CZ__multiply_factored_factorial(matrix): "
"matrix[0,0] is null/0");
"matrix[0,0] is null/0");
if(!isnull(stop))
pix = stop;
@@ -376,7 +376,7 @@ define bigcatalan(n){
/*
df(-111) = -1/3472059605858239446587523014902616804783337112829102414124928
7753332469144201839599609375
7753332469144201839599609375
df(-3+1i) = 0.12532538977287649201-0.0502372106177184607i
df(2n + 1) = (2*n)!/(n!*2^n)
@@ -427,7 +427,7 @@ define doublefactorial(n){
*/
eps=epsilon(epsilon()*1e-2);
ret = 2^(n/2-1/4 * cos(pi()* n)+1/4) * pi()^(1/4 *
cos(pi()* n)-1/4)* gamma(n/2+1);
cos(pi()* n)-1/4)* gamma(n/2+1);
epsilon(eps);
return ret;
}

View File

@@ -188,7 +188,7 @@ define hms_abs(a)
/* firewall - just absolute value non hms objects */
if (! istype(a, ans)) {
return abs(a);
return abs(a);
}
/* compute hours */

View File

@@ -156,7 +156,7 @@ define be2file(v, filename)
*/
octlen = int((highbit(v)+8) / 8);
for (i=octlen-1; i >= 0; --i) {
fputc(fd, char(v >> (i*8)));
fputc(fd, char(v >> (i*8)));
}
/*

View File

@@ -731,7 +731,7 @@ rodseth_xhn(x, h, n)
return 0;
}
/*
/*
* Check for jacobi(x-2, h*2^n-1) == 1 (Ref4, condition 1) part 1
*/
testval = h*2^n-1;
@@ -739,7 +739,7 @@ rodseth_xhn(x, h, n)
return 0;
}
/*
/*
* Check for jacobi(x+2, h*2^n-1) == -1 (Ref4, condition 1) part 2
*/
if (jacobi(x+2, testval) != -1) {

641
cal/palindrome.cal Normal file
View File

@@ -0,0 +1,641 @@
/*
* palindrome - palindrome utilities
*
* Copyright (C) 2021 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
* as published by the Free Software Foundation.
*
* Calc is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
* Public License for more details.
*
* A copy of version 2.1 of the GNU Lesser General Public License is
* distributed with calc under the filename COPYING-LGPL. You should have
* received a copy with calc; if not, write to Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Under source code control: 2021/11/06 14:35:37
* File existed as early as: 2021
*
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
/*
* digitof - return the a digit of a value
*
* NOTE: We assume base 10 digits and place 1 is the units digit.
*
* given:
* val value to find a digit of
* place digit place
*
* returns:
* value (>= 0 and < 10) that is the place-th digit of val
* or 0 if place is not a digit of val
*/
define digitof(val, place)
{
local d; /* length of val in digits */
/* determine length */
d = digits(val);
/* firewall - return 0 if digit place doesn't exist */
if (place < 1 || place > d) {
return 0;
}
/* return the place-th digit of val as a single digit */
return (val // (10^(place-1))) % 10;
}
/*
* copalplace - determine the other place in a palindrome
*
* NOTE: We assume base 10 digits and place 1 is the units digit.
*
* given:
* d digits of a value
* place digit place
*
* returns:
* given palindrome val, the other digit paired with place
* or 0 if place is not a digit of val
*/
define copalplace(d, place)
{
/* firewall - return 0 if digit place doesn't exist */
if (d < 1 || place < 1 || place > d) {
return 0;
}
/* return digit coplace */
return d+1 - place;
}
/*
* upperhalf - return the upper half of a palindrome
*
* NOTE: We assume base 10 digits and place 1 is the units digit.
*
* NOTE: When the value has an odd number of digits, the upper half
* includes the middle digit.
*
* given:
* val a value
*
* returns:
* the upper half digits of a value
*/
define upperhalf(val)
{
local d; /* length of val in digits */
local halfd; /* length of upper hand of val */
/* determine length */
d = digits(val);
halfd = d // 2;
/* return upper half */
return (val // 10^halfd);
}
/*
* mkpal - make a value into a palindrome
*
* NOTE: We assume base 10 digits and place 1 is the units digit.
*
* given:
* val a value
*
* returns:
* val as a palindrome with lower half being reverse digits of val
*/
define mkpal(val)
{
local d; /* length of val in digits */
local i; /* counter */
local ret; /* palindrome being formed */
/* determine length */
d = digits(val);
/* insert digits in reverse order at the bottom */
ret = val;
for (i=0; i < d; ++i) {
ret = ret*10 + digit(val, i);
}
return ret;
}
/*
* mkpalmiddigit - make a value into a palindrome with a middle digit
*
* NOTE: We assume base 10 digits and place 1 is the units digit.
*
* given:
* val a value
* digit the digit to put into the middle of the palindrome
*
* returns:
* val as a palindrome with lower half being reverse digits of val
* and digit as a middle digit
*/
define mkpalmiddigit(val, digit)
{
local d; /* length of val in digits */
local i; /* counter */
local ret; /* palindrome being formed */
/* determine length */
d = digits(val);
/* insert digits in reverse order at the bottom */
ret = val*10 + digit;
for (i=0; i < d; ++i) {
ret = ret*10 + digit(val, i);
}
return ret;
}
/*
* ispal - determine if a value is a palindrome
*
* NOTE: We assume base 10 digits and place 1 is the units digit.
*
* given:
* val a value
*
* returns:
* 1 ==> val is a palindrome
* 0 ==> val is NOT a palindrome
*/
define ispal(val)
{
local half; /* upper half of digits of val */
local digit; /* middle digit */
/* case: val has an even number of digits */
if (iseven(digits(val))) {
/* test palindrome-ness */
return (val == mkpal(upperhalf(val)));
/* case: val can an odd number of digits */
} else {
/* test palindrome-ness */
half = upperhalf(val);
digit = half % 10;
half //= 10;
return (val == mkpalmiddigit(half, digit));
}
}
/*
* palnextpal - return next palindrome from a known palindrome
*
* NOTE: We assume base 10 digits and place 1 is the units digit.
*
* given:
* pal a palindrome
*
* returns:
* next palindrome > pal
*/
define palnextpal(pal)
{
local paldigits; /* digits in pal */
local half; /* upper half of newval */
local newhalf; /* half+1 */
local newpal; /* new palindrome */
/* case: negative palindrome */
if (pal < 0) {
return -(palprevpal(-pal));
}
/*
* start with upper half
*/
half = upperhalf(pal);
/*
* prep to find a larger palindrome
*/
newhalf = half+1;
/*
* form palindrome from new upper half
*
* We need to watch for the corner case where changing the
* half changes the number of digits as this will impact
* or even/odd number of digits processing.
*/
paldigits = digits(pal);
if (digits(newhalf) == digits(half)) {
/* no change in half digits: process as normal */
if (iseven(paldigits)) {
newpal = mkpal(newhalf);
} else {
newpal = mkpalmiddigit(newhalf // 10, newhalf % 10);
}
} else {
/* change in half digits: process as opposite */
if (iseven(paldigits)) {
newpal = mkpalmiddigit(newhalf // 10, newhalf % 10);
} else {
newpal = mkpal(newhalf);
}
}
/*
* return the new palindrome
*/
return newpal;
}
/*
* nextpal - return next palindrome from a value
*
* NOTE: We assume base 10 digits and place 1 is the units digit.
*
* given:
* val a value
*
* returns:
* next palindrome > val
*/
define nextpal(val)
{
local newval; /* val+1 */
local newvaldigits; /* digits in newval */
local half; /* upper half of newval */
local pal; /* palindrome test value */
local newpal; /* new palindrome */
/* case: negative value */
if (val < 0) {
return -(prevpal(-val));
}
/*
* start looking from a larger value
*/
newval = val+1;
newvaldigits = digits(newval);
/* case: single digit palindrome */
if (newvaldigits < 2) {
return newval;
}
/*
* start with next upper half
*/
half = upperhalf(newval);
/*
* form palindrome from upper half
*
* We need to deal with even vs. odd digit counts
* when forming a palindrome from a half as the
* half may not or may include the middle digit.
*/
if (iseven(newvaldigits)) {
pal = mkpal(half);
} else {
pal = mkpalmiddigit(half // 10, half % 10);
}
/*
* case: we found a larger palindrome, we are done
*/
if (pal > val) {
return pal;
}
/*
* we need to find an even larger palindrome
*/
newpal = palnextpal(pal);
/*
* return the new palindrome
*/
return newpal;
}
/*
* palprevpal - return previous palindrome from a palindrome
*
* NOTE: We assume base 10 digits and place 1 is the units digit.
*
* given:
* pal a palindrome
*
* returns:
* previous palindrome < pal
*/
define palprevpal(pal)
{
local paldigits; /* digits in pal */
local half; /* upper half of newval */
local newhalf; /* half+1 */
local newpal; /* new palindrome */
/* case: negative value */
if (pal < 0) {
return -(palnextpal(-pal));
}
/* case: single digit palindrome */
if (pal < 10) {
newpal = pal-1;
return newpal;
}
/* case: 10 or 11 */
if (pal < 12) {
newpal = 9;
return newpal;
}
/*
* start with upper half
*/
half = upperhalf(pal);
/*
* prep to find a smaller palindrome
*/
newhalf = half-1;
/*
* form palindrome from new upper half
*
* We need to watch for the corner case where changing the
* half changes the number of digits as this will impact
* or even/odd number of digits processing.
*/
paldigits = digits(pal);
if (digits(newhalf) == digits(half)) {
/* no change in half digits: process as normal */
if (iseven(paldigits)) {
newpal = mkpal(newhalf);
} else {
newpal = mkpalmiddigit(newhalf // 10, newhalf % 10);
}
} else {
/* change in half digits: process as opposite */
if (iseven(paldigits)) {
newpal = mkpalmiddigit(newhalf // 10, newhalf % 10);
} else {
newpal = mkpal(newhalf);
}
}
/*
* return the new palindrome
*/
return newpal;
}
/*
* prevpal - return previous palindrome from a value
*
* NOTE: We assume base 10 digits and place 1 is the units digit.
*
* given:
* val a value
*
* returns:
* previous palindrome < val
*/
define prevpal(val)
{
local newval; /* val-1 */
local newvaldigits; /* digits in newval */
local half; /* upper half of newval */
local pal; /* palindrome test value */
local newpal; /* new palindrome */
/* case: negative value */
if (val < 0) {
return -(nextpal(-val));
}
/*
* start looking from a smaller value
*/
newval = val-1;
newvaldigits = digits(newval);
/* case: single digit palindrome */
if (newvaldigits < 2) {
return newval;
}
/*
* start with previous upper half
*/
half = upperhalf(newval);
/*
* form palindrome from upper half
*
* We need to deal with even vs. odd digit counts
* when forming a palindrome from a half as the
* half may not or may include the middle digit.
*/
if (iseven(newvaldigits)) {
pal = mkpal(half);
} else {
pal = mkpalmiddigit(half // 10, half % 10);
}
/*
* case: we found a smaller palindrome, we are done
*/
if (pal < val) {
return pal;
}
/*
* we need to find an even smaller palindrome
*/
newpal = palprevpal(pal);
/*
* return the new palindrome
*/
return newpal;
}
/*
* nextprimepal - return next palindrome that is a (highly probable) prime
*
* NOTE: We assume base 10 digits and place 1 is the units digit.
*
* given:
* val a value
*
* returns:
* next palindrome (highly probable) prime > val
*/
define nextprimepal(val)
{
local pal; /* palindrome test value */
local dpal; /* digits in pal */
/*
* pre-start under the next palindrome
*/
pal = nextpal(val-1);
/*
* loop until we find a (highly probable) prime or 0
*/
do {
/* case: negative values and tiny values */
if (pal < 2) {
return 2;
}
/*
* compute the next palindrome
*/
pal = palnextpal(pal);
dpal = digits(pal);
/* case: 11 is the only prime palindrome with even digit count */
if (pal == 11) {
return 11;
}
/* case: even number of digits and not 11 */
if (iseven(dpal)) {
/*
* Except for 11 (which is handled above already), there are
* no prime palindrome with even digits. So we need to
* increase the digit count and work with that larger palindrome.
*/
pal = nextpal(10^dpal);
}
/* case: palindrome is even or ends in 5 */
if (iseven(pal % 10) || (pal%10 == 10/2)) {
/*
* we need to increase the bottom and top digits
* so that we have a chance to be prime
*/
pal += (1 + 10^(dpal-1));
}
if (config("resource_debug") & 0x8) {
print "DEBUG: nextprimepal:", pal;
}
} while (ptest(pal) == 0 && pal > 0);
/* return palindrome that his (highly probable) prime or 0 */
return pal;
}
/*
* prevprimepal - return prev palindrome that is a (highly probable) prime
*
* NOTE: We assume base 10 digits and place 1 is the units digit.
*
* given:
* val a value
*
* returns:
* prev palindrome (highly probable) prime < val or 0
*/
define prevprimepal(val)
{
local pal; /* palindrome test value */
local dpal; /* digits in pal */
/*
* pre-start over the previous palindrome
*/
pal = prevpal(val+1);
/*
* loop until we find a (highly probable) prime or 0
*/
do {
/*
* case: single digit values are always palindromes
*/
if (val < 10) {
/*
* The prevcand() call will return 0 if there is no previous prime
* such as the case when val < 2.
*/
return prevcand(pal);
}
/*
* compute the previous palindrome
*/
pal = palprevpal(pal);
dpal = digits(pal);
/* case: 11 is the only prime palindrome with even digit count */
if (pal == 11) {
return 11;
}
/* case: 2 digit palindrome and not 11 */
if (dpal == 2) {
return 7;
}
/* case: even number of digits */
if (iseven(dpal)) {
/*
* Except for 11 (which is handled above already), there are
* no prime palindrome with even digits. So we need to
* decrease the digit count and work with that smaller palindrome.
*/
pal = prevpal(10^(dpal-1));
}
/* case: palindrome is even or ends in 5 */
if (iseven(pal % 10) || (pal%10 == 10/2)) {
/*
* we need to decrease the bottom and top digits
* so that we have a chance to be prime
*/
pal -= (1 + 10^(dpal-1));
}
if (config("resource_debug") & 0x8) {
print "DEBUG: prevprimepal:", pal;
}
} while (ptest(pal) == 0 && pal > 0);
/* return palindrome that his (highly probable) prime or 0 */
return pal;
}

View File

@@ -336,7 +336,7 @@ define __CZ__produce_long_random_number(n)
ret = 1;
if(!isint(n) || n<1)
return newerror("__CZ__produce_long_random_number(n): "
"n is not an integer >=1");
"n is not an integer >=1");
for(k=0;k<n;k++){
ret += random();
ret = toomcook4square(ret);

View File

@@ -72,7 +72,7 @@ define hurwitzzeta(s,a){
limit=(precision*ln(10)-re((s-.5)*result)+(1.*realpart_a)*ln(2.*pi()))/2;
limit=max(2,ceil(max(limit,abs(s*1.)/2)));
limit_function=ceil(sqrt((limit+realpart_a/2-.25)^2+(imagpart_s*1.)^2/4)/
pi());
pi());
if (config("user_debug") > 0) {
print "limit_function = " limit_function;
print "limit = " limit;

20
calc.c
View File

@@ -277,14 +277,14 @@ main(int argc, char **argv)
if (nextcp(&cp, &index, argc, argv,
FALSE)) {
fprintf(stderr,
"-D expects argument\n");
"-D expects argument\n");
exit(5);
}
havearg = TRUE;
if (*cp != ':') {
if (*cp < '0' || *cp > '9') {
fprintf(stderr,
"-D expects"
"-D expects"
" integer\n");
exit(6);
}
@@ -296,13 +296,13 @@ main(int argc, char **argv)
if (*cp != '\0' &&
*cp != ' ' && *cp != ':') {
fprintf(stderr,
"Bad syntax im -D"
"Bad syntax im -D"
" arg\n");
exit(7);
}
if (*cp != ':') {
if (nextcp(&cp, &index,
argc, argv,
argc, argv,
FALSE)
|| *cp != ':')
break;
@@ -318,7 +318,7 @@ main(int argc, char **argv)
if (*cp != ':') {
if (*cp < '0' || *cp > '9') {
fprintf(stderr,
"-D : expects"
"-D : expects"
" integer\n");
exit(9);
}
@@ -330,13 +330,13 @@ main(int argc, char **argv)
if (*cp != '\0' &&
*cp != ' ' && *cp != ':') {
fprintf(stderr,
"Bad syntax im -D"
"Bad syntax im -D"
" : arg\n");
exit(10);
}
if (*cp != ':') {
if (nextcp(&cp, &index,
argc, argv,
argc, argv,
FALSE)
|| *cp != ':') {
break;
@@ -346,12 +346,12 @@ main(int argc, char **argv)
if (nextcp(&cp, &index, argc, argv,
FALSE)) {
fprintf(stderr, "-D : : expects"
" argument\n");
" argument\n");
exit(11);
}
if (*cp < '0' || *cp > '9') {
fprintf(stderr, "-D :: expects"
" integer\n");
" integer\n");
exit(12);
}
user_debug = cp;
@@ -398,7 +398,7 @@ main(int argc, char **argv)
if (nextcp(&cp, &index, argc,
argv, haveendstr)) {
fprintf(stderr, "-f -once"
" expects"
" expects"
" filename\n");
exit(16);
}

View File

@@ -497,7 +497,7 @@ uninstall:
continue; \
fi; \
if [ -f "${T}${SCRIPTDIR}/$$i" ]; then \
${RM} -f "${T}${SCRIPTDIR}/$$i"; \
${RM} -f "${T}${SCRIPTDIR}/$$i"; \
if [ -f "${T}${SCRIPTDIR}/$$i" ]; then \
echo "cannot uninstall ${T}${SCRIPTDIR}/$$i"; \
else \

View File

@@ -374,12 +374,12 @@ Step 5: Write your custom function
One is able to set bit 8 by way of the calc command line:
calc -D 128
calc -D 128
See the calc man page for details. One may also set that bit
while running calc by way of the config() builtin function:
config("calc_debug", 128);
config("calc_debug", 128);
See the help/config file for details on calc_debug.

View File

@@ -496,7 +496,7 @@ EXT=
# The default calc versions
#
VERSION= 2.14.0.6
VERSION= 2.14.0.10
# Names of shared libraries with versions
#
@@ -1708,7 +1708,7 @@ uninstall:
continue; \
fi; \
if [ -f "${T}${CUSTOMHELPDIR}/$$i" ]; then \
${RM} -f "${T}${CUSTOMHELPDIR}/$$i"; \
${RM} -f "${T}${CUSTOMHELPDIR}/$$i"; \
if [ -f "${T}${CUSTOMHELPDIR}/$$i" ]; then \
echo "cannot uninstall ${T}${CUSTOMHELPDIR}/$$i"; \
else \
@@ -1721,7 +1721,7 @@ uninstall:
continue; \
fi; \
if [ -f "${T}${CUSTOMCALDIR}/$$i" ]; then \
${RM} -f "${T}${CUSTOMCALDIR}/$$i"; \
${RM} -f "${T}${CUSTOMCALDIR}/$$i"; \
if [ -f "${T}${CUSTOMCALDIR}/$$i" ]; then \
echo "cannot uninstall ${T}${CUSTOMCALDIR}/$$i"; \
else \
@@ -1734,7 +1734,7 @@ uninstall:
continue; \
fi; \
if [ -f "${T}${CUSTOMINCDIR}/$$i" ]; then \
${RM} -f "${T}${CUSTOMINCDIR}/$$i"; \
${RM} -f "${T}${CUSTOMINCDIR}/$$i"; \
if [ -f "${T}${CUSTOMINCDIR}/$$i" ]; then \
echo "cannot uninstall ${T}${CUSTOMINCDIR}/$$i"; \
else \

View File

@@ -496,7 +496,7 @@ EXT=
# The default calc versions
#
VERSION= 2.14.0.6
VERSION= 2.14.0.10
# Names of shared libraries with versions
#

View File

@@ -498,7 +498,7 @@ uninstall:
continue; \
fi; \
if [ -f "${T}${CUSTOMHELPDIR}/$$i" ]; then \
${RM} -f "${T}${CUSTOMHELPDIR}/$$i"; \
${RM} -f "${T}${CUSTOMHELPDIR}/$$i"; \
if [ -f "${T}${CUSTOMHELPDIR}/$$i" ]; then \
echo "cannot uninstall ${T}${CUSTOMHELPDIR}/$$i"; \
else \
@@ -511,7 +511,7 @@ uninstall:
continue; \
fi; \
if [ -f "${T}${CUSTOMCALDIR}/$$i" ]; then \
${RM} -f "${T}${CUSTOMCALDIR}/$$i"; \
${RM} -f "${T}${CUSTOMCALDIR}/$$i"; \
if [ -f "${T}${CUSTOMCALDIR}/$$i" ]; then \
echo "cannot uninstall ${T}${CUSTOMCALDIR}/$$i"; \
else \
@@ -524,7 +524,7 @@ uninstall:
continue; \
fi; \
if [ -f "${T}${CUSTOMINCDIR}/$$i" ]; then \
${RM} -f "${T}${CUSTOMINCDIR}/$$i"; \
${RM} -f "${T}${CUSTOMINCDIR}/$$i"; \
if [ -f "${T}${CUSTOMINCDIR}/$$i" ]; then \
echo "cannot uninstall ${T}${CUSTOMINCDIR}/$$i"; \
else \

View File

@@ -13,7 +13,7 @@ DESCRIPTION
This custom function will return the value:
q mod 2^(2^127-1)
q mod 2^(2^127-1)
This custom function serves as a demonstration of how to write
a custom function. It performs the equivalent of:

2
file.c
View File

@@ -926,7 +926,7 @@ printid(FILEID id, int flags)
if (get_open_pos(fp, &pos) < 0) {
if (fileno(fp) > 2)
math_str("Error while determining file position!");
math_str("Error while determining file position!");
math_chr(')');
return 0;
}

27
func.c
View File

@@ -154,6 +154,25 @@ STATIC int env_pool_max = 0; /* number of env_pool elements allocated */
STATIC struct env_pool *e_pool = NULL; /* env_pool elements */
/*
* constants used for hours or degrees conversion functions
*/
STATIC HALF _nineval_[] = { 9 };
STATIC HALF _twentyfourval_[] = { 24 };
STATIC HALF _threesixtyval_[] = { 360 };
STATIC HALF _fourhundredval_[] = { 400 };
STATIC NUMBER _qtendivnine_ = { { _tenval_, 1, 0 },
{ _nineval_, 1, 0 }, 1, NULL };
STATIC NUMBER _qninedivten_ = { { _nineval_, 1, 0 },
{ _tenval_, 1, 0 }, 1, NULL };
STATIC NUMBER _qtwentyfour = { { _twentyfourval_, 1, 0 },
{ _oneval_, 1, 0 }, 1, NULL };
STATIC NUMBER _qthreesixty = { { _threesixtyval_, 1, 0 },
{ _oneval_, 1, 0 }, 1, NULL };
STATIC NUMBER _qfourhundred = { { _fourhundredval_, 1, 0 },
{ _oneval_, 1, 0 }, 1, NULL };
/*
* user-defined error strings
*/
@@ -1106,6 +1125,9 @@ f_randombit(int count, NUMBER **vals)
long cnt; /* bits needed or skipped */
/* parse args */
ztmp.len = 0; /* paranoia */
ztmp.v = NULL;
ztmp.sign = 0;
if (count == 0) {
zrandom(1, &ztmp);
ans = ziszero(ztmp) ? qlink(&_qzero_) : qlink(&_qone_);
@@ -1298,6 +1320,7 @@ f_digit(int count, VALUE **vals)
base = _ten_;
}
res.v_type = V_NUM;
res.v_subtype = V_NOSUBTYPE;
res.v_num = qdigit(vals[0]->v_num, vals[1]->v_num->num, base);
if (res.v_num == NULL)
return error_value(E_DGT3);
@@ -1323,6 +1346,7 @@ f_digits(int count, VALUE **vals)
base = _ten_;
}
res.v_type = V_NUM;
res.v_subtype = V_NOSUBTYPE;
res.v_num = itoq(qdigits(vals[0]->v_num, base));
return res;
}
@@ -1346,6 +1370,7 @@ f_places(int count, VALUE **vals)
places = qdecplaces(vals[0]->v_num);
res.v_type = V_NUM;
res.v_subtype = V_NOSUBTYPE;
res.v_num = itoq(places);
return res;
}
@@ -3606,6 +3631,7 @@ f_comb(VALUE *v1, VALUE *v2)
copyvalue(v1, &result);
decvalue(v1, &tmp1);
div.v_type = V_NUM;
div.v_subtype = V_NOSUBTYPE;
div.v_num = qlink(&_qtwo_);
n--;
for (;;) {
@@ -9039,6 +9065,7 @@ f_sleep(int count, VALUE **vals)
NUMBER *q1, *q2;
res.v_type = V_NULL;
res.v_subtype = V_NOSUBTYPE;
#if !defined(_WIN32)
if (count > 0) {
if (vals[0]->v_type != V_NUM || qisneg(vals[0]->v_num))

56
help.c
View File

@@ -29,6 +29,7 @@
#include <ctype.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/errno.h>
#include "calc.h"
#include "conf.h"
@@ -262,6 +263,7 @@ givehelp(char *type)
}
snprintf(helppath, snprintf_len, "%s/%s", calc_helpdir, type);
helppath[snprintf_len] = '\0'; /* paranoia */
errno = 0;
stream = fopen(helppath, "r");
if (stream != NULL) {
@@ -276,30 +278,42 @@ givehelp(char *type)
* open the helpfile (looking in CUSTOMHELPDIR last)
*/
} else {
char *cust_helppath; /* path to the custom help file */
size_t cust_snprintf_len; /* malloced custom snprintf buf len */
char *cust_helppath; /* path to the custom help file */
size_t cust_snprintf_len; /* malloced custom snprintf buf len */
cust_snprintf_len = strlen(calc_customhelpdir)+1+strlen(type) + 1;
cust_helppath = (char *)malloc(cust_snprintf_len+1);
if (cust_helppath == NULL) {
fprintf(stderr, "malloc failure for givehelp #1\n");
return;
}
snprintf(cust_helppath, cust_snprintf_len,
"%s/%s", calc_customhelpdir, type);
cust_helppath[cust_snprintf_len] = '\0'; /* paranoia */
stream = fopen(cust_helppath, "r");
if (stream != NULL) {
cust_snprintf_len =
strlen(calc_customhelpdir)+1+strlen(type) + 1;
cust_helppath = (char *)malloc(cust_snprintf_len+1);
if (cust_helppath == NULL) {
fprintf(stderr, "malloc failure for givehelp #1\n");
return;
}
snprintf(cust_helppath, cust_snprintf_len,
"%s/%s", calc_customhelpdir, type);
cust_helppath[cust_snprintf_len] = '\0'; /* paranoia */
errno = 0;
stream = fopen(cust_helppath, "r");
if (stream != NULL) {
/*
* we have the help file open, now display it
*/
page_file(stream);
(void) fclose(stream);
}
free(cust_helppath);
cust_helppath = NULL;
/*
* we have the help file open, now display it
*/
page_file(stream);
(void) fclose(stream);
/* unable to open help file */
} else {
fprintf(stderr, "unable to open help file: %s - %s\n",
type, strerror(errno));
}
free(cust_helppath);
cust_helppath = NULL;
#else /* CUSTOM */
/* unable to open help file */
} else {
fprintf(stderr, "unable to open help file: %s - %s\n",
type, strerror(errno));
#endif /* CUSTOM */
}

View File

@@ -894,7 +894,7 @@ uninstall:
continue; \
fi; \
if [ -f "${T}${HELPDIR}/$$i" ]; then \
${RM} -f "${T}${HELPDIR}/$$i"; \
${RM} -f "${T}${HELPDIR}/$$i"; \
if [ -f "${T}${HELPDIR}/$$i" ]; then \
echo "cannot uninstall ${T}${HELPDIR}/$$i"; \
else \

View File

@@ -79,7 +79,7 @@ EXAMPLE
10 /* 012 */
; base2(16),
; 131072
131072 /* 0x20000 */
131072 /* 0x20000 */
; 2345
2345 /* 0x929 */
@@ -96,7 +96,7 @@ LINK LIBRARY
SEE ALSO
base, config, str
## Copyright (C) 2002 Landon Curt Noll
## Copyright (C) 2002,2021 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

View File

@@ -866,10 +866,10 @@ DESCRIPTION
when a variable name collides with an exist name of a higher scope.
Examples of collisions are when:
* both local and static variables have the same name
* both local and global variables have the same name
* both function parameter and local variables have the same name
* both function parameter and global variables have the same name
* both local and static variables have the same name
* both local and global variables have the same name
* both function parameter and local variables have the same name
* both function parameter and global variables have the same name
The initial "redecl_warn" value is 1.
@@ -895,7 +895,7 @@ EXAMPLE
1
; config("version")
"2.12.0"
"2.12.0"
; config("all")
mode "real"

View File

@@ -31,7 +31,7 @@ DESCRIPTION
The value d will be set as if the following were used:
d = int(return_value);
d = int(return_value);
For some rounding modes, d will be an integer in the interval [0, 360).
For other rounding modes, d will be an integer in the interval (-360, 0].
@@ -52,7 +52,7 @@ DESCRIPTION
The following shows relationship between the return value and the resulting
d, and m values:
return_value == d + m/60;
return_value == d + m/60;
EXAMPLE

View File

@@ -32,7 +32,7 @@ DESCRIPTION
The value d will be set as if the following were used:
d = int(return_value);
d = int(return_value);
For some rounding modes, d will be an integer in the interval [0, 360).
For other rounding modes, d will be an integer in the interval (-360, 0].
@@ -67,7 +67,7 @@ DESCRIPTION
The following shows relationship between the return value and the resulting
d, m, and s values:
return_value == d + m/60 + s/3600;
return_value == d + m/60 + s/3600;
EXAMPLE

View File

@@ -73,8 +73,8 @@ EXAMPLE
; for (n = 6; n >= -6; n--) print digit(a, n, 256),; print
0 0 0 0 1 226 64 201 251 231 108 139 67
; for (n = 1; n >= -12; n++) print digit(10/7, n),; print
; 0 1 4 2 8 5 7 1 4 2 8 5 7 1
; for (n = 1; n >= -12; n++) print digit(10/7, n),; print
; 0 1 4 2 8 5 7 1 4 2 8 5 7 1
; print digit(10/7, -7e1000, 1e6)
428571
@@ -92,7 +92,7 @@ LINK LIBRARY
SEE ALSO
bit
## Copyright (C) 1999-2006 Landon Curt Noll
## Copyright (C) 1999-2006,2021 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

View File

@@ -21,7 +21,7 @@ DESCRIPTION
The builtin function:
display(d)
display(d)
display()
is an alias for:
@@ -96,7 +96,7 @@ LINK LIBRARY
SEE ALSO
config, epsilon, fprintf, printf, strprintf
## Copyright (C) 2004,2018 Landon Curt Noll
## Copyright (C) 2004,2018,2021 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

View File

@@ -38,7 +38,7 @@ DESCRIPTION
(*) NOTE on 'b' / binary/text mode:
The 'b' or fopen binary mode has no effect on POSIX / Linux
The 'b' or fopen binary mode has no effect on POSIX / Linux
/ Un*x-like systems. On those systems a text file is the
same as a binary file (as it should be for any modern-day
operating system). Adding 'b' to an fopen has no effect
@@ -52,9 +52,9 @@ DESCRIPTION
Names of files are subject to ~ expansion just like the C or
Korn shell. For example, the file name:
~/lib/gleet
~/lib/fizzbin
refers to the file 'gleet' under the directory lib located
refers to the file 'fizzbin' under the directory lib located
in your home directory. The file name:
~chongo/was_here
@@ -107,7 +107,7 @@ SEE ALSO
fprintf, fputc, fputs, fseek, fsize, ftell, isfile, printf, prompt,
fpathopen, strerror
## Copyright (C) 1999-2006 Landon Curt Noll
## Copyright (C) 1999-2006,2021 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

View File

@@ -21,7 +21,7 @@ DESCRIPTION
Absolute filenames, and filenames with an implied path are files
that begin with:
/ # absolute path
/ # absolute path
./ # implied path through the current working directory
../ # implied path through the current working directory parent
~ # absolute path going through a home directory
@@ -29,12 +29,12 @@ DESCRIPTION
A search path is a :-separated list of directories used to search for
a filename. For example:
fpathopen("whey", "r", ".:/tmp:/var/tmp:~chongo/pub:~/tmp");
fpathopen("whey", "r", ".:/tmp:/var/tmp:~chongo/pub:~/tmp");
will cause this function to open the first readable file it
files while searching through these paths in order:
./whey
./whey
/tmp/whey
/var/tmp/whey
~chongo/pub/whey
@@ -46,16 +46,16 @@ DESCRIPTION
to open files under the given mode. If the mode allows for
writing and a file can be created, then that file is returned.
This call open "./gleet" for writing if the current directory is
writable, even if "./gleet" did not previously exist:
This call open "./fizzbin" for writing if the current directory is
writable, even if "./fizzbin" did not previously exist:
fpathopen("gleet", "r", ".:/tmp:/var/tmp:~chongo/pub:~/tmp");
fpathopen("fizzbin", "r", ".:/tmp:/var/tmp:~chongo/pub:~/tmp");
This call will likely open (and create if needded) for appending,
the file "/tmp/log" assuming that the user is not allowed to
create files in the previous system directories:
fpathopen("log", "a", "/:/etc:/bin:/usr/bin:/tmp");
fpathopen("log", "a", "/:/etc:/bin:/usr/bin:/tmp");
The CALCPATH search path is taken from the $CALCPATH environment
variable or if no such variable exists, a compiled in default search
@@ -92,7 +92,7 @@ DESCRIPTION
(*) NOTE on 'b' / binary/text mode:
The 'b' or fopen binary mode has no effect on POSIX / Linux
The 'b' or fopen binary mode has no effect on POSIX / Linux
/ Un*x-like systems. On those systems a text file is the
same as a binary file (as it should be for any modern-day
operating system). Adding 'b' to an fopen has no effect
@@ -106,9 +106,9 @@ DESCRIPTION
Names of files are subject to ~ expansion just like the C or
Korn shell. For example, the file name:
~/lib/gleet
~/lib/fizbin
refers to the file 'gleet' under the directory lib located
refers to the file 'fizbin' under the directory lib located
in your home directory. The file name:
~chongo/was_here
@@ -180,7 +180,7 @@ SEE ALSO
fprintf, fputc, fputs, fseek, fsize, ftell, isfile, printf, prompt,
environment, calcpath
## Copyright (C) 2006 Landon Curt Noll
## Copyright (C) 2006,2021 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

View File

@@ -31,7 +31,7 @@ DESCRIPTION
The value g will be set as if the following were used:
g = int(return_value);
g = int(return_value);
For some rounding modes, g will be an integer in the interval [0, 400).
For other rounding modes, g will be an integer in the interval (-400, 0].
@@ -52,7 +52,7 @@ DESCRIPTION
The following shows relationship between the return value and the resulting
g, and m values:
return_value == g + m/60;
return_value == g + m/60;
EXAMPLE

View File

@@ -32,7 +32,7 @@ DESCRIPTION
The value g will be set as if the following were used:
g = int(return_value);
g = int(return_value);
For some rounding modes, g will be an integer in the interval [0, 400).
For other rounding modes, g will be an integer in the interval (-400, 0].
@@ -67,7 +67,7 @@ DESCRIPTION
The following shows relationship between the return value and the resulting
g, m, and s values:
return_value == g + m/60 + s/3600;
return_value == g + m/60 + s/3600;
EXAMPLE

View File

@@ -31,7 +31,7 @@ DESCRIPTION
The value h will be set as if the following were used:
h = int(return_value);
h = int(return_value);
For some rounding modes, h will be an integer in the interval [0, 24).
For other rounding modes, h will be an integer in the interval (-24, 0].
@@ -52,7 +52,7 @@ DESCRIPTION
The following shows relationship between the return value and the resulting
h, and m values:
return_value == h + m/60;
return_value == h + m/60;
EXAMPLE

View File

@@ -32,7 +32,7 @@ DESCRIPTION
The value h will be set as if the following were used:
h = int(return_value);
h = int(return_value);
For some rounding modes, h will be an integer in the interval [0, 24).
For other rounding modes, h will be an integer in the interval (-24, 0].
@@ -67,7 +67,7 @@ DESCRIPTION
The following shows relationship between the return value and the resulting
h, m, and s values:
return_value == h + m/60 + s/3600;
return_value == h + m/60 + s/3600;
EXAMPLE

View File

@@ -18,7 +18,7 @@ DESCRIPTION
takes into account more abstract concepts such as data types.
WARNING: Use of FNV-0 is NOT recommended for general purposes.
Calc uses FNV-0 for internal objects such as associative
Calc uses FNV-0 for internal objects such as associative
arrays as well as other internal processes. Calc
maintains the use of FNV-0 for backwards compatibility.
@@ -47,7 +47,7 @@ LINK LIBRARY
SEE ALSO
ishash, fnv, sha1
## Copyright (C) 1999-2007,2014 Landon Curt Noll
## Copyright (C) 1999-2007,2014,2021 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

View File

@@ -13,7 +13,7 @@ What is calc?
and the calculator will print:
15
15
Calc has the usual collection of arithmetic operators +, -, /, *
as well as ^ (exponentiation), % (modulus) and // (integer divide).
@@ -27,7 +27,7 @@ What is calc?
Notice that calc values can be very large. For example:
2^23209-1
2^23209-1
will print:
@@ -60,7 +60,7 @@ What is calc?
and the calculator prints:
13763753091226345046315979581580902400000000
13763753091226345046315979581580902400000000
The calculator also knows about complex numbers, so that typing:
@@ -69,7 +69,7 @@ What is calc?
will print:
17+6i
17+6i
-55.50474777265624667147+193.9265235748927986537i
The calculator can calculate transcendental functions, and accept and
@@ -81,19 +81,19 @@ What is calc?
prints:
0.8414709848078965066525023216302989996225630607983710656727517099919104
0.8414709848078965066525023216302989996225630607983710656727517099919104
Calc can output values in terms of fractions, octal or hexadecimal.
For example:
config("mode", "fraction"),
config("mode", "fraction"),
(17/19)^23
base(16),
(19/17)^29
will print:
19967568900859523802559065713/257829627945307727248226067259
19967568900859523802559065713/257829627945307727248226067259
0x9201e65bdbb801eaf403f657efcf863/0x5cd2e2a01291ffd73bee6aa7dcf7d1
All numbers are represented as fractions with arbitrarily large

View File

@@ -18,12 +18,12 @@ DESCRIPTION
Note that issq() works on rational values, so:
issq(25/16) == 1
issq(25/16) == 1
If you want to test for prefect square integers, you need to exclude
non-integer values before you test:
isint(curds) && issq(curds)
isint(curds) && issq(curds)
EXAMPLE
; print issq(25), issq(3), issq(0)
@@ -45,7 +45,7 @@ SEE ALSO
isobjtype, isodd, isprime, isrand, israndom, isreal, isrel,
issimple, isstr, istype
## Copyright (C) 1999 Landon Curt Noll
## Copyright (C) 1999,2021 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

View File

@@ -17,8 +17,8 @@ DESCRIPTION
If y is an odd prime, then the Legendre symbol (x/y) returns:
(x/y) == 0 x is divisible by y (0 == x % y)
(x/y) == 1 if x is a quadratic residue modulo y
(x/y) == -1 if x is not a quadratic residue modulo y
(x/y) == 1 if x is a quadratic residue modulo y
(x/y) == -1 if x is not a quadratic residue modulo y
Legendre symbol often denoted as (x/y) as if x/y were a fraction.
@@ -75,7 +75,7 @@ DESCRIPTION
jacobi(x,y) == 0 if x <= 0
jacobi(x,y) == 0 if y <= 0
jacobi(x,y) == 0 if y is even
jacobi(x,y) == 0 if y is even
jacobi(x,b) == 0 if gcd(x,b) > 1
@@ -105,7 +105,7 @@ DESCRIPTION
It is also worth noting that:
jacobi(x,y) == 0 if gcd(y,x) != 1
jacobi(x,y) == 0 if gcd(y,x) != 1
jacobi(y,y) == 0 if y > 1
Based on the generalization of the quadratic reciprocity theorem,
@@ -125,8 +125,8 @@ DESCRIPTION
When b is odd:
jacobi(x^2,b) == 1 if gcd(x,b) == 1
jacobi(x,b^2) == 1 if gcd(x,b) == 1
jacobi(x^2,b) == 1 if gcd(x,b) == 1
jacobi(x,b^2) == 1 if gcd(x,b) == 1
jacobi(x0,b) == jacobi(x1,b) if x0 == x1 % b
@@ -162,7 +162,7 @@ DESCRIPTION
j = 1;
while (x != 0) {
while (iseven(x)) {
x = x / 2;
x = x / 2;
t = b % 8;
if (t == 3 || t == 5) {
j = -j;
@@ -170,7 +170,7 @@ DESCRIPTION
}
swap(x,b);
if (((x % 4) == 3) && ((b % 4) == 3)) {
j = -j;
j = -j;
}
x = x % b;
}

View File

@@ -163,7 +163,7 @@ DESCRIPTION
printf(" [%d,%d]: %e", i, j, A[i,j]);
if (i != matmax(A,1))
printf("\n");
}
}
}
So that when one defines a 2D matrix such as:
@@ -414,7 +414,7 @@ SEE ALSO
det, inverse, isident, test, config, search, rsearch, reverse, copy,
blkcpy, dp, cp, randperm, sort
## Copyright (C) 1999-2006,2018 Landon Curt Noll
## Copyright (C) 1999-2006,2018,2021 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

View File

@@ -25,11 +25,11 @@ TYPES
DESCRIPTION
The expression:
x % y
x % y
is equivalent to call:
mod(x, y)
mod(x, y)
The function:
@@ -37,7 +37,7 @@ DESCRIPTION
is equivalent to:
config("mod", rnd), x % y
config("mod", rnd), x % y
except that the global config("mod") value does not change.
@@ -137,7 +137,7 @@ LINK LIBRARY
SEE ALSO
quo, quomod, //, %
## Copyright (C) 1999-2006 Landon Curt Noll
## Copyright (C) 1999-2006,2021 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

View File

@@ -135,7 +135,7 @@ Using objects
xx_print 1 print value, default prints elements
xx_one 1 multiplicative identity, default is 1
xx_test 1 logical test (false,true => 0,1),
default tests elements
default tests elements
xx_add 2
xx_sub 2
xx_neg 1 negative
@@ -146,10 +146,10 @@ Using objects
xx_norm 1 square of absolute value
xx_conj 1 conjugate
xx_pow 2 integer power, default does multiply,
square, inverse
square, inverse
xx_sgn 1 sign of value (-1, 0, 1)
xx_cmp 2 equality (equal,nonequal => 0,1),
default tests elements
default tests elements
xx_rel 2 relative order, positive for >, etc.
xx_quo 3 integer quotient
xx_mod 3 remainder of division
@@ -196,7 +196,7 @@ Using objects
test2300.cal
test3100.cal
## Copyright (C) 1999,2010 Landon Curt Noll
## Copyright (C) 1999,2010,2021 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

View File

@@ -85,7 +85,7 @@
The man command is an alias for the help command. Try:
man jacobi
man jacobi
Only calc help files may be displayed by the help and man commands.

View File

@@ -18,7 +18,7 @@ DESCRIPTION
As a unary operator:
# value
# value
returns the number of 1 bits, or pop-count of the absolute value of
the numerator (abs(num(value))). Therefore when x is a non-negative
@@ -52,7 +52,7 @@ DESCRIPTION
For example, of an executable file contains:
#!/usr/local/src/bin/calc/calc -q -f
#!/usr/local/src/bin/calc/calc -q -f
/* NOTE: The #! above must start in column 1 of the 1st line */
/* The 1st line must end with -f */
## Single # shell comments don't work, use two or more

View File

@@ -14,7 +14,7 @@ DESCRIPTION
Generate a pseudo-random number using an subtractive 100 shuffle generator.
We return a pseudo-random number over the half closed interval:
[min,beyond) ((min <= return < beyond))
[min,beyond) ((min <= return < beyond))
By default, min is 0 and beyond is 2^64.

View File

@@ -14,7 +14,7 @@ DESCRIPTION
Generate a pseudo-random number using a Blum-Blum-Shub generator.
We return a pseudo-random number over the half closed interval:
[min,beyond) ((min <= return < beyond))
[min,beyond) ((min <= return < beyond))
By default, min is 0 and beyond is 2^64.
@@ -159,7 +159,7 @@ LINK LIBRARY
SEE ALSO
seed, srand, randbit, isrand, rand, srandom, israndom
## Copyright (C) 1999-2007 Landon Curt Noll
## Copyright (C) 1999-2007,2021 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

View File

@@ -29,13 +29,13 @@ Statements
This works as expected:
if (expr) {
if (expr) {
...
}
However this WILL NOT WORK AS EXPECTED:
if (expr)
if (expr)
{
...
}
@@ -43,7 +43,7 @@ Statements
because calc will parse the if being terminated by
an empty statement followed by a
if (expr) ;
if (expr) ;
{
...
}
@@ -294,7 +294,7 @@ Statements
help command top level commands
help expression calc expression syntax
help builtin calc builtin functions
help usage how to invoke the calc command and calc -options
help usage how to invoke the calc command and calc -options
You may obtain help on individual builtin functions. For example:
@@ -302,7 +302,7 @@ Statements
help round
See:
help builtin
help builtin
for a list of builtin functions.
@@ -321,11 +321,11 @@ Statements
The man command is an alias for the help command. For example:
man jacobi
man jacobi
Only calc help files may be displayed by the help and man commands.
## Copyright (C) 1999-2007,2017 Landon Curt Noll
## Copyright (C) 1999-2007,2017,2021 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

View File

@@ -14,7 +14,7 @@ DESCRIPTION
The stoponerror controls when or if calc stops based on the
number of errors:
n == -1 do not stop
n == -1 do not stop
n == 0 stop on error unless calc was invoked with -c
n > 0 stop when n errors are encountered
@@ -35,7 +35,7 @@ LINK LIBRARY
SEE ALSO
errcount, errmax, errorcodes, iserror, errno, strerror, newerror
## Copyright (C) 2006 Landon Curt Noll
## Copyright (C) 2006,2021 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

View File

@@ -18,7 +18,7 @@ DESCRIPTION
EXAMPLE
; strtolower(" GNU Lesser General Public License");
" gnu lesser general public license"
" gnu lesser general public license"
LIMITS
none.

View File

@@ -18,7 +18,7 @@ DESCRIPTION
EXAMPLE
; strtoupper(" GNU Lesser General Public License");
" GNU LESSER GENERAL PUBLIC LICENSE"
" GNU LESSER GENERAL PUBLIC LICENSE"
LIMITS
none.

View File

@@ -73,11 +73,11 @@ Unexpected
Be careful about the precedence of operators. Note that:
-1 ^ 0.5 == -1
-1 ^ 0.5 == -1
whereas:
(-1) ^ 0.5 == 1i
(-1) ^ 0.5 == 1i
because the above expression in parsed as:
@@ -85,7 +85,7 @@ Unexpected
whereas:
(-1) ^ 0.5 == 1i
(-1) ^ 0.5 == 1i
op= operators associate left to right
@@ -277,7 +277,7 @@ Unexpected
A single # is an calc operator, not a comment. However two or more
##'s in a row is a comment. See "help pound" for more information.
#!/usr/local/src/bin/calc/calc -q -f
#!/usr/local/src/bin/calc/calc -q -f
/* a correct comment */
## another correct comment
@@ -289,7 +289,7 @@ Unexpected
This next example is WRONG:
#!/usr/local/src/bin/calc/calc -q -f
#!/usr/local/src/bin/calc/calc -q -f
# This is not a calc calc comment because it has only a single #
# You must to start comments with ## or /*
@@ -350,7 +350,7 @@ Unexpected
In most interactive shells:
calc 2 * 3
calc 2 * 3
will frequently produce a "Missing operator" error because the '*' is
evaluated as a "shell glob". To avoid this you must quote or escape
@@ -358,11 +358,11 @@ Unexpected
For example, bash / ksh / sh shell users should use:
calc '2 * 3'
calc '2 * 3'
or:
calc 2 \* 3
calc 2 \* 3
or some other form of shell meta-character escaping.
@@ -393,7 +393,7 @@ Unexpected
To avoid this problem, use:
seq 5 | while read i; do calc "($i+3)^2" </dev/null; done
seq 5 | while read i; do calc "($i+3)^2" </dev/null; done
which produces the expected results:

View File

@@ -12,16 +12,16 @@ DESCRIPTION
Calc version strings can be of the form:
x.y.z.w
x.y.z
x.y
x.y.z.w
x.y.z
x.y
where x, y, z, w, v are integers (without leading 0's) and,
t is the literal character 't'.
EXAMPLE
; version()
"2.11.5.4"
"2.11.5.4"
LIMITS
none

View File

@@ -1127,7 +1127,7 @@ addreadset(char *name, char *path, struct stat *sbuf)
* like UNIX inodes. _fullpath also allocated the memory for
* this new longer path name.
*/
{
{
readset[ret].path = _fullpath(NULL, path, MSDOS_MAX_PATH);
if (readset[ret].path == NULL) {
return -1;

View File

@@ -636,6 +636,11 @@ libcalc_call_me_last(void)
}
}
/*
* free all globals
*/
freeglobals();
/*
* all done
*/

View File

@@ -161,7 +161,7 @@ removelistfirst(LIST *lp, VALUE *vp)
}
*vp = lp->l_first->e_value;
lp->l_first->e_value.v_type = V_NULL;
lp->l_first->e_value.v_type = V_NOSUBTYPE;
lp->l_first->e_value.v_subtype = V_NOSUBTYPE;
removelistelement(lp, lp->l_first);
}

View File

@@ -927,6 +927,7 @@ matindices(MATRIX *mp, long index)
lp = listalloc();
val.v_type = V_NUM;
val.v_subtype = V_NOSUBTYPE;
j = mp->m_dim;
while (--j >= 0) {
@@ -1068,6 +1069,7 @@ matident(MATRIX *m)
for (row = 0; row < rows; row++) {
for (col = 0; col < rows; col++) {
val->v_type = V_NUM;
val->v_subtype = V_NOSUBTYPE;
val->v_num = ((row == col) ? qlink(&_qone_) :
qlink(&_qzero_));
val++;
@@ -1126,6 +1128,7 @@ matinv(MATRIX *m)
else
val->v_num = qlink(&_qzero_);
val->v_type = V_NUM;
val->v_subtype = V_NOSUBTYPE;
val++;
}
}

View File

@@ -446,7 +446,7 @@ qisqrt(NUMBER *q)
}
zquo(q->num, q->den, &tmp, 0);
(void) zsqrt(tmp, &r->num,0);
freeh(tmp.v);
zfree(tmp);
return r;
}
@@ -673,7 +673,7 @@ qdigit(NUMBER *q, ZVALUE dpos, ZVALUE base)
/*
* In the first stage, q is expressed as base^k * N/D where
* gcd(D, base) = 1
* K is k as a ZVALUE
* K is k as a ZVALUE
*/
base.sign = 0;
if (ziszero(base) || zisunit(base))
@@ -683,6 +683,7 @@ qdigit(NUMBER *q, ZVALUE dpos, ZVALUE base)
return qlink(&_qzero_);
k = zfacrem(q->num, base, &N);
if (k == 0) {
zfree(N);
k = zgcdrem(q->den, base, &D);
if (k > 0) {
zequo(q->den, D, &A);

17
qmath.c
View File

@@ -37,26 +37,15 @@
NUMBER _qzero_ = { { _zeroval_, 1, 0 }, { _oneval_, 1, 0 }, 1, NULL };
NUMBER _qone_ = { { _oneval_, 1, 0 }, { _oneval_, 1, 0 }, 1, NULL };
NUMBER _qtwo_ = { { _twoval_, 1, 0 }, { _oneval_, 1, 0 }, 1, NULL };
NUMBER _qthree_ = { { _threeval_, 1, 0 }, { _oneval_, 1, 0 }, 1, NULL };
NUMBER _qfour_ = { { _fourval_, 1, 0 }, { _oneval_, 1, 0 }, 1, NULL };
NUMBER _qten_ = { { _tenval_, 1, 0 }, { _oneval_, 1, 0 }, 1, NULL };
NUMBER _qnegone_ = { { _oneval_, 1, 1 }, { _oneval_, 1, 0 }, 1, NULL };
NUMBER _qonehalf_ = { { _oneval_, 1, 0 }, { _twoval_, 1, 0 }, 1, NULL };
NUMBER _qneghalf_ = { { _oneval_, 1, 1 }, { _twoval_, 1, 0 }, 1, NULL };
NUMBER _qonesqbase_ = { { _oneval_, 1, 0 }, { _sqbaseval_, 2, 0 }, 1, NULL };
NUMBER _qtendivnine_ = { { _tenval_, 1, 0 }, { _nineval_, 1, 0 }, 1, NULL };
NUMBER _qninedivten_ = { { _nineval_, 1, 0 }, { _tenval_, 1, 0 }, 1, NULL };
NUMBER _qthreesixty = { { _threesixtyval_, 1, 0 },
{ _oneval_, 1, 0 }, 1, NULL };
NUMBER _qfourhundred = { { _fourhundredval_, 1, 0 },
{ _oneval_, 1, 0 }, 1, NULL };
NUMBER _qtwentyfour = { { _twentyfourval_, 1, 0 },
{ _oneval_, 1, 0 }, 1, NULL };
NUMBER * initnumbs[] = {&_qzero_, &_qone_, &_qtwo_, &_qthree_,
&_qfour_, &_qten_, &_qnegone_, &_qonehalf_, &_qneghalf_,
&_qonesqbase_, &_qtendivnine_, &_qninedivten_,
&_qthreesixty, &_qfourhundred, &_qtwentyfour,
NUMBER * initnumbs[] = {&_qzero_, &_qone_, &_qtwo_,
&_qten_, &_qnegone_, &_qonehalf_, &_qneghalf_,
&_qonesqbase_,
NULL /* must be last */
};

View File

@@ -272,9 +272,7 @@ static inline NUMBER* qlink(NUMBER* q) { if(q) { (q)->links++; } return q; }
* constants used often by the arithmetic routines
*/
EXTERN NUMBER _qzero_, _qone_, _qnegone_, _qonehalf_, _qneghalf_, _qonesqbase_;
EXTERN NUMBER _qtwo_, _qthree_, _qfour_, _qten_;
EXTERN NUMBER _qtendivnine_, _qninedivten_;
EXTERN NUMBER _qthreesixty, _qfourhundred, _qtwentyfour;
EXTERN NUMBER _qtwo_, _qten_;
EXTERN NUMBER * initnumbs[];

View File

@@ -1129,6 +1129,7 @@ qln(NUMBER *q, NUMBER *epsilon)
sum.sign = neg;
if (k + n >= m) {
zshift(sum, n - m, &qtmp->num);
zfree(sum);
} else {
if (k) {
zshift(sum, -k, &qtmp->num);

View File

@@ -96,16 +96,16 @@ S_FUNC QCKHASH blk_hash(BLOCK *blk, QCKHASH val);
* the next 32 bit QCKHASH
*
* Example:
* QCKHASH val;
* int x;
* QCKHASH val;
* int x;
*
* quasi_fnv(x, val);
* quasi_fnv(x, val);
*
* NOTE: The (x) argument may be an expression such as something with
* a ++ or --. The macro must only use (x) once.
* a ++ or --. The macro must only use (x) once.
*
* NOTE: The (val) argument just be a lvalue / something to which
* a value can be assigned.
* a value can be assigned.
*
* The careful observer will note that (x) need not be a simple
* octet. This is not a bug, but a feature. The FNV hash was
@@ -366,7 +366,7 @@ randhash(RAND *r, QCKHASH val)
return V_RAND+val;
} else {
/* hash control values */
val += V_RAND;
val += V_RAND;
quasi_fnv(r->j, val);
quasi_fnv(r->k, val);
quasi_fnv(r->bits, val);

4
rpm.mk
View File

@@ -49,7 +49,7 @@
# %_gpgbin /usr/bin/gpg
# IMPORTANT NOTE: Unless the package redhat-rpm-config is installed,
# the calc-debuginfo rpm will not be created.
# the calc-debuginfo rpm will not be created.
#
# IMPORTANT NOTE: These packages are important for general
# rpm processing:
@@ -266,7 +266,7 @@ chkpkg:
${V} echo '=-=-=-=-= rpm.mk start of $@ rule =-=-=-=-='
for i in "$(RPM_TOP)/RPMS/$(TARCH)/$(RPMx86_64)" \
"$(RPM_TOP)/RPMS/$(TARCH)/$(DRPMx86_64)" \
"$(RPM_TOP)/SRPMS/$(SRPM)" ; do \
"$(RPM_TOP)/SRPMS/$(SRPM)" ; do \
echo "***** start $$i" ; \
${RPM_TOOL} -qpi "$$"i ; \
echo "***** files $$i" ; \

View File

@@ -103,7 +103,7 @@ main(int argc, char **argv)
/*
* seed the generator
*/
prev_state = zsrandom2(seed, zconst[1]);
prev_state = zsrandom2(seed, _one_);
if (prev_state == NULL) {
math_error("previous random state is NULL");
/*NOTREACHED*/

View File

@@ -93,7 +93,7 @@ main(int argc, char **argv)
/*
* seed the generator
*/
prev_state = zsrandom2(seed, zconst[10]);
prev_state = zsrandom2(seed, _ten_);
if (prev_state == NULL) {
math_error("previous random state is NULL");
/*NOTREACHED*/

1
seed.c
View File

@@ -373,6 +373,7 @@ pseudo_seed(void)
* We do care (that much) if these calls fail. We do not
* need to process any data in the 'sdata' structure.
*/
memset(&sdata, 0, sizeof(sdata));
#if defined(HAVE_GETTIME)
# if defined(CLOCK_SGI_CYCLE)
(void) clock_gettime(CLOCK_SGI_CYCLE, &sdata.sgi_cycle);

83
str.c
View File

@@ -43,6 +43,7 @@
#define STR_TABLECHUNK 100 /* how often to reallocate string table */
#define STR_CHUNK (1<<11) /* size of string storage allocation */
#define OCTET_VALUES 256 /* number of different values in a OCTET */
#define STR_UNIQUE (1<<7) /* size of string to allocate separately */
STRING _nullstring_ = {"", 0, 1, NULL};
@@ -68,12 +69,14 @@ void
initstr(STRINGHEAD *hp)
{
if (hp->h_list == NULL) {
hp->h_list = (char *)malloc(2000);
/* alloc + 1 guard paranoia */
hp->h_list = (char *)malloc(STR_CHUNK + 1);
if (hp->h_list == NULL) {
math_error("Cannot allocate string header");
/*NOTREACHED*/
}
hp->h_avail = 2000;
hp->h_list[STR_CHUNK] = '\0'; /* guard paranoia */
hp->h_avail = STR_CHUNK;
hp->h_used = 0;
}
hp->h_avail += hp->h_used;
@@ -105,11 +108,14 @@ addstr(STRINGHEAD *hp, char *str)
if ((str == NULL) || (*str == '\0'))
return NULL;
len = strlen(str) + 1;
if (hp->h_avail <= len) {
newsize = len + 2000 + hp->h_used + hp->h_avail;
list = (char *)realloc(hp->h_list, newsize);
if (len >= hp->h_avail) {
/* alloc + 1 guard paranoia */
newsize = len + STR_CHUNK + hp->h_used + hp->h_avail + 1;
/* alloc + 1 guard paranoia */
list = (char *)realloc(hp->h_list, newsize + 1);
if (list == NULL)
return NULL;
list[newsize] = '\0'; /* guard paranoia */
hp->h_list = list;
hp->h_avail = newsize - hp->h_used;
}
@@ -134,16 +140,19 @@ charstr(int ch)
int i;
if (chartable == NULL) {
cp = (char *)malloc(512);
/* alloc + 1 guard paranoia */
cp = (char *)malloc((OCTET_VALUES + 1)*2);
if (cp == NULL) {
math_error("Cannot allocate character table");
/*NOTREACHED*/
}
for (i = 0; i < 256; i++) {
for (i = 0; i < OCTET_VALUES; i++) {
*cp++ = (char)i;
*cp++ = '\0';
}
chartable = cp - 512;
chartable = cp - (OCTET_VALUES*2);
*cp++ = '\0'; /* guard paranoia */
*cp++ = '\0'; /* guard paranoia */
}
return &chartable[(ch & 0xff) * 2];
}
@@ -274,11 +283,16 @@ addliteral(char *str)
*/
if (literals.l_count >= literals.l_maxcount) {
count = literals.l_maxcount + STR_TABLECHUNK;
if (literals.l_maxcount)
table = (char **) realloc(literals.l_table, count *
sizeof(char *));
else
table = (char **) malloc(count * sizeof(char *));
if (literals.l_maxcount) {
/* alloc + 1 guard paranoia */
table = (char **) realloc(literals.l_table,
(count + 1) * sizeof(char *));
table[count] = NULL; /* guard paranoia */
} else {
/* alloc + 1 guard paranoia */
table = (char **) malloc((count + 1) * sizeof(char *));
table[count] = NULL; /* guard paranoia */
}
if (table == NULL) {
math_error("Cannot allocate string literal table");
/*NOTREACHED*/
@@ -296,11 +310,13 @@ addliteral(char *str)
*/
len = ROUNDUP(len+1, FULL_LEN);
if (len >= STR_UNIQUE) {
newstr = (char *)malloc(len);
/* alloc + 1 guard paranoia */
newstr = (char *)malloc(len + 1);
if (newstr == NULL) {
math_error("Cannot allocate large literal string");
/*NOTREACHED*/
}
newstr[len] = '\0'; /* guard paranoia */
strlcpy(newstr, str, len);
table[literals.l_count++] = newstr;
return newstr;
@@ -310,11 +326,13 @@ addliteral(char *str)
* then allocate a new one.
*/
if (literals.l_avail < len) {
newstr = (char *)malloc(STR_CHUNK);
/* alloc + 1 guard paranoia */
newstr = (char *)malloc(STR_CHUNK + 1);
if (newstr == NULL) {
math_error("Cannot allocate new literal string");
/*NOTREACHED*/
}
newstr[STR_CHUNK] = '\0'; /* guard paranoia */
literals.l_alloc = newstr;
literals.l_avail = STR_CHUNK;
}
@@ -939,9 +957,9 @@ stringcaserel(STRING *s1, STRING *s2)
c2++;
}
if ( (tolower(*c1)) > (tolower(*c2)))
return 1;
return 1;
if ( (tolower(*c1)) < (tolower(*c2)))
return -1;
return -1;
if (i1 < i2) return -1;
return (i1 > i2);
}
@@ -1106,11 +1124,14 @@ stralloc(void)
STRING **newfn;
if (freeStr == NULL) {
freeStr = (STRING *) malloc(sizeof (STRING) * STRALLOC);
/* alloc + 1 guard paranoia */
freeStr = (STRING *) malloc(sizeof (STRING) * (STRALLOC + 1));
if (freeStr == NULL) {
math_error("Unable to allocate memory for stralloc");
/*NOTREACHED*/
}
/* guard paranoia */
memset(freeStr+STRALLOC, 0, sizeof(STRING));
freeStr[STRALLOC - 1].s_next = NULL;
freeStr[STRALLOC - 1].s_links = 0;
@@ -1132,10 +1153,16 @@ stralloc(void)
blockcount++;
if (firstStrs == NULL) {
newfn = (STRING **) malloc( blockcount * sizeof(STRING *));
} else {
/* alloc + 1 guard paranoia */
newfn = (STRING **)
realloc(firstStrs, blockcount * sizeof(STRING *));
malloc((blockcount + 1) * sizeof(STRING *));
newfn[blockcount] = NULL; /* guard paranoia */
} else {
/* alloc + 1 guard paranoia */
newfn = (STRING **)
realloc(firstStrs,
(blockcount + 1) * sizeof(STRING *));
newfn[blockcount] = NULL; /* guard paranoia */
}
if (newfn == NULL) {
math_error("Cannot allocate new string block");
@@ -1274,11 +1301,14 @@ STATIC STRING **stringconsttable;
void
initstrings(void)
{
stringconsttable = (STRING **) malloc(sizeof(STRING *) * STRCONSTALLOC);
/* alloc + 1 guard paranoia */
stringconsttable = (STRING **)
malloc(sizeof(STRING *) * (STRCONSTALLOC + 1));
if (stringconsttable == NULL) {
math_error("Unable to allocate constant table");
/*NOTREACHED*/
}
stringconsttable[STRCONSTALLOC] = NULL; /* guard paranoia */
stringconsttable[0] = &_nullstring_;
stringconstcount = 1;
stringconstavail = STRCONSTALLOC - 1;
@@ -1305,13 +1335,18 @@ addstring(char *str, size_t len)
if (stringconsttable == NULL) {
initstrings();
} else {
sp = (STRING **) realloc((char *) stringconsttable,
sizeof(STRING *) * (stringconstcount + STRCONSTALLOC));
/* alloc + 1 guard paranoia */
sp = (STRING **)
realloc((char *) stringconsttable,
sizeof(STRING *) *
(stringconstcount + STRCONSTALLOC + 1));
if (sp == NULL) {
math_error("Unable to reallocate string "
"const table");
/*NOTREACHED*/
}
/* guard paranoia */
sp[stringconstcount + STRCONSTALLOC] = NULL;
stringconsttable = sp;
stringconstavail = STRCONSTALLOC;
}

2
strl.c
View File

@@ -93,7 +93,7 @@ strlcpy(char * dst, const char * src, size_t dstsize)
/*
* perform the size limited copy and NUL terminate
*/
if (srclen > dstsize-1) {
if (srclen+1 > dstsize) {
memcpy(dst, src, dstsize-1);
dst[dstsize-1] = '\0';
#if defined(STRL_TEST)

View File

@@ -110,7 +110,8 @@ addglobal(char *name, BOOL isstatic)
return NULL;
hp = &globalhash[HASHSYM(name, len)];
for (sp = *hp; sp; sp = sp->g_next) {
if ((sp->g_len == len) && (strcmp(sp->g_name, name) == 0)
if ((sp->g_len == len) &&
(strncmp(sp->g_name, name, len+1) == 0)
&& (sp->g_filescope == newfilescope)
&& (sp->g_funcscope == newfuncscope))
return sp;
@@ -145,8 +146,9 @@ findglobal(char *name)
bestsp = NULL;
len = strlen(name);
for (sp = globalhash[HASHSYM(name, len)]; sp; sp = sp->g_next) {
if ((sp->g_len == len) && !strcmp(sp->g_name, name)) {
for (sp = globalhash[HASHSYM(name, len)]; sp != NULL; sp = sp->g_next) {
if ((sp->g_len == len) &&
(strncmp(sp->g_name, name, len+1) == 0)) {
if ((bestsp == NULL) ||
(sp->g_filescope > bestsp->g_filescope) ||
(sp->g_funcscope > bestsp->g_funcscope))
@@ -232,6 +234,7 @@ showallglobals(void)
printf("No global variables\n");
}
S_FUNC void
printtype(VALUE *vp)
{
@@ -360,6 +363,7 @@ writeglobals(char *name)
return 0;
}
/*
* Free all non-null global and visible static variables
*/

View File

@@ -54,7 +54,7 @@ static char *program;
#define MAJOR_VER 2 /* major library version */
#define MINOR_VER 14 /* minor library version */
#define MAJOR_PATCH 0 /* major software version level */
#define MINOR_PATCH 6 /* minor software version level */
#define MINOR_PATCH 10 /* minor software version level */
/*
@@ -79,7 +79,7 @@ char *Copyright = "\n"
"calc - arbitrary precision calculator\n"
"\n"
"Copyright (C) 1999-2021 David I. Bell, Landon Curt Noll "
"and Ernest Bowen\n"
"and Ernest Bowen\n"
"\n"
"Initial author: David I. Bell\n"
"\n"

20
zfunc.c
View File

@@ -1439,6 +1439,8 @@ zlog10(ZVALUE z, BOOL *was_10_power)
if (was_10_power != NULL) {
*was_10_power = TRUE;
}
zfree(pow10);
zfree(temp);
return power;
/* ignore this entry if we went too large */
@@ -1452,6 +1454,7 @@ zlog10(ZVALUE z, BOOL *was_10_power)
pow10 = temp;
}
}
zfree(pow10);
return power;
}
@@ -1616,7 +1619,7 @@ zfacrem(ZVALUE z1, ZVALUE z2, ZVALUE *rem)
long
zgcdrem(ZVALUE z1, ZVALUE z2, ZVALUE *res)
{
ZVALUE tmp1, tmp2;
ZVALUE tmp1, tmp2, tmp3, tmp4;
long count, onecount;
long sh;
@@ -1647,8 +1650,10 @@ zgcdrem(ZVALUE z1, ZVALUE z2, ZVALUE *res)
}
zgcd(z1, z2, &tmp1);
if (zisunit(tmp1) || ziszero(tmp1))
if (zisunit(tmp1) || ziszero(tmp1)) {
zfree(tmp1);
return 0;
}
zequo(z1, tmp1, &tmp2);
count = 1;
z1 = tmp2;
@@ -1658,16 +1663,19 @@ zgcdrem(ZVALUE z1, ZVALUE z2, ZVALUE *res)
* the gcd becomes one.
*/
while (!zisunit(z2)) {
onecount = zfacrem(z1, z2, &tmp1);
onecount = zfacrem(z1, z2, &tmp3);
if (onecount) {
count += onecount;
zfree(z1);
z1 = tmp1;
z1 = tmp3;
} else {
zfree(tmp3);
}
zgcd(z1, z2, &tmp1);
zgcd(z1, z2, &tmp4);
zfree(z2);
z2 = tmp1;
z2 = tmp4;
}
zfree(z2);
*res = z1;
return count;
}

104
zmath.c
View File

@@ -35,54 +35,27 @@
HALF _zeroval_[] = { 0 };
HALF _oneval_[] = { 1 };
HALF _twoval_[] = { 2 };
HALF _threeval_[] = { 3 };
HALF _fourval_[] = { 4 };
HALF _fiveval_[] = { 5 };
HALF _sixval_[] = { 6 };
HALF _sevenval_[] = { 7 };
HALF _eightval_[] = { 8 };
HALF _nineval_[] = { 9 };
HALF _tenval_[] = { 10 };
HALF _elevenval_[] = { 11 };
HALF _twelveval_[] = { 12 };
HALF _thirteenval_[] = { 13 };
HALF _fourteenval_[] = { 14 };
HALF _fifteenval_[] = { 15 };
HALF _sixteenval_[] = { 16 };
HALF _seventeenval_[] = { 17 };
HALF _eightteenval_[] = { 18 };
HALF _nineteenval_[] = { 19 };
HALF _twentyval_[] = { 20 };
HALF _sqbaseval_[] = { 0, 1 };
HALF _pow4baseval_[] = { 0, 0, 1 };
HALF _pow8baseval_[] = { 0, 0, 0, 0, 1 };
HALF _threesixtyval_[] = { 360 };
HALF _fourhundredval_[] = { 400 };
HALF _twentyfourval_[] = { 24 };
ZVALUE zconst[] = {
{ _zeroval_, 1, 0}, { _oneval_, 1, 0}, { _twoval_, 1, 0},
{ _threeval_, 1, 0}, { _fourval_, 1, 0}, { _fiveval_, 1, 0},
{ _sixval_, 1, 0}, { _sevenval_, 1, 0}, { _eightval_, 1, 0},
{ _nineval_, 1, 0}, { _tenval_, 1, 0}, { _elevenval_, 1, 0},
{ _twelveval_, 1, 0}, { _thirteenval_, 1, 0}, { _fourteenval_, 1, 0},
{ _fifteenval_, 1, 0}, { _sixteenval_, 1, 0}, { _seventeenval_, 1, 0},
{ _eightteenval_, 1, 0}, { _nineteenval_, 1, 0}, { _twentyval_, 1, 0},
{ _threesixtyval_, 1, 0}, { _fourhundredval_, 1, 0},
{ _twentyfourval_, 1, 0}
};
ZVALUE _zero_ = { _zeroval_, 1, 0};
HALF _oneval_[] = { 1 };
ZVALUE _one_ = { _oneval_, 1, 0 };
ZVALUE _two_ = { _twoval_, 1, 0 };
ZVALUE _ten_ = { _tenval_, 1, 0 };
ZVALUE _sqbase_ = { _sqbaseval_, 2, 0 };
ZVALUE _pow4base_ = { _pow4baseval_, 4, 0 };
ZVALUE _pow8base_ = { _pow8baseval_, 4, 0 };
ZVALUE _neg_one_ = { _oneval_, 1, 1 };
HALF _twoval_[] = { 2 };
ZVALUE _two_ = { _twoval_, 1, 0 };
HALF _tenval_[] = { 10 };
ZVALUE _ten_ = { _tenval_, 1, 0 };
HALF _sqbaseval_[] = { 0, 1 };
ZVALUE _sqbase_ = { _sqbaseval_, 2, 0 };
HALF _pow4baseval_[] = { 0, 0, 1 };
ZVALUE _pow4base_ = { _pow4baseval_, 4, 0 };
HALF _pow8baseval_[] = { 0, 0, 0, 0, 1 };
ZVALUE _pow8base_ = { _pow8baseval_, 4, 0 };
/*
* 2^64 as a ZVALUE
*/
@@ -96,6 +69,20 @@ ZVALUE _b64_ = { _pow8baseval_, 5, 0 };
-=@=- BASEB not 16 or 32 -=@=-
#endif
/*
* ZVALUE - values that should not be freed
*/
HALF *half_tbl[] = {
_zeroval_,
_oneval_,
_twoval_,
_tenval_,
_sqbaseval_,
_pow4baseval_,
_pow8baseval_,
NULL /* must be last */
};
/*
* highhalf[i] - masks off the upper i bits of a HALF
@@ -260,11 +247,38 @@ alloc(LEN len)
}
/*
* is_const - determine if a HALF array is an pre-allocated array
*
* given:
* h pointer to the beginning of the HALF array
*
* returns:
* TRUE - h is found in the half_tbl array
* FALSE - is is not found in the half_tbl array
*/
int
is_const(HALF* h)
{
HALF **h_p; /* half_tbl array pointer */
/* search the half_tbl for h */
for (h_p = &half_tbl[0]; *h_p != NULL; ++h_p) {
if (h == *h_p) {
return TRUE; /* found in the half_tbl array */
}
}
/* not found in the half_tbl array */
return FALSE;
}
#ifdef ALLOCTEST
void
freeh(HALF *h)
{
if ((h != _zeroval_) && (h != _oneval_)) {
if (!is_const(h)) {
free(h);
++nfree;
}

46
zmath.h
View File

@@ -55,8 +55,7 @@
#ifndef ALLOCTEST
# define freeh(p) { if (((void *)p != (void *)_zeroval_) && \
((void *)p != (void *)_oneval_)) free((void *)p); }
# define freeh(p) { if (!is_const(p)) { free((void *)(p)); } }
#endif
@@ -289,6 +288,7 @@ typedef struct {
* Function prototypes for integer math routines.
*/
E_FUNC HALF * alloc(LEN len);
E_FUNC int is_const(HALF* h);
#ifdef ALLOCTEST
E_FUNC void freeh(HALF *);
#endif
@@ -579,7 +579,12 @@ E_FUNC void zredcpower(REDC *rp, ZVALUE z1, ZVALUE z2, ZVALUE *res);
#define zcopyval(z1,z2) memcpy((z2).v, (z1).v, (z1).len * sizeof(HALF))
#define zquicktrim(z) {if (((z).len > 1) && ((z).v[(z).len-1] == 0)) \
(z).len--;}
#define zfree(z) freeh((z).v)
#define zfree(z) {if ((z).len != 0 && (z).v != NULL) { \
freeh((z).v); \
(z).v = NULL; \
(z).len = 0; \
(z).sign = 0; } \
}
/*
@@ -642,20 +647,35 @@ E_FUNC ZVALUE *swap_HALF_in_ZVALUE(ZVALUE *dest, ZVALUE *src, BOOL all);
/*
* constants used often by the arithmetic routines
*/
EXTERN HALF _zeroval_[], _oneval_[], _twoval_[], _threeval_[], _fourval_[];
EXTERN HALF _fiveval_[], _sixval_[], _sevenval_[], _eightval_[], _nineval_[];
EXTERN HALF _tenval_[], _elevenval_[], _twelveval_[], _thirteenval_[];
EXTERN HALF _fourteenval_[], _fifteenval_[];
EXTERN HALF _zeroval_[];
EXTERN ZVALUE _zero_;
EXTERN HALF _oneval_[];
EXTERN ZVALUE _one_;
EXTERN ZVALUE _neg_one_;
EXTERN HALF _twoval_[];
EXTERN ZVALUE _two_;
EXTERN HALF _tenval_[];
EXTERN ZVALUE _ten_;
EXTERN HALF _sqbaseval_[];
EXTERN HALF _fourthbaseval_[];
EXTERN HALF _threesixtyval_[], _fourhundredval_[], _twentyfourval_[];
EXTERN ZVALUE _sqbase_;
EXTERN ZVALUE zconst[]; /* ZVALUE integers from 0 thru 15 */
EXTERN HALF _pow4baseval_[];
EXTERN ZVALUE _pow4base_;
EXTERN ZVALUE _zero_, _one_, _two_, _ten_, _neg_one_;
EXTERN ZVALUE _sqbase_, _pow4base_, _pow8base_;
EXTERN HALF _pow8baseval_[];
EXTERN ZVALUE _pow8base_;
EXTERN ZVALUE _b32_, _b64_;
/* _b32_ is _sqbaseval_ or _pow4baseval_ depending on BASEB */
EXTERN ZVALUE _b32_;
/* _b64_ is _pow4baseval_ or _pow8baseval_ depending on BASEB */
EXTERN ZVALUE _b64_;
EXTERN HALF *half_tbl[]; /* preset HALF constants, NULL termated list */
EXTERN BOOL _math_abort_; /* nonzero to abort calculations */
EXTERN ZVALUE _tenpowers_[]; /* table of 10^2^n */

33
zmod.c
View File

@@ -493,6 +493,7 @@ zpowermod(ZVALUE z1, ZVALUE z2, ZVALUE z3, ZVALUE *res)
HALF curhalf; /* current word of power */
unsigned int curpow; /* current low power */
unsigned int curbit; /* current bit of low power */
BOOL free_z1; /* TRUE => need to free z1 */
int i;
if (zisneg(z3) || ziszero(z3)) {
@@ -535,17 +536,22 @@ zpowermod(ZVALUE z1, ZVALUE z2, ZVALUE z3, ZVALUE *res)
* within the modulo range. Then check for zero or one specially.
*/
ztmp.len = 0;
free_z1 = FALSE;
if (zisneg(z1) || zrel(z1, z3) >= 0) {
zmod(z1, z3, &ztmp, 0);
zfree(z1);
z1 = ztmp;
free_z1 = TRUE;
}
if (ziszero(z1)) {
zfree(z1);
if (ztmp.len)
zfree(ztmp);
*res = _zero_;
return;
}
if (zisone(z1)) {
zfree(z1);
if (ztmp.len)
zfree(ztmp);
*res = _one_;
@@ -598,10 +604,12 @@ zpowermod(ZVALUE z1, ZVALUE z2, ZVALUE z3, ZVALUE *res)
* future use.
*/
if (pp->v == NULL) {
if (curpow & 0x1)
if (curpow & 0x1) {
zcopy(z1, &modpow);
else
free_z1 = FALSE;
} else {
modpow = _one_;
}
for (curbit = 0x2;
curbit <= curpow;
@@ -667,8 +675,7 @@ zpowermod(ZVALUE z1, ZVALUE z2, ZVALUE z3, ZVALUE *res)
}
for (pp = &lowpowers[2]; pp <= &lowpowers[POWNUMS-1]; pp++) {
if (pp->v != NULL)
freeh(pp->v);
zfree(*pp);
}
*res = ans;
if (ztmp.len)
@@ -689,6 +696,9 @@ zpowermod(ZVALUE z1, ZVALUE z2, ZVALUE z3, ZVALUE *res)
powermodredc = zredcalloc(z3);
rp = powermodredc;
zredcencode(rp, z1, &temp);
if (free_z1 == TRUE) {
zfree(z1);
}
zredcpower(rp, temp, z2, &z1);
zfree(temp);
zredcdecode(rp, z1, res);
@@ -727,10 +737,12 @@ zpowermod(ZVALUE z1, ZVALUE z2, ZVALUE z3, ZVALUE *res)
* calculate it and remember it in the table for future use.
*/
if (pp->v == NULL) {
if (curpow & 0x1)
if (curpow & 0x1) {
zcopy(z1, &modpow);
else
free_z1 = FALSE;
} else {
modpow = _one_;
}
for (curbit = 0x2; curbit <= curpow; curbit *= 2) {
pp = &lowpowers[curbit];
@@ -789,12 +801,14 @@ zpowermod(ZVALUE z1, ZVALUE z2, ZVALUE z3, ZVALUE *res)
}
for (pp = &lowpowers[2]; pp <= &lowpowers[POWNUMS-1]; pp++) {
if (pp->v != NULL)
freeh(pp->v);
zfree(*pp);
}
*res = ans;
if (ztmp.len)
zfree(ztmp);
if (free_z1 == TRUE) {
zfree(z1);
}
}
/*
@@ -1836,8 +1850,7 @@ zredcpower(REDC *rp, ZVALUE z1, ZVALUE z2, ZVALUE *res)
}
for (pp = lowpowers; pp < &lowpowers[POWNUMS]; pp++) {
if (pp->len)
freeh(pp->v);
zfree(*pp);
}
if (sign && !ziszero(ans)) {
zsub(rp->mod, ans, res);

View File

@@ -1092,6 +1092,15 @@
STATIC RANDOM blum;
/*
* static constants 3 and 4 used by zsrandom4
*/
STATIC HALF _threeval_[] = { 3 };
STATIC ZVALUE _three_ = { _threeval_, 1, 0 };
STATIC HALF _fourval_[] = { 4 };
STATIC ZVALUE _four_ = { _fourval_, 1, 0 };
/*
* Default Blum generator
*
@@ -2296,19 +2305,19 @@ zsrandom1(CONST ZVALUE seed, BOOL need_ret)
last_r.v = NULL;
do {
/* free temp storage */
if (last_r.v != NULL) {
zfree_random(last_r);
}
zfree_random(last_r);
/*
* last_r = r;
* r = pmod(last_r, 2, n);
*/
last_r = r;
zcopy(r, &last_r);
zfree_random(r);
zsquaremod(last_r, blum.n, &r);
} while (zrel(r, last_r) > 0);
zfree_random(blum.r);
blum.r = r;
/* free temp storage */
zfree_random(last_r);
@@ -2532,11 +2541,11 @@ zsrandom4(CONST ZVALUE seed, CONST ZVALUE ip, CONST ZVALUE iq, long trials)
/*
* search the 'p' and 'q' Blum prime (3 mod 4) candidates
*/
if (!znextcand(ip, trials, _zero_, zconst[3], zconst[4], &p)) {
if (!znextcand(ip, trials, _zero_, _three_, _four_, &p)) {
math_error("failed to find 1st Blum prime");
/*NOTREACHED*/
}
if (!znextcand(iq, trials, _zero_, zconst[3], zconst[4], &q)) {
if (!znextcand(iq, trials, _zero_, _three_, _four_, &q)) {
math_error("failed to find 2nd Blum prime");
/*NOTREACHED*/
}
@@ -2663,6 +2672,9 @@ zrandomskip(long cnt)
free(p_blum);
}
loglogn = (long)blum.loglogn;
new_r.len = 0; /* paranoia */
new_r.v = NULL;
new_r.sign = 0;
/*
* skip required bits in the buffer
@@ -2769,6 +2781,9 @@ zrandom(long cnt, ZVALUE *res)
}
loglogn = blum.loglogn;
mask = blum.mask;
new_r.len = 0; /* paranoia */
new_r.v = NULL;
new_r.sign = 0;
/*
* allocate storage
@@ -3062,21 +3077,16 @@ randomcopy(CONST RANDOM *state)
void
randomfree(RANDOM *state)
{
/* avoid free of the pre-defined states */
if (state == &init_blum) {
return;
}
if (state >= &random_pregen[0] &&
state <= &random_pregen[BLUM_PREGEN-1]) {
return;
}
/* free the values */
zfree_random(state->n);
zfree_random(state->r);
/* free it if it is not pre-defined */
state->seeded = 0;
state->bits = 0; /* paranoia */
state->buffer = 0;
/* free it if it is not pre-defined */
if (state != &blum) {
free(state);
}