mirror of
https://github.com/lcn2/calc.git
synced 2025-08-22 01:23:28 +03:00
Compare commits
36 Commits
v2.14.0.6
...
v2.14.0.10
Author | SHA1 | Date | |
---|---|---|---|
|
769ac51f8c | ||
|
cdda633369 | ||
|
50f349f4d7 | ||
|
ef00e00328 | ||
|
bb041098bc | ||
|
f794b8d859 | ||
|
bd990cef1f | ||
|
febb9d96b3 | ||
|
13ae9b804e | ||
|
56cc4897d6 | ||
|
eb940e0a21 | ||
|
f3adb35e36 | ||
|
d1d365d7ba | ||
|
af214b166d | ||
|
51b933dfff | ||
|
c4e5007587 | ||
|
c838798f04 | ||
|
23d49a41fe | ||
|
3d300acca1 | ||
|
8f449ba6d2 | ||
|
f4d754b47d | ||
|
fde724aa2d | ||
|
e411a3e6bf | ||
|
7db81649b0 | ||
|
08fe6f13f4 | ||
|
e11d159c81 | ||
|
dfd66be871 | ||
|
27f977b545 | ||
|
2ca6e789ca | ||
|
ff8f921ebc | ||
|
005b78227a | ||
|
b7a42a9d3d | ||
|
3d1e938cb6 | ||
|
8b98a7c1f6 | ||
|
dbf5acf5e8 | ||
|
5fe5ab1c4b |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -94,6 +94,7 @@ sample_rand
|
||||
tags
|
||||
terminal.h
|
||||
ver_calc
|
||||
win32/
|
||||
|
||||
# other commonly excluded patterns
|
||||
#
|
||||
|
134
CHANGES
134
CHANGES
@@ -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:
|
||||
|
||||
|
@@ -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:
|
||||
|
||||
|
4
LIBRARY
4
LIBRARY
@@ -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
|
||||
|
28
Makefile
28
Makefile
@@ -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"; \
|
||||
|
@@ -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; \
|
||||
|
24
cal/Makefile
24
cal/Makefile
@@ -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 \
|
||||
|
38
cal/README
38
cal/README
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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 */
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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 */
|
||||
|
@@ -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)));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -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
641
cal/palindrome.cal
Normal 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;
|
||||
}
|
@@ -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);
|
||||
|
@@ -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
20
calc.c
@@ -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);
|
||||
}
|
||||
|
@@ -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 \
|
||||
|
@@ -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.
|
||||
|
||||
|
@@ -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 \
|
||||
|
@@ -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
|
||||
#
|
||||
|
@@ -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 \
|
||||
|
@@ -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
2
file.c
@@ -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
27
func.c
@@ -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
56
help.c
@@ -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 */
|
||||
}
|
||||
|
||||
|
@@ -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 \
|
||||
|
@@ -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
|
||||
|
10
help/config
10
help/config
@@ -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"
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
14
help/intro
14
help/intro
@@ -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
|
||||
|
@@ -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
|
||||
|
16
help/jacobi
16
help/jacobi
@@ -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;
|
||||
}
|
||||
|
4
help/mat
4
help/mat
@@ -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
|
||||
|
8
help/mod
8
help/mod
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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.
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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.
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -18,7 +18,7 @@ DESCRIPTION
|
||||
|
||||
EXAMPLE
|
||||
; strtolower(" GNU Lesser General Public License");
|
||||
" gnu lesser general public license"
|
||||
" gnu lesser general public license"
|
||||
|
||||
LIMITS
|
||||
none.
|
||||
|
@@ -18,7 +18,7 @@ DESCRIPTION
|
||||
|
||||
EXAMPLE
|
||||
; strtoupper(" GNU Lesser General Public License");
|
||||
" GNU LESSER GENERAL PUBLIC LICENSE"
|
||||
" GNU LESSER GENERAL PUBLIC LICENSE"
|
||||
|
||||
LIMITS
|
||||
none.
|
||||
|
@@ -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:
|
||||
|
||||
|
@@ -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
|
||||
|
2
input.c
2
input.c
@@ -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;
|
||||
|
@@ -636,6 +636,11 @@ libcalc_call_me_last(void)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* free all globals
|
||||
*/
|
||||
freeglobals();
|
||||
|
||||
/*
|
||||
* all done
|
||||
*/
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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++;
|
||||
}
|
||||
}
|
||||
|
5
qfunc.c
5
qfunc.c
@@ -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
17
qmath.c
@@ -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 */
|
||||
};
|
||||
|
||||
|
4
qmath.h
4
qmath.h
@@ -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[];
|
||||
|
||||
|
||||
|
1
qtrans.c
1
qtrans.c
@@ -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);
|
||||
|
12
quickhash.c
12
quickhash.c
@@ -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
4
rpm.mk
@@ -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" ; \
|
||||
|
@@ -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*/
|
||||
|
@@ -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
1
seed.c
@@ -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
83
str.c
@@ -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
2
strl.c
@@ -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)
|
||||
|
10
symbol.c
10
symbol.c
@@ -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
|
||||
*/
|
||||
|
@@ -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
20
zfunc.c
@@ -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
104
zmath.c
@@ -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
46
zmath.h
@@ -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
33
zmod.c
@@ -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);
|
||||
|
40
zrandom.c
40
zrandom.c
@@ -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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user