Compare commits

..

411 Commits

Author SHA1 Message Date
Landon Curt Noll
232b3bddef Release v2.15.1.0
The following are the changes in this release:

    Converted all ASCII tabs to ASCII spaces using a 8 character
    tab stop, for all files, except for all Makefiles (plus rpm.mk).
    The command `git diff -w` reports no changes.  There is no
    functionality change in calc: only ASCII tabs to ASCII spaces.

    Fixed trailblank.  It was pruning . in its find search.
    Added check for ASCII tabs is non-Makefiles.

    This version will form the basis for the calc v2 to calc v3 fork.
2024-07-11 22:49:00 -07:00
Landon Curt Noll
5ac3e495b2 prep CHANGES for the next release of calc 2024-07-11 22:45:39 -07:00
Landon Curt Noll
56153d6615 fix trailblank and sort .gitignore 2024-07-11 22:42:37 -07:00
Landon Curt Noll
2a4f399593 prep CHANGES for the next release of calc 2024-07-11 22:14:31 -07:00
Landon Curt Noll
160de4bb38 prep CHANGES for the next release of calc 2024-07-11 22:12:41 -07:00
Landon Curt Noll
db77e29a23 convert ASCII TABs to ASCII SPACEs
Converted all ASCII tabs to ASCII spaces using a 8 character
tab stop, for all files, except for all Makefiles (plus rpm.mk).
The `git diff -w` reports no changes.
2024-07-11 22:03:52 -07:00
Landon Curt Noll
fe9cefe6ef fix dependabot.yml location
GitHub parses `dependabot.yml` as an action file because I put it in .github/workflows/ by mistake.
It should be `.github/dependabot.yml`.

See https://stackoverflow.com/questions/69446872/dependabot-error-githubl1-no-event-triggers-defined-in-on
2024-07-04 12:18:14 -07:00
Landon Curt Noll
ea4c50ade0 updated codeql-analysis.yml
Merged from mkiocccentry: .github/workflows/codeql.yml
2024-07-03 23:12:53 -07:00
Landon Curt Noll
7f72908b95 add regression test for ilog2 bug
Added regress test to verify the
[fix](33815f49e6)
for
[issue #148](https://github.com/lcn2/calc/issues/148).

Sorry: We forgot to include this regression test to previous update.
2024-05-31 18:23:23 -07:00
Landon Curt Noll
a547c36f0a prep CHANGES for the next release of calc 2024-05-27 18:47:41 -07:00
Landon Curt Noll
1e2698b42d Merge pull request #149 from bambooleafz/master
this should fixes issue #148
2024-05-27 18:36:31 -07:00
bambooleafz
33815f49e6 Update qfunc.c
the previous `*qlog2 = utoq(log2)` may be incorrect. under that case, `qlog2` actually points to `_qone_` and causes `_qone_` changed
2024-05-27 19:40:59 +08:00
Landon Curt Noll
732279bcc3 Merge pull request #147 from fruityloops1/master 2024-05-13 11:52:00 -07:00
fruityloops1
7f4e1eb68d Fix help page typo 2024-05-13 20:43:41 +02:00
Landon Curt Noll
1232b59949 Merge pull request #144 from coreysciuto-toast/patch-1
Fix Manpage typo
2024-02-12 14:39:23 -08:00
Corey Sciuto
90feefc622 Fix Manpage typo 2024-02-12 16:59:15 -05:00
Landon Curt Noll
c97ee188ad Release v2.15.0.6
The following are the changes in this release:

     Thanks to GitHub user @ashamedbit, a long standing memory leak in
     zrandom.c has been fixed.
2024-02-09 08:28:56 -08:00
Landon Curt Noll
ae85846839 improve useful strings produced by update_ver 2024-02-09 08:27:02 -08:00
Landon Curt Noll
e096bd9ad8 credit @ashamedbit a memory leak fix in zrandom.c 2024-02-09 08:02:50 -08:00
Landon Curt Noll
884b1bc81b Merge pull request #142 from ashamedbit/fix-memory-leak
Fix memory leak in zrandom.c
2024-02-09 07:53:47 -08:00
ashamedbit
a30a518ba7 Fix memory leak in zrandom.c 2024-02-09 03:48:11 -05:00
Landon Curt Noll
bb3b861090 Release v2.15.0.5
The following are the changes in this release:

     make clobber now removes the legacy files: have_fpos.h, help/man,
     and help/usage.  The latter 2 are now managed as help aliases
     in help.c.

     make install now removes the legacy files: ${HELPDIR}/man
     and ${HELPDIR}/usage.

     Fixed a problem where, when calc was linked with and uses GNU
     readline then for any multi-line copy-and-paste, only the first
     line is executed.  Thanks to GitHub user @malfisya for reporting
     this problem, and thanks to GitHub user @gromit1811 for doing
     the research needed to overcome deficiencies in the GNU readline
     documentation, and for supplying the work-a-round to allow
     multi-line copy-and-paste to work as expected!
2024-02-01 20:45:42 -08:00
Landon Curt Noll
0a3469125e prep CHANGES for the next release of calc 2024-02-01 20:38:19 -08:00
Landon Curt Noll
9b37e79f21 update CHANGES, fix make clobber and make install
make clobber also removes the legacy files: help/man, and help/usage.

make install now removes the legacy files: ${HELPDIR}/man and
${HELPDIR}/usage.

Document the GNU readline then for any multi-line copy-and-paste
fix in CHANGES.
2024-01-05 10:21:26 -08:00
Landon Curt Noll
18cd1f9067 Merge pull request #139 from gromit1811/master
Properly handle multi-line strings and newline returned by readline()
2024-01-05 09:51:47 -08:00
Martin Buck
43fc022dc8 Properly handle multi-line strings and newline returned by readline()
Fix for #138

According to
https://lists.gnu.org/archive/html/bug-readline/2024-01/msg00000.html
it's OK for readline() to return multi-line strings and/or newlines in case
of bracketed paste (enabled by default since readline 8.1) and also in other
situations even though its documentation explicitly states the opposite. So
we need to handle this properly in calc instead of just using the first line
and dropping the rest: Split the string returned by readline() into lines
and return line by line with each invocation of hist_getline(), each
possbily adding a terminating newline.
2024-01-05 10:34:25 +01:00
Landon Curt Noll
29695028cd improve make clobber
make clobber now removes the legacy file: have_fpos.h
2023-12-26 12:41:29 -08:00
Landon Curt Noll
1d37930d22 Release v2.15.0.4
The following are the changes in this release:

    Fixed bug that caused calc to fail to compile filepos2z() in file.c
    on little endian machines for the Debian apcalc package.  Thanks to
    Martin Buck (m at rtin-buck dor de) for for fix.

    Removed unused macros from zmath.h:

	SWAP_B32_IN_HASH(dest, src)
	SWAP_B16_IN_HASH(dest, src)
	SWAP_B8_IN_HASH(dest, src)
	SWAP_B32_IN_FLAG(dest, src)
	SWAP_B16_IN_FLAG(dest, src)
	SWAP_B8_IN_FLAG(dest, src)

    When SWAP_HALF_IN_B32(dest, src), SWAP_B32_IN_FULL(dest, src),
    SWAP_B16_IN_HALF(dest, src), SWAP_B32_IN_bool(dest, src),
    or SWAP_B32_IN_LEN(dest, src), SWAP_HALF_IN_FILEPOS(dest, src)
    is an assignment such as:

	(*(dest) = *(src))

    We now case the dest and src pointers to the proper type before
    referencing and performing the assignment.

    Documented unexpected behavior when calc is running in
    "shell script mode" and the prompt builtin function is used
    without the -p flag.  Updated help/prompt, help/unexpected
    and the calc man page accordingly.

    Unless calc is given the -p command line option, calc will reopen
    stdin as /dev/null instead of just closing stdin.  This prevents
    subsequent opens grabbing the 1st file descriptor.

    Disable regress tests 4709, 4710, and 7763 because they print
    multi-byte sequences, which are just fine for calc, the awk
    used to evaluate the regression suite output in some legacy
    systems report a "multibyte conversion failure".

    Added a number of missing Makefile variables to the "make env" rule.

    The man command is used to format the calc.1 man page into calc.usage.

    The "help calc" command now prints the formatted calc man page (calc.usage).
    The "help man" command now prints the formatted calc man page (calc.usage).
    The "help usage" command now prints the formatted calc man page (calc.usage).

    The file, calc.cat1, is formed by gzipping the calc.usage
    formatted man page.  The calc.cat1 is installed as the calc
    cat section 1 man page.

    Updated the Copyright string in version.c to refer to
    the COPYING file and the "help copying" command.

    Added calc.cat1 to .gitignore.  Using "sort -d -u" to sort .gitignore content.

    Avoiding use of modern [[ and ]] in Makefile for those legacy systems
    whose shell do not support them.  Be sure to use ||'s between []'s
    to avoid problems with legacy shell such as the Bourne shell. *sigh*

    Fixed the order of "help full" to match the order of topics listed
    buy the "help help" command.

    Sorted the halias[] help topics table in help.c using sort -d -u.
2023-12-21 05:52:06 -08:00
Landon Curt Noll
60698d2130 fix Makefile for legacy shell
The top level Makefile needs to use multiple []'s between  ||'s
to not cause problems for legacy shells such as the Bourne shell.

For example:

```make
	-${Q} if [ -z "${MANDIR}" ] || [ ! -s calc.1 ]; then \
...
	-${Q} if [ -z "${CATDIR}" ] || [ ! -s calc.cat1 ]; then \
```
2023-12-21 05:44:19 -08:00
Landon Curt Noll
3e7ccfd31c Release v2.15.0.3
The following are the changes in this release:

    Fixed bug that caused calc to fail to compile filepos2z() in file.c
    on little endian machines for the Debian apcalc package.  Thanks to
    Martin Buck (m at rtin-buck dor de) for for fix.

    Removed unused macros from zmath.h:

	SWAP_B32_IN_HASH(dest, src)
	SWAP_B16_IN_HASH(dest, src)
	SWAP_B8_IN_HASH(dest, src)
	SWAP_B32_IN_FLAG(dest, src)
	SWAP_B16_IN_FLAG(dest, src)
	SWAP_B8_IN_FLAG(dest, src)

    When SWAP_HALF_IN_B32(dest, src), SWAP_B32_IN_FULL(dest, src),
    SWAP_B16_IN_HALF(dest, src), SWAP_B32_IN_bool(dest, src),
    or SWAP_B32_IN_LEN(dest, src), SWAP_HALF_IN_FILEPOS(dest, src)
    is an assignment such as:

	(*(dest) = *(src))

    We now case the dest and src pointers to the proper type before
    referencing and performing the assignment.

    Documented unexpected behavior when calc is running in
    "shell script mode" and the prompt builtin function is used
    without the -p flag.  Updated help/prompt, help/unexpected
    and the calc man page accordingly.

    Unless calc is given the -p command line option, calc will reopen
    stdin as /dev/null instead of just closing stdin.  This prevents
    subsequent opens grabbing the 1st file descriptor.

    Disable regress tests 4709, 4710, and 7763 because they print
    multi-byte sequences, which are just fine for calc, the awk
    used to evaluate the regression suite output in some legacy
    systems report a "multibyte conversion failure".

    Added a number of missing Makefile variables to the "make env" rule.

    The man command is used to format the calc.1 man page into calc.usage.

    The "help calc" command now prints the formatted calc man page (calc.usage).
    The "help man" command now prints the formatted calc man page (calc.usage).
    The "help usage" command now prints the formatted calc man page (calc.usage).

    The file, calc.cat1, is formed by gzipping the calc.usage
    formatted man page.  The calc.cat1 is installed as the calc
    cat section 1 man page.

    Updated the Copyright string in version.c to refer to
    the COPYING file and the "help copying" command.

    Added calc.cat1 to .gitignore.  Using "sort -d -u" to sort .gitignore content.

    Avoiding use of modern [[ and ]] in Makefile for those legacy systems
    whose shell do not support them.  *sigh*

    Fixed the order of "help full" to match the order of topics listed
    buy the "help help" command.

    Sorted the halias[] help topics table in help.c using sort -d -u.
2023-12-21 05:33:43 -08:00
Landon Curt Noll
488d81b809 prep CHANGES for the next release of calc 2023-12-21 05:29:01 -08:00
Landon Curt Noll
932d27053e update help/prompt copyright date
Put back 2006 date between 1999 and 2023.
2023-12-19 03:15:20 -08:00
Landon Curt Noll
8e8d6c852a fix distlist inventory and fix make clobber 2023-12-19 01:00:25 -08:00
Landon Curt Noll
54dd89dcf7 document prompt in shell script mode, fix man formatting, legacy awk
Documented unexpected behavior when calc is running in
"shell script mode" and the prompt builtin function is used
without the -p flag.  Updated help/prompt, help/unexpected
and the calc man page accordingly.

Unless calc is given the -p command line option, calc will reopen
stdin as /dev/null instead of just closing stdin.  This prevents
subsequent opens grabbing the 1st file descriptor.

Disable regress tests 4709, 4710, and 7763 because they print
multi-byte sequences, which are just fine for calc, the awk
used to evaluate the regression suite output in some legacy
systems report a "multibyte conversion failure".

Added a number of missing Makefile variables to the "make env" rule.

The man command is used to format the calc.1 man page into calc.usage.

The "help calc" command now prints the formatted calc man page (calc.usage).
The "help man" command now prints the formatted calc man page (calc.usage).
The "help usage" command now prints the formatted calc man page (calc.usage).

The file, calc.cat1, is formed by gzipping the calc.usage
formatted man page.  The calc.cat1 is installed as the calc
cat section 1 man page.

Updated the Copyright string in version.c to refer to
the COPYING file and the "help copying" command.

Added calc.cat1 to .gitignore.  Using "sort -d -u" to sort .gitignore content.

Avoiding use of modern [[ and ]] in Makefile for those legacy systems
whose shell do not support them.  *sigh*

Fixed the order of "help full" to match the order of topics listed
buy the "help help" command.

Sorted the halias[] help topics table in help.c using sort -d -u.
2023-12-19 00:40:10 -08:00
Landon Curt Noll
d91e966f19 improve how calc compiles on big endian machines
Fixed bug that caused calc to fail to compile filepos2z() in file.c
on little endian machines for the Debian apcalc package.  Thanks to
Martin Buck (m at rtin-buck dor de) for for fix.

Removed unused macros from zmath.h:

    SWAP_B32_IN_HASH(dest, src)
    SWAP_B16_IN_HASH(dest, src)
    SWAP_B8_IN_HASH(dest, src)
    SWAP_B32_IN_FLAG(dest, src)
    SWAP_B16_IN_FLAG(dest, src)
    SWAP_B8_IN_FLAG(dest, src)

When SWAP_HALF_IN_B32(dest, src), SWAP_B32_IN_FULL(dest, src),
SWAP_B16_IN_HALF(dest, src), SWAP_B32_IN_bool(dest, src),
or SWAP_B32_IN_LEN(dest, src), SWAP_HALF_IN_FILEPOS(dest, src)
is an assignment such as:

    (*(dest) = *(src))

We now case the dest and src pointers to the proper type before
referencing and performing the assignment.
2023-12-14 23:20:35 -08:00
Landon Curt Noll
8d6f83ad91 Release v2.15.0.2
The following are the changes in this release:

    Updated BUGS about MSYS2 on Windows compiling of calc.

    Added more git related checks and sanity checks to chk_tree.

    Added ${FSANITIZE} make variable to Makefile.config to hold
    common Address Sanitizer (ASAN) optins to modern Linux and macOS.
    The Address Sanitizer is NOT enabled not compiled in by default.
    Improved comments in Makefile.local for RHEL9.2 (Linux) and for
    macOS 14.0 that, when uncommented and calc is recompiled (i.e.,
    make clobber all) will enable the Address Sanitizer (ASAN) for calc.

    Fixed memory leaks in the logn, aversin, acoversin, avercos,
    acovercos, ahaversin, ahavercos, ahacovercos, aexsec,
    aexcsc, and acrd.

    Fixed a compile error in zmath.h that impacted legacy 32-bit Big
    Endian machines.  Thanks goes to GitHub user @gromit1811 for their
    pull request.

    Fixed the check for <sys/mount.h> when forming have_sys_mount.h.
    Thanks goes to GitHub user @gromit1811 for their pull request.

    Added "STATIC bool blum_initialized = false" to zrandom.c to improve
    how the code detects if the Blum-Blum-Shub pseudo-random number
    generator is seeded or not, and how to free the state correctly.

    NOTE: There is a very minor memory leak in zrandom.c that will be
    fixed in a later release.
2023-12-08 14:03:07 -08:00
Landon Curt Noll
8dd380a9f7 prep CHANGES for the next release of calc 2023-12-08 13:56:48 -08:00
Landon Curt Noll
fbaff69c92 improve how random seed state is determined
Added "STATIC bool blum_initialized = false" to zrandom.c to improve
how the code detects if the Blum-Blum-Shub pseudo-random number
generator is seeded or not, and how to free the state correctly.

NOTE: There is a very minor memory leak in zrandom.c that will be
fixed in a later release.
2023-12-08 13:51:14 -08:00
Landon Curt Noll
c724227ef9 thank GitHub user @gromit1811 for have_sys_mount.h fix 2023-11-02 17:25:51 -07:00
Landon Curt Noll
3fd64578a6 Merge pull request #132 from gromit1811/fix_have_sys_mount
Actually check for sys/mount.h when forming have_sys_mount.h
2023-11-02 17:24:25 -07:00
Martin Buck
c9c4105ddc Actually check for sys/mount.h when forming have_sys_mount.h
So far, the Makefile checked for sys/param.h instead and that suspiciously
looks like a copy & paste error.

Found by the Debian hurd-i386 build daemon because calc failed to compile
there and it seems to lack sys/mount.h. Not that this would be an extremely
relevant architecture these days, but nevertheless... ;-)
2023-11-02 21:43:10 +01:00
Landon Curt Noll
80b7cd34fe final tweak to the thanks in CHANGES .. promise :-)
We could collapse the last 3+ commits, but
then again why try to cover up the fun!  :-)
2023-11-01 16:17:59 -07:00
Landon Curt Noll
630947d35c improve thanks in CHANGES :-) 2023-11-01 16:15:15 -07:00
Landon Curt Noll
45f62fd7b4 fixed a typo in the previous commit :-) 2023-11-01 16:14:33 -07:00
Landon Curt Noll
8ca980b2bb Thank GitHub user @gromit1811 for zmath.h fix 2023-11-01 16:13:25 -07:00
Landon Curt Noll
2ace631d00 Merge branch 'master' of github.com:lcn2/calc 2023-11-01 16:05:56 -07:00
Landon Curt Noll
41d339c60e updated trigonometric function list in help/unexpected 2023-11-01 16:04:45 -07:00
Landon Curt Noll
cc3bb98fa0 Merge pull request #131 from gromit1811/fix-fposval-build-failure 2023-11-01 15:58:53 -07:00
Martin Buck
2b506a74e7 Fix file.c build failure on 32 bit big endian machines
On ancient 32 bit big endian machines (e.g. MIPS) file.c fails to build
when FILEPOS is a struct and not a scalar. This happens because the
SWAP_HALF_IN_FILEPOS macro essentially expands to a simple assignment in
this case but the types are incompatile (HALF and FILEPOS).

Detailed compile error (this is from an older version so line numbers might
be wrong but the error is the same):

gcc  -DCALC_SRC -DCUSTOM -Wall  -g -O2 -fstack-protector-strong -Wformat -Werror=format-security   -O3 -g3 -Wno-error=long-long -Wno-long-long -c file.c
In file included from qmath.h:32,
                 from cmath.h:32,
                 from value.h:33,
                 from calc.h:33,
                 from file.c:39:
file.c: In function 'filepos2z':
zmath.h:85:46: error: incompatible types when assigning to type 'HALF' {aka 'long unsigned int'} from type 'FILEPOS' {aka 'struct _G_fpos_t'}
 #define SWAP_HALF_IN_B32(dest, src) (*(dest) = *(src))
                                              ^
fposval.h:15:42: note: in expansion of macro 'SWAP_HALF_IN_B32'
 #define SWAP_HALF_IN_FILEPOS(dest, src)  SWAP_HALF_IN_B32(dest, src)
                                          ^~~~~~~~~~~~~~~~
file.c:1370:2: note: in expansion of macro 'SWAP_HALF_IN_FILEPOS'
  SWAP_HALF_IN_FILEPOS(ret.v, &pos);
  ^~~~~~~~~~~~~~~~~~~~

Fix this by adding suitable casts to the definition of SWAP_HALF_IN_FILEPOS
on big endian machines. Strictly speaking, the casts only seem to be
necessary when using SWAP_HALF_IN_B32, but they can't hurt in the other
cases either.
2023-11-01 21:30:43 +01:00
Landon Curt Noll
826d2d8175 Merge pull request #129 from gromit1811/man-wrap-long-paths 2023-10-17 15:53:14 -07:00
Landon Curt Noll
af8ffb3098 Merge pull request #128 from gromit1811/master 2023-10-17 15:11:31 -07:00
Martin Buck
71dd30c4c6 Allow word-wrapping in long path names in man page 2023-10-18 00:09:37 +02:00
Martin Buck
8ca96a8c29 Fix minor man page spelling errors 2023-10-17 23:41:02 +02:00
Landon Curt Noll
0bba80c92b Merge pull request #118 from planet36/help-typos
Fix minor typos in help docs
2023-10-10 07:08:34 -07:00
Steven Ward
c1882e2ea0 Use full name of function to match help file 2023-10-09 21:29:56 -04:00
Steven Ward
79964338d1 Fix minor typos 2023-10-09 21:29:47 -04:00
Steven Ward
d809ce5cf0 Use null() instead of nul() 2023-10-09 21:24:47 -04:00
Steven Ward
daac7b35af ctime() does not remove the trailing newline 2023-10-09 21:23:53 -04:00
Steven Ward
40d6e22318 s/windowz/Windows/ 2023-10-09 21:23:36 -04:00
Landon Curt Noll
ab2038ecbc fix more memory leaks
Fixed more memory leaks in the aversin, acoversin, avercos,
acovercos, ahaversin, ahavercos, ahacovercos, aexsec,
aexcsc, and acrd.
2023-10-06 23:54:55 -07:00
Landon Curt Noll
0b57d6b605 fix memory leak in the logn builtin function 2023-10-06 23:27:42 -07:00
Landon Curt Noll
01f0605055 improve chk_tree and trailblank
The chk_tree will check for files in distlist that
would otherwise be ignored by trailblank or that
are used, by convention, as tempory / test files.

Fixed a shellcheck nit in trailblank.
2023-10-06 22:25:00 -07:00
Landon Curt Noll
0e6016f429 improve Address Sanitizer (ASAN) support and chk_tree
Updated BUGS about MSYS2 on Windows compiling of calc.

    Added more git related checks and sanity checks to chk_tree.

    Added ${FSANITIZE} make variable to Makefile.config to hold
    common Address Sanitizer (ASAN) optins to modern Linux and macOS.
    The Address Sanitizer is NOT enabled not compiled in by default.
    Improved comments in Makefile.local for RHEL9.2 (Linux) and for
    macOS 14.0 that, when uncommented and calc is recompiled (i.e.,
    make clobber all) will enable the Address Sanitizer (ASAN) for calc.
2023-10-06 21:59:06 -07:00
Landon Curt Noll
2d2e1c5894 change make prep to report on chk_tree failures
Before, make prep would show but not object to chk_tree failures.
Now, if all except chk_tree is OK, make prep will report:

    almost satifactory except for chk_tree
2023-10-06 18:39:04 -07:00
Landon Curt Noll
50ba5f9a3e improve and update FSANITIZE comments in Makefile.local 2023-10-06 18:38:06 -07:00
Landon Curt Noll
850cdbef1d fix chk_tree ahead / behind direction 2023-10-06 18:05:59 -07:00
Landon Curt Noll
21cedfcae4 improve branch check for chk_tree 2023-10-06 18:04:05 -07:00
Landon Curt Noll
4fa137a638 update BUGS about MSYS2 and Windows success 2023-10-06 18:00:06 -07:00
Landon Curt Noll
6ebe707670 fix git branch checks 2023-10-06 17:55:12 -07:00
Landon Curt Noll
885db22315 add git branch checks to chk_tree 2023-10-06 17:52:30 -07:00
Landon Curt Noll
06a9997da7 fix git diff and improve git diff detection 2023-10-06 17:38:01 -07:00
Landon Curt Noll
fae4b8e81b add git checks for staged and unstaged changes 2023-10-06 17:31:37 -07:00
Landon Curt Noll
ddf0c8f1f5 fixed some warnings for errtbl.c on Cygwin systems 2023-10-05 05:02:05 -07:00
Landon Curt Noll
d52cbcea14 avoid issues where funclist.sed forms help/funclist.c
The funclist.sed sed script, when transforming func.c
into help/funclist.c, was creating nested comments.
While those were hardless, a single change to func.c
avoids the naive funclist.sed processing and avoids
(harmless) warnings when compiling help/funclist.c
in the course of building the function list.
2023-10-05 04:59:13 -07:00
Landon Curt Noll
d14d525a6a Release v2.15.0.1
The following are the changes in this release:

    The tarball for calc version 2.15.0.0 was missing version.h.
    The version.h is now listed as part of the calc distribution.

    Added the following new trigonometric functions:

	versin(x [,eps])	versed trigonometric sine
	coversin(x [,eps])	coversed trigonometric sine
	vercos(x [,eps])	versed trigonometric cosine
	covercos(x [,eps])	coversed trigonometric cosine
	aversin(x [,eps])	inverse versed trigonometric sine
	acoversin(x [,eps])	inverse coversed trigonometric sine
	avercos(x [,eps])	inverse versed trigonometric cosine
	acovercos(x [,eps])	inverse coversed trigonometric cosine
	haversin(x [,eps])	half versed trigonometric sine
	hacoversin(x [,eps])	half coversed trigonometric sine
	havercos(x [,eps])	half versed trigonometric cosine
	hacovercos(x [,eps])	half coversed trigonometric cosine
	ahaversin(x [,eps])	inverse half versed trigonometric sine
	ahacoversin(x [,eps])	inverse half coversed trigonometric sine
	ahavercos(x [,eps])	inverse half versed trigonometric cosine
	ahacovercos(x [,eps])	inverse half coversed trigonometric cosine
	exsec(x [,eps])		exterior trigonometric secant
	aexsec(x [,eps])	inverse exterior trigonometric secant
	excsc(x [,eps])		exterior trigonometric cosecant
	aexcsc(x [,eps])	inverse exterior trigonometric cosecant
	crd(x [,eps])		trigonometric chord of a unit circle
	acrd(x [,eps])		inverse trigonometric chord of a unit circle
	cas(x [,eps])		trigonometric cosine plus sine
	cis(x [,eps])		Euler's formula

    As Msys2 is a fork of Cygwin, if the OSNAME is Msys, the Cygwin
    target will be used.  Thanks to GitHub user @iahung2 for the
    pull request.

    Support for win32 and DJGPP has been dropped.  Calc version
    2.14.3.5 was the last to make references to win32 and make
    references to DJGPP.  Future versions of calc may work under
    those systems, we just elected to remove the somewhat out of
    date and awkward `win32.mkdef` and related win32 references.

    If you are a win32 user, please feel free to create a win32
    target in Makefile.target and submit as a pull request.
    If you are a DJGPP user, please feel free to create a DJGPP
    target in Makefile.target and submit as a pull request.
    Until someone can test such systems, we prefer to wait
    until someone is able to test and supply a pull request.

    Added PTR_LEN (length of a pointer) and PTR_BITS (bit length
    of a pointer) to longbits.h.

    Moved calc version definition from version.c to version.h.

    Sorted the order of symbols printed by "make env".

    Test if <stdbool.h> exists and set HAVE_STDBOOL_H accordingly
    in have_stdbool.h.  Added HAVE_STDBOOL_H to allow one to force
    this value.

    Added "bool.h" include file to support use of boolean symbols,
    true and false for pre-c99 C compilers.  The "bool.h" include
    file defines TRUE as true, FALSE as false, and BOOL as bool:
    for backward compatibility.

    Replaced in C source, TRUE with true, FALSE with false, and
    BOOL with bool.

    Fixed have_statfs optional executable file extension ${EXT{ in
    the ${UTIL_PROGS} make variable.

    Test if <stdint.h> exists and set HAVE_STDINT_H accordingly
    in have_stdint.h.  Added HAVE_STDINT_H to allow one to force
    this value.

    Test if <inttypes.h> exists and set HAVE_INTTYPES_H accordingly
    in have_inttypes.h.  Added HAVE_INTTYPES_H to allow one to force
    this value.

    Added c_chk.c to check the compiler and C include for calc
    requirements.  If you are unable to compile this program, or
    if this program when compiles does not exit 0, then your C
    compiler and/or C include fails to meet calc requirements.
    Compilers that are at least c99 MUST be able to compile this
    program such that when run will exit 0.

    The "make hsrc" file will attempt to compile and run c_chk and
    will warn if the C compiler and/or C include fails to meet
    calc requirements.  The "make debug" system will run c_chk -c
    to print information about the C compiler and C include.
    Currently failure to compile cc_chk.c or c_chk exiting non-0
    will just print "WARNING!!" strings to stderr.

    The make chk_c file also forms status.chk_c.h which either
    defines CHK_C when the C compiler and select include files
    appear to meet calc requirements, or undefines CHK_C
    when it does not.

    Added int.h as a central place for calc integer types and
    integer macros.

    Removed `-R release_file` and `-r release_file` command
    line options from `ver_calc`.  Add `-h` option.  Updated
    comments in "README.RELEASE", which serves as the contents
    of the calc command "help release".

    Added log2(x [,eps]) builtin function.  When x is an integer
    power of 2, log2(x) will return an integer, otherwise it will
    return the equivalent of ln(x)/ln(2).

    Removed CALC2_COMPAT in favor of ckecking if MAJOR_VER < 3.

    The sign element in a ZVALUE is now of type SIGN, which is either
    SB32 when MAJOR_VER < 3, or a bool otherwise.

    The len element in a ZVALUE is of type LEN.  LEN type is SB32 when
    MAJOR_VER < 3, or a uintptr_t otherwise.

    Setting an invalid epsilon via the epsilon(value) or confiv("epsilon",
    value) triggers an error.  The epsilon value must be: 0 < epsilon < 1.

    Added new logn(x, n [,eps]) builtin to compute logarithms to base n.

    Verify that eps arguments (error tolerance arguments that override
    the default epsilon value) to builtin functions have proper values.
    Previously the eps argument had little to no value checks for
    many builtin functions.

    Document in help files for builtin functions that take eps arguments,
    the LIMIT range for such eps values.

    Removed old Makefile testing rules for make dbx and make gdb.

    Improved "make run" to execute calccalc using shared libraries
    from the local directory, and with reading of the startup scripts
    disabled.

    Changed "make prep" to perform various tests that are used to
    help verify that calc is ready for a release.  Added the
    update_ver tool, (formerly verupdate) and the trailblank tool
    that existed outside of the calc source base but neverthless
    used in the calc release process.  Both of these tools are used
    by "make prep".

    Added Makefile testing rule "make testfuncsort" to check for
    the sort of the builtin function list.  Changed the order that
    builtin functions are listed by "show builtin" and the help/builtin
    to match the sorting of "LANG=C LC_ALL=C sort -d -u".

    Added c_to_q(COMPLEX *c, bool cfree) to make is easier to convert
    a COMPLEX value that is real (imag part is 0) into a NUMBER and
    optionally free the COMPLEX value.  The func.c code now uses c_to_q().

    Added q_to_c(NUMBER *q) to make it easier to convert a NUMBER
    into an allocated COMPLEX value.

    Added new vercos(x, [,eps]) for versed cosine and covercos(x, [,eps])
    for inverse versed cosine.

    Added new avercos(x, [,eps]) for inverse versed cosine and acovercos(x, [,eps])
    for inverse coversed cosine.

    Improved comments about use of the ${CALC_ENV} Makefile variable.
    Noted in Makefile.cal where and how the ${CALC_ENV} is used.
    Use ${CALC_ENV} Makefile variable were needed.

    Modified regression test cal/regress.cal: in some cases test numbers
    were adjusted.  Add comments indicate which test numbers apply to
    which code.  Indicated where there is room for new tests.
    Expanded the end of test numbers from 9999 to  99999.

    To make the meaning a bit more clear in cal/regress.cal, we have
    renamed the following test calc resource files that are related to
    the calc regression test suite:

	cal/test1700.cal -> cal/test8000.read.cal
	cal/test2300.cal -> cal/test2300.obj_incdec.cal
	cal/test2600.cal -> cal/test2600.numfunc.cal
	cal/test2700.cal -> cal/test2700.isqrt.cal
	cal/test3100.cal -> cal/test3100.matobj.cal
	cal/test3400.cal -> cal/test3400.trig.cal
	cal/test4000.cal -> cal/test4000.ptest.cal
	cal/test4100.cal -> cal/test4100.redc.cal
	cal/test4600.cal -> cal/test4600.fileop.cal
	cal/test5100.cal -> cal/test5100.newdecl.cal
	cal/test5200.cal -> cal/test5200.globstat.cal
	cal/test8400.cal -> cal/test8400.quit.cal
	cal/test8500.cal -> cal/test8500.divmod.cal
	cal/test8600.cal -> cal/test8600.maxargs.cal
	cal/set8700.cal -> cal/test8700.dotest.cal
	cal/test8900.cal -> cal/test8900.special.cal
	cal/test9300.cal -> cal/test9300.frem.cal

    Added to test 94dd, read of a number of new calc resource files
    that are not already read as a result of the calc regression test suite.

    Fixed more documentation and code comments that referred to the
    old additive 55 (a55) shuffle pseudo-random number generator.
    We have been using the subtractive 100 shuffle pseudo-random
    number generator in place of the additive 55 generator for a
    while now.

    Improved help files trigonometric functions.  They were corrected
    to indicate that complex arguments are allowed: an oversight
    from long ago when those trigonometric functions were expanded
    to include complex arguments.  The EXAMPLE sections were expanded
    and made consistent, where applicable, across the trigonometric
    help files.  Documented libcalc functions in the SEE ALSO sections.

    Improved "SEE ALSO" for the hyperbolic function help files.

    Expanded the calc regression test suite test 34dd to test various
    real and complex values for trigonometric functions.

    Added complex multiple approximation function to commath.c so
    that users of libcalc may directly round complex number to
    nearest multiple of a given real number:

	E_FUNC COMPLEX *cmappr(COMPLEX *c, NUMBER *e, long rnd, bool cfree);

    For example:

	COMPLEX *c;             /* complex number to round to nearest epsilon */
	NUMBER *eps;            /* epsilon rounding precision */
	COMPLEX *res;           /* c rounded to nearest epsilon */
	long rnd = 24L;         /* a common rounding mode */
	bool ok_to_free;        /* true ==> free c, false ==> do not free c */

	...

	res = cmappr(c, eps, ok_to_free);

    The complex trigonometric functions tan, cot, sec, csc were
    implemented in func.c as calls to complex sin and complex cos.
    We added the following direct calls to comfunc.c so that users
    of libcalc may call them directly:

	E_FUNC COMPLEX *c_tan(COMPLEX *c, NUMBER *eps);
	E_FUNC COMPLEX *c_cot(COMPLEX *c, NUMBER *eps);
	E_FUNC COMPLEX *c_sec(COMPLEX *c, NUMBER *eps);
	E_FUNC COMPLEX *c_cot(COMPLEX *c, NUMBER *eps);

    Added help/errorcodes rule to the top level Makefile.

    Added E_USERMAX symbol (== 32767) to indicate the maximum value
    allowed for user error codes.

    Improved help/error.  Added text about error code ranges and
    range symbols.

    Changed calc_errno a global int variable so that is may be directly
    accessed by libcalc users.

    Further improve help files for help/errno, help/error, help/newerror,
    help/stoponerror and help/strerror by adding to documentation
    of the calc error code system as well as libcalc interface
    where applicable.

    Changed #define E_USERDEF to #define E__USERDEF.

    Removed use of E_USERDEF, E__BASE, E__COUNT, and E__HIGHEST
    from custom/c_sysinfo because the c_sysinfo is just a demo
    and this will simplify the custom/Makefile.

    The include file calcerr.h is now the errsym.h include file.
    The calcerr.tbl has been replaced by errtbl.c and errtbl.h.

    The calcerr_c.awk, calcerr_c.sed, calcerr_h.awk, and
    calcerr_h.sed files are now obsolete and have been removed.
    The calcerr.c and calcerr.h now obsolete and are no longer built.

    The calc computation error codes, symbols and messages are now in
    a error_table[] array of struct errtbl.

    An E_STRING is a string corresponds to an error code #define.
    For example, the E_STRING for the calc error E_STRCAT,
    is the string "E_STRING".  An E_STRING must now match
    the regular expression: "^E_[A-Z0-9_]+$".

    The old array error_table[] of error message strings has been
    replaced by a new error_table[] array of struct errtbl.  The struct
    errtbl array holds calc errnum error codes, the related E_STRING
    symbol as a string, and the original related error message.
    To add new computation error codes, add them near the bottom of the
    error_table[] array, just before the NULL entry.

    The ./errcode utility, when run, will verify the consistency of
    the error_table[] array.

    The Makefile uses ./errcode -e to generate the contents of
    help/errorcodes file.  The help errorcodes now prints
    information from the new cstruct errtbl error_table[] array.

    The help/errorcodes.hdr and help/errorcodes.sed files are
    now obsolete and have been removed.

    The Makefile uses ./errcode -d to generate the contents of the
    errsym.h include file.

    Code that used the old array error_table[] of error message strings
    such as:

	#include "calcerr.h"

	char *msg;	/* calc computation error message */

	msg = error_table[errnum - E__BASE];

    where errnum is the calc computation error code
    E__BASE <= errnum <= E__HIGHEST, may now use:

	#include "errtbl.h"
	#include "errsym.h"

	char *msg;	/* calc computation error message */

	msg = error_table[errnum - E__BASE].errmsg;

    Rename the #define E__COUNT to ECOUNT to avoid confusion
    with "E_STRING" error symbols.

    Renamed "E_1OVER0" to "E_DIVBYZERO".
    Renamed "E_0OVER0" to "E_ZERODIVZERO".

    The verify_error_table() function that does a verification
    the error_table[] array and setup private_error_alias[] array
    is now called by libcalc_call_me_first().

    Fix comment about wrong include file in have_sys_mount.h.

    Removed unused booltostr() and strtobool() macros from bool.h.

    Moved define of math_error(char *, ...) from zmath.h to errtbl.h.
    The errtbl.h include file, unless ERRCODE_SRC is defined
    also includes attribute.h and errsym.h.

    Added E_STRING to error([errnum | "E_STRING"]) builtin function.
    Added E_STRING to errno([errnum | "E_STRING"]) builtin function.
    Added E_STRING to strerror([errnum | "E_STRING"]) builtin function.
    Calling these functions with an E_STRING errsym is the same as calling
    them with the matching errnum code.

    Standardized on calc computation error related E_STRING strings
    where there are a set of related codes.  Changed "E_...digits" into
    "E_..._digits".  For example, E_FPUTC1 became E_FPUTC_1, E_FPUTC2
    became E_FPUTC_2, and E_FPUTC3 became E_FPUTC_3.  In a few cases
    such as E_APPR became E_APPR_1, because there was a E_APPR2 (which
    became E_APPR_2) and E_APPR3 (which became E_APPR_3).  To other
    special cases, E_ILOG10 became E_IBASE10_LOG and E_ILOG2 became
    E_IBASE2_LOG because E_ILOG10 and E_ILOG2 are both independent calc
    computation error related E_STRING strings.  Now related sets of
    E_STRING strings end in _ (underscore) followed by digits.

    Added errsym builtin function.  The errsym(errnum | "E_STRING")
    builtin, , when given a valid integer errnum that corresponds to a
    calc error condition, will return an E_STRING string, AND when given
    a valid E_STRING string that is associated with a calc error
    condition, will return errnum integer that corresponds to a calc
    error condition.

    Supplying a non-integer numeric errnum code to error(), errno(),
    strerror(), or errsym() will result in an error.

    Added tests to the calc regression test suite (cal/regress.cal) to
    verify that the errnum calc computation error codes and their
    E_STRING values have not changed.

    Improved the clarity of calc regression suite (regress.cal) to mostly
    use E_STRING errsym instead of numeric errnum values for error()
    and errno() related tests.

    Fixed SEE ALSO typo in help randperm.

    Fixed calc regression test 42dd to set the display value back to 20.

    Added to test 95dd and test9500.trigeq.cal to the calc regression test
    suite to perform extensive test of trigonometric functions.

    Added to test 34dd, some if the missing inverse trigonometric tests.

    Improved builtin function strings, as printed by help builtin,
    that use an optional accuracy (epsilon) arg by adding a comma.

The following are the changes from calc version 2.14.3.4 to 2.14.3.5:

    Under macOS, to reduce dependency chains, we remove functions
    and data that are unreachable by the entry point or exported
    symbols.  In particular, the macOS linker is used with both
    "-dead_strip" and "-dead_strip_dylibs".

    The libcalc shared library is now linked with libcustcalc.

    The config("triground") controls rounding for the following
    trigonometric and hyperbolic functions:

	sin, cos, tan, cot, sec, csc
	asin, acos, atan, acot, asec, acsc
	versin, coversin, vercos, covercos
	aversin, acoversin, avercos, acovercos
	haversin, hacoversin, havercos, hacovercos
	ahaversin, hacoversin, havercos, ahacovercos
	exsec, aexsec, excsc, aexcsc
	crd, acrd
	cas, cis
	sinh, cosh, tanh, coth, sech, csch
	asinh, acosh, atanh, acoth, asech, acsch

    In addition to taking a complex root (such as via the power
    function on a complex value), "triground" is used for:

	exp, polar

    For the above mentioned functions, the rounding mode used to
    round the result to the nearest epsilon value is controlled by,
    and defaults to:

	config("triground", 24)

    As with other config options, the call returns the previous mode,
    without a 2nd argument, returns the current mode without changing it:

	config("triground")

    When printing an error, calc used to print the errnum (error number):

	; 1/0
		Error 10001

    Calc now prints the errsym (errsym):

	; 1/0
		Error E_DIVBYZERO

    Added errsym E_LN_3 for ln(0).
    Added errsym E_LOG_5 for log(0).
    Added errsym E_LOG2_4 for log2(0).
    Added errsym E_LOGN_6 for logn(0,base).

    Added a chk_tree tool to help look for problems such as files that are
    result of building calc that are also part of the calc distribution,
    and files that are part of the calc source that are missing from the
    calc distribution, and files that are of unknown status that are either
    result of building calc nor missing from the calc distribution.

    Updated file lists in Makefile, sorting as needed.

    Updated Makefile PHONY rule to include Makefile rules that are NOT files.

    Reduced make chatter for rules that build lists.

    Added make verifydist to verify the existence of files that are part of
    the calc distribution.

    Added make verifydist to make prep.

    Added a chk_tree double check, one after make clobber, one before
    the final make chk, to make prep.  Added double pass of chk_tree to
    make full_debug (and thus to the make debug output).

    Improved notes for install locations in Makefile.config.

    Added printing of ${BUILD_ALL} to make env output.
2023-10-05 04:37:59 -07:00
Landon Curt Noll
698f73cd3e prep CHANGES for the next release of calc 2023-10-05 04:34:22 -07:00
Landon Curt Noll
e1888d9b9e note recent chk_tree changes in CHANGES 2023-10-05 04:33:30 -07:00
Landon Curt Noll
b54f68a797 Add comments to Makefile.local
Added comments to Makefile.local about how to force calc to install
under /usr/local.
2023-10-05 03:42:26 -07:00
Landon Curt Noll
77d7e665e0 Improve Makefile comments and tests
Improved notes for install locations in Makefile.config.

Added printing of ${BUILD_ALL} to make env output.

Added double pass of chk_tree to make full_debug (and thus to the make
debug output).
2023-10-05 03:27:14 -07:00
Landon Curt Noll
e96ef61718 fix missing version.h, add chk_tree tool
The tarball for calc version 2.15.0.0 was missing version.h.
The version.h is now listed as part of the calc distribution.

Added a chk_tree tool to help look for problems such as files that are
result of building calc that are also part of the calc distribution,
and files that are part of the calc source that are missing from the
calc distribution, and files that are of unknown status that are either
result of building calc nor missing from the calc distribution.

Updated file lists in Makefile, sorting as needed.

Updated Makefile PHONY rule to include Makefile rules that are NOT files.

Reduced make chatter for rules that build lists.

Added make verifydist to verify the existence of files that are part of
the calc distribution.

Added make verifydist to make prep.

Added a chk_tree double check, one after make clobber, one before the
final make chk, to make prep.
2023-10-05 02:50:45 -07:00
Landon Curt Noll
0eee1a615d add calc version regex on update_ver 2023-10-03 23:45:38 -07:00
Landon Curt Noll
d2025c5f24 fix make ver_calc in Makefile 2023-10-03 23:03:19 -07:00
Landon Curt Noll
801dad8f57 fix make clobber for cal/Makefile 2023-10-03 23:00:44 -07:00
Landon Curt Noll
5a227873e5 Release v2.15.0.0
The following are the changes in this release:

    Added the following new trigonometric functions:

	versin(x [,eps])	versed trigonometric sine
	coversin(x [,eps])	coversed trigonometric sine
	vercos(x [,eps])	versed trigonometric cosine
	covercos(x [,eps])	coversed trigonometric cosine
	aversin(x [,eps])	inverse versed trigonometric sine
	acoversin(x [,eps])	inverse coversed trigonometric sine
	avercos(x [,eps])	inverse versed trigonometric cosine
	acovercos(x [,eps])	inverse coversed trigonometric cosine
	haversin(x [,eps])	half versed trigonometric sine
	hacoversin(x [,eps])	half coversed trigonometric sine
	havercos(x [,eps])	half versed trigonometric cosine
	hacovercos(x [,eps])	half coversed trigonometric cosine
	ahaversin(x [,eps])	inverse half versed trigonometric sine
	ahacoversin(x [,eps])	inverse half coversed trigonometric sine
	ahavercos(x [,eps])	inverse half versed trigonometric cosine
	ahacovercos(x [,eps])	inverse half coversed trigonometric cosine
	exsec(x [,eps])		exterior trigonometric secant
	aexsec(x [,eps])	inverse exterior trigonometric secant
	excsc(x [,eps])		exterior trigonometric cosecant
	aexcsc(x [,eps])	inverse exterior trigonometric cosecant
	crd(x [,eps])		trigonometric chord of a unit circle
	acrd(x [,eps])		inverse trigonometric chord of a unit circle
	cas(x [,eps])		trigonometric cosine plus sine
	cis(x [,eps])		Euler's formula

    As Msys2 is a fork of Cygwin, if the OSNAME is Msys, the Cygwin
    target will be used.  Thanks to GitHub user @iahung2 for the
    pull request.

    Support for win32 and DJGPP has been dropped.  Calc version
    2.14.3.5 was the last to make references to win32 and make
    references to DJGPP.  Future versions of calc may work under
    those systems, we just elected to remove the somewhat out of
    date and awkward `win32.mkdef` and related win32 references.

    If you are a win32 user, please feel free to create a win32
    target in Makefile.target and submit as a pull request.
    If you are a DJGPP user, please feel free to create a DJGPP
    target in Makefile.target and submit as a pull request.
    Until someone can test such systems, we prefer to wait
    until someone is able to test and supply a pull request.

    Added PTR_LEN (length of a pointer) and PTR_BITS (bit length
    of a pointer) to longbits.h.

    Moved calc version definition from version.c to version.h.

    Sorted the order of symbols printed by "make env".

    Test if <stdbool.h> exists and set HAVE_STDBOOL_H accordingly
    in have_stdbool.h.  Added HAVE_STDBOOL_H to allow one to force
    this value.

    Added "bool.h" include file to support use of boolean symbols,
    true and false for pre-c99 C compilers.  The "bool.h" include
    file defines TRUE as true, FALSE as false, and BOOL as bool:
    for backward compatibility.

    Replaced in C source, TRUE with true, FALSE with false, and
    BOOL with bool.

    Fixed have_statfs optional executable file extension ${EXT{ in
    the ${UTIL_PROGS} make variable.

    Test if <stdint.h> exists and set HAVE_STDINT_H accordingly
    in have_stdint.h.  Added HAVE_STDINT_H to allow one to force
    this value.

    Test if <inttypes.h> exists and set HAVE_INTTYPES_H accordingly
    in have_inttypes.h.  Added HAVE_INTTYPES_H to allow one to force
    this value.

    Added c_chk.c to check the compiler and C include for calc
    requirements.  If you are unable to compile this program, or
    if this program when compiles does not exit 0, then your C
    compiler and/or C include fails to meet calc requirements.
    Compilers that are at least c99 MUST be able to compile this
    program such that when run will exit 0.

    The "make hsrc" file will attempt to compile and run c_chk and
    will warn if the C compiler and/or C include fails to meet
    calc requirements.  The "make debug" system will run c_chk -c
    to print information about the C compiler and C include.
    Currently failure to compile cc_chk.c or c_chk exiting non-0
    will just print "WARNING!!" strings to stderr.

    The make chk_c file also forms status.chk_c.h which either
    defines CHK_C when the C compiler and select include files
    appear to meet calc requirements, or undefines CHK_C
    when it does not.

    Added int.h as a central place for calc integer types and
    integer macros.

    Removed `-R release_file` and `-r release_file` command
    line options from `ver_calc`.  Add `-h` option.  Updated
    comments in "README.RELEASE", which serves as the contents
    of the calc command "help release".

    Added log2(x [,eps]) builtin function.  When x is an integer
    power of 2, log2(x) will return an integer, otherwise it will
    return the equivalent of ln(x)/ln(2).

    Removed CALC2_COMPAT in favor of ckecking if MAJOR_VER < 3.

    The sign element in a ZVALUE is now of type SIGN, which is either
    SB32 when MAJOR_VER < 3, or a bool otherwise.

    The len element in a ZVALUE is of type LEN.  LEN type is SB32 when
    MAJOR_VER < 3, or a uintptr_t otherwise.

    Setting an invalid epsilon via the epsilon(value) or confiv("epsilon",
    value) triggers an error.  The epsilon value must be: 0 < epsilon < 1.

    Added new logn(x, n [,eps]) builtin to compute logarithms to base n.

    Verify that eps arguments (error tolerance arguments that override
    the default epsilon value) to builtin functions have proper values.
    Previously the eps argument had little to no value checks for
    many builtin functions.

    Document in help files for builtin functions that take eps arguments,
    the LIMIT range for such eps values.

    Removed old Makefile testing rules for make dbx and make gdb.

    Improved "make run" to execute calccalc using shared libraries
    from the local directory, and with reading of the startup scripts
    disabled.

    Changed "make prep" to perform various tests that are used to
    help verify that calc is ready for a release.  Added the
    update_ver tool, (formerly verupdate) and the trailblank tool
    that existed outside of the calc source base but neverthless
    used in the calc release process.  Both of these tools are used
    by "make prep".

    Added Makefile testing rule "make testfuncsort" to check for
    the sort of the builtin function list.  Changed the order that
    builtin functions are listed by "show builtin" and the help/builtin
    to match the sorting of "LANG=C LC_ALL=C sort -d -u".

    Added c_to_q(COMPLEX *c, bool cfree) to make is easier to convert
    a COMPLEX value that is real (imag part is 0) into a NUMBER and
    optionally free the COMPLEX value.  The func.c code now uses c_to_q().

    Added q_to_c(NUMBER *q) to make it easier to convert a NUMBER
    into an allocated COMPLEX value.

    Added new vercos(x, [,eps]) for versed cosine and covercos(x, [,eps])
    for inverse versed cosine.

    Added new avercos(x, [,eps]) for inverse versed cosine and acovercos(x, [,eps])
    for inverse coversed cosine.

    Improved comments about use of the ${CALC_ENV} Makefile variable.
    Noted in Makefile.cal where and how the ${CALC_ENV} is used.
    Use ${CALC_ENV} Makefile variable were needed.

    Modified regression test cal/regress.cal: in some cases test numbers
    were adjusted.  Add comments indicate which test numbers apply to
    which code.  Indicated where there is room for new tests.
    Expanded the end of test numbers from 9999 to  99999.

    To make the meaning a bit more clear in cal/regress.cal, we have
    renamed the following test calc resource files that are related to
    the calc regression test suite:

	cal/test1700.cal -> cal/test8000.read.cal
	cal/test2300.cal -> cal/test2300.obj_incdec.cal
	cal/test2600.cal -> cal/test2600.numfunc.cal
	cal/test2700.cal -> cal/test2700.isqrt.cal
	cal/test3100.cal -> cal/test3100.matobj.cal
	cal/test3400.cal -> cal/test3400.trig.cal
	cal/test4000.cal -> cal/test4000.ptest.cal
	cal/test4100.cal -> cal/test4100.redc.cal
	cal/test4600.cal -> cal/test4600.fileop.cal
	cal/test5100.cal -> cal/test5100.newdecl.cal
	cal/test5200.cal -> cal/test5200.globstat.cal
	cal/test8400.cal -> cal/test8400.quit.cal
	cal/test8500.cal -> cal/test8500.divmod.cal
	cal/test8600.cal -> cal/test8600.maxargs.cal
	cal/set8700.cal -> cal/test8700.dotest.cal
	cal/test8900.cal -> cal/test8900.special.cal
	cal/test9300.cal -> cal/test9300.frem.cal

    Added to test 94dd, read of a number of new calc resource files
    that are not already read as a result of the calc regression test suite.

    Fixed more documentation and code comments that referred to the
    old additive 55 (a55) shuffle pseudo-random number generator.
    We have been using the subtractive 100 shuffle pseudo-random
    number generator in place of the additive 55 generator for a
    while now.

    Improved help files trigonometric functions.  They were corrected
    to indicate that complex arguments are allowed: an oversight
    from long ago when those trigonometric functions were expanded
    to include complex arguments.  The EXAMPLE sections were expanded
    and made consistent, where applicable, across the trigonometric
    help files.  Documented libcalc functions in the SEE ALSO sections.

    Improved "SEE ALSO" for the hyperbolic function help files.

    Expanded the calc regression test suite test 34dd to test various
    real and complex values for trigonometric functions.

    Added complex multiple approximation function to commath.c so
    that users of libcalc may directly round complex number to
    nearest multiple of a given real number:

	E_FUNC COMPLEX *cmappr(COMPLEX *c, NUMBER *e, long rnd, bool cfree);

    For example:

	COMPLEX *c;             /* complex number to round to nearest epsilon */
	NUMBER *eps;            /* epsilon rounding precision */
	COMPLEX *res;           /* c rounded to nearest epsilon */
	long rnd = 24L;         /* a common rounding mode */
	bool ok_to_free;        /* true ==> free c, false ==> do not free c */

	...

	res = cmappr(c, eps, ok_to_free);

    The complex trigonometric functions tan, cot, sec, csc were
    implemented in func.c as calls to complex sin and complex cos.
    We added the following direct calls to comfunc.c so that users
    of libcalc may call them directly:

	E_FUNC COMPLEX *c_tan(COMPLEX *c, NUMBER *eps);
	E_FUNC COMPLEX *c_cot(COMPLEX *c, NUMBER *eps);
	E_FUNC COMPLEX *c_sec(COMPLEX *c, NUMBER *eps);
	E_FUNC COMPLEX *c_cot(COMPLEX *c, NUMBER *eps);

    Added help/errorcodes rule to the top level Makefile.

    Added E_USERMAX symbol (== 32767) to indicate the maximum value
    allowed for user error codes.

    Improved help/error.  Added text about error code ranges and
    range symbols.

    Changed calc_errno a global int variable so that is may be directly
    accessed by libcalc users.

    Further improve help files for help/errno, help/error, help/newerror,
    help/stoponerror and help/strerror by adding to documentation
    of the calc error code system as well as libcalc interface
    where applicable.

    Changed #define E_USERDEF to #define E__USERDEF.

    Removed use of E_USERDEF, E__BASE, E__COUNT, and E__HIGHEST
    from custom/c_sysinfo because the c_sysinfo is just a demo
    and this will simplify the custom/Makefile.

    The include file calcerr.h is now the errsym.h include file.
    The calcerr.tbl has been replaced by errtbl.c and errtbl.h.

    The calcerr_c.awk, calcerr_c.sed, calcerr_h.awk, and
    calcerr_h.sed files are now obsolete and have been removed.
    The calcerr.c and calcerr.h now obsolete and are no longer built.

    The calc computation error codes, symbols and messages are now in
    a error_table[] array of struct errtbl.

    An E_STRING is a string corresponds to an error code #define.
    For example, the E_STRING for the calc error E_STRCAT,
    is the string "E_STRING".  An E_STRING must now match
    the regular expression: "^E_[A-Z0-9_]+$".

    The old array error_table[] of error message strings has been
    replaced by a new error_table[] array of struct errtbl.  The struct
    errtbl array holds calc errnum error codes, the related E_STRING
    symbol as a string, and the original related error message.
    To add new computation error codes, add them near the bottom of the
    error_table[] array, just before the NULL entry.

    The ./errcode utility, when run, will verify the consistency of
    the error_table[] array.

    The Makefile uses ./errcode -e to generate the contents of
    help/errorcodes file.  The help errorcodes now prints
    information from the new cstruct errtbl error_table[] array.

    The help/errorcodes.hdr and help/errorcodes.sed files are
    now obsolete and have been removed.

    The Makefile uses ./errcode -d to generate the contents of the
    errsym.h include file.

    Code that used the old array error_table[] of error message strings
    such as:

	#include "calcerr.h"

	char *msg;	/* calc computation error message */

	msg = error_table[errnum - E__BASE];

    where errnum is the calc computation error code
    E__BASE <= errnum <= E__HIGHEST, may now use:

	#include "errtbl.h"
	#include "errsym.h"

	char *msg;	/* calc computation error message */

	msg = error_table[errnum - E__BASE].errmsg;

    Rename the #define E__COUNT to ECOUNT to avoid confusion
    with "E_STRING" error symbols.

    Renamed "E_1OVER0" to "E_DIVBYZERO".
    Renamed "E_0OVER0" to "E_ZERODIVZERO".

    The verify_error_table() function that does a verification
    the error_table[] array and setup private_error_alias[] array
    is now called by libcalc_call_me_first().

    Fix comment about wrong include file in have_sys_mount.h.

    Removed unused booltostr() and strtobool() macros from bool.h.

    Moved define of math_error(char *, ...) from zmath.h to errtbl.h.
    The errtbl.h include file, unless ERRCODE_SRC is defined
    also includes attribute.h and errsym.h.

    Added E_STRING to error([errnum | "E_STRING"]) builtin function.
    Added E_STRING to errno([errnum | "E_STRING"]) builtin function.
    Added E_STRING to strerror([errnum | "E_STRING"]) builtin function.
    Calling these functions with an E_STRING errsym is the same as calling
    them with the matching errnum code.

    Standardized on calc computation error related E_STRING strings
    where there are a set of related codes.  Changed "E_...digits" into
    "E_..._digits".  For example, E_FPUTC1 became E_FPUTC_1, E_FPUTC2
    became E_FPUTC_2, and E_FPUTC3 became E_FPUTC_3.  In a few cases
    such as E_APPR became E_APPR_1, because there was a E_APPR2 (which
    became E_APPR_2) and E_APPR3 (which became E_APPR_3).  To other
    special cases, E_ILOG10 became E_IBASE10_LOG and E_ILOG2 became
    E_IBASE2_LOG because E_ILOG10 and E_ILOG2 are both independent calc
    computation error related E_STRING strings.  Now related sets of
    E_STRING strings end in _ (underscore) followed by digits.

    Added errsym builtin function.  The errsym(errnum | "E_STRING")
    builtin, , when given a valid integer errnum that corresponds to a
    calc error condition, will return an E_STRING string, AND when given
    a valid E_STRING string that is associated with a calc error
    condition, will return errnum integer that corresponds to a calc
    error condition.

    Supplying a non-integer numeric errnum code to error(), errno(),
    strerror(), or errsym() will result in an error.

    Added tests to the calc regression test suite (cal/regress.cal) to
    verify that the errnum calc computation error codes and their
    E_STRING values have not changed.

    Improved the clarity of calc regression suite (regress.cal) to mostly
    use E_STRING errsym instead of numeric errnum values for error()
    and errno() related tests.

    Fixed SEE ALSO typo in help randperm.

    Fixed calc regression test 42dd to set the display value back to 20.

    Added to test 95dd and test9500.trigeq.cal to the calc regression test
    suite to perform extensive test of trigonometric functions.

    Added to test 34dd, some if the missing inverse trigonometric tests.

    Improved builtin function strings, as printed by help builtin,
    that use an optional accuracy (epsilon) arg by adding a comma.
2023-10-03 22:39:35 -07:00
Landon Curt Noll
915054391e changed a few CHANGES notes to use changed instead of change 2023-10-03 22:28:42 -07:00
Landon Curt Noll
4b7ba942ee prep CHANGES for the next release of calc 2023-10-03 22:25:23 -07:00
Landon Curt Noll
42129a3672 change error printing from errnum to errsym
When printing an error, calc used to print the errnum (error number):

    ; 1/0
	    Error 10001

Calc now prints the errsym (errsym):

    ; 1/0
	    Error E_DIVBYZERO

Added errsym E_LN_3 for ln(0).
Added errsym E_LOG_5 for log(0).
Added errsym E_LOG2_4 for log2(0).
Added errsym E_LOGN_6 for logn(0,base).
2023-10-03 22:12:14 -07:00
Landon Curt Noll
db582d6e34 add config("triground") to trigonometric function rounding
The config("triground") controls rounding for the following
trigonometric and hyperbolic functions:

    sin, cos, tan, cot, sec, csc
    asin, acos, atan, acot, asec, acsc
    versin, coversin, vercos, covercos
    aversin, acoversin, avercos, acovercos
    haversin, hacoversin, havercos, hacovercos
    ahaversin, hacoversin, havercos, ahacovercos
    exsec, aexsec, excsc, aexcsc
    crd, acrd
    cas, cis
    sinh, cosh, tanh, coth, sech, csch
    asinh, acosh, atanh, acoth, asech, acsch

In addition to taking a complex root (such as via the power
function on a complex value), "triground" is used for:

    exp, polar

For the above mentioned functions, the rounding mode used to
round the result to the nearest epsilon value is controlled by,
and defaults to:

    config("triground", 24)

As with other config options, the call returns the previous mode,
without a 2nd argument, returns the current mode without changing it:

    config("triground")

Improved "SEE ALSO" for the hyperbolic function help files.
2023-10-03 20:31:13 -07:00
Landon Curt Noll
fec9712b9a improve half trig help file equivalent to lines 2023-10-03 02:10:45 -07:00
Landon Curt Noll
68e1914ee7 document in LIBRARY, q_to_c() that was previously added
Added q_to_c(NUMBER *q) to make it easier to convert a NUMBER
into an allocated COMPLEX value.
2023-10-03 01:59:00 -07:00
Landon Curt Noll
2c4abcd2b7 add cas and cis trigonometric functions
Added the following new trigonometric functions:

    cas(x [,eps])		trigonometric cosine plus sine
    cis(x [,eps])		Euler's formula
2023-10-03 01:41:42 -07:00
Landon Curt Noll
26fc394089 add trigonometric chord of a unit circle functions
Improve builtin function strings, as printed by help builtin,
that use an optional accuracy (epsilon) arg by adding a comma.

Added the following new trigonometric functions:

    crd(x [,eps])		trigonometric chord of a unit circle
    acrd(x [,eps])		inverse trigonometric chord of a unit circle
2023-10-02 22:43:33 -07:00
Landon Curt Noll
c78a893862 add exterior trigonometric functions
Added the following new trigonometric functions:

    exsec(x [,eps])		exterior trigonometric secant
    aexsec(x [,eps])		inverse exterior trigonometric secant
    excsc(x [,eps])		exterior trigonometric cosecant
    aexcsc(x [,eps])		inverse exterior trigonometric cosecant

Added to test 95dd and test9500.trigeq.cal to the calc regression test
suite to perform extensive test of trigonometric functions.

Added to test 34dd, some if the missing inverse trigonometric tests.
2023-10-01 23:12:21 -07:00
Landon Curt Noll
5d62e58704 add half trigonometric functions
Fixed SEE ALSO typo in help randperm.

Added the following new trigonometric functions:

    haversin(x [,eps])		half versed trigonometric sine
    hacoversin(x [,eps])	half coversed trigonometric sine
    havercos(x [,eps])		half versed trigonometric cosine
    hacovercos(x [,eps])	half coversed trigonometric cosine
    ahaversin(x [,eps])		inverse half versed trigonometric sine
    ahacoversin(x [,eps])	inverse half coversed trigonometric sine
    ahavercos(x [,eps])		inverse half versed trigonometric cosine
    ahacovercos(x [,eps])	inverse half coversed trigonometric cosine

Fixed calc regression test 42dd to set the display value back to 20.

Added test 95dd and test9500.trigeq.cal to the calc regression test
suite to perform extensive test of trigonometric functions.

Fix and improve recently comments and variable names added new
trigonometric functions in comfunc.c, func.c, qtrans.c.
2023-09-28 23:46:53 -07:00
Landon Curt Noll
ab95e47c0a fix and improve trigonometric help files
The trigonometric file files have had several bug fixed.

The EXAMPLE sections of trigonometric file have
been made consistent.

Added these new help files in anticipation of
the code for these new (i.e., to be written) builtin functions:

    hacovercos hacoversin havercos haversin
    ahacovercos ahacoversin ahavercos ahaversin
2023-09-24 12:52:14 -07:00
Landon Curt Noll
db80afb843 expand on error testing in calc regression suite
Rename E_BROUND to E_BROUND_1 as per an earlier change
on the E_STRING formats.

    E_BROUND ==> E_BROUND_1

Improve the ciarify of calc regression suite (regress.cal) to mostly
use E_STRING errsym instead of numeric errnum values for error()
and errno() related tests.
2023-09-21 12:35:50 -07:00
Landon Curt Noll
70a8225c0b restore error return for invalid args in error(), errno(), strerror(), errsym()
Passing an invalid argument to error(), errno() or strerror() will
again return an error value.
2023-09-20 23:26:46 -07:00
Landon Curt Noll
5fbb0ad2ea add test 10ddd to verify E_STRING values for calc computation error codes
Added tests to the calc regression test suite (cal/regress.cal) to
verify that the errnum calc computation error codes and their
E_STRING values have not changed.
2023-09-20 23:10:32 -07:00
Landon Curt Noll
b741e98b13 restore optimized compiling of calc
We forgot to disable debug mode after
our debugging session was over.
Sorry (tm Canada :-))!
2023-09-20 22:39:11 -07:00
Landon Curt Noll
066bb78f0e fix error detection in logn 2023-09-20 22:37:31 -07:00
Landon Curt Noll
1a898caf3f add errsym builtin function
NOTE: errstr was renamed to errsym.

Added errsym builtin function.  The errsym(errnum | "E_STRING")
builtin, , when given a valid integer errnum that corresponds to a
calc error condition, will return an E_STRING string, AND when given
a valid E_STRING string that is associated with a calc error
condition, will return errnum integer that corresponds to a calc
error condition.

Supplying a non-integer numeric errnum code to error(), errno(),
strerror(), or errsym() will result in an error.
2023-09-20 22:22:49 -07:00
Landon Curt Noll
120527d375 fix gcc v12.2.0 warnings when compiling errtbl.c 2023-09-19 22:13:10 -07:00
Landon Curt Noll
39429e370c fix errtbl.c to compile under gcc
When errtbl.c is being compiled for the errcode executable,
(when ERRCODE_SRC is defined), skip functions that make
called to math_error() and name_newerrorstr() from libcalc.
2023-09-19 18:42:34 -07:00
Landon Curt Noll
ff90bc0e3a add E_STRING to error, errno, strerror, change multiple E_STRING's
While help/errstr has been added, the errstr builtin function is
not yet written.  In anticipation of the new errstr builtin the
rest of the calc error system has been updated to associated errsym
E_STRING's with errnum error codes and errmsg error messages.

Minor improvements to help/rand.

The verify_error_table() function that does a verification
the error_table[] array and setup private_error_alias[] array
is now called by libcalc_call_me_first().

Fix comment about wrong include file in have_sys_mount.h.

Removed unused booltostr() and strtobool() macros from bool.h.

Moved define of math_error(char *, ...) from zmath.h to errtbl.h.
The errtbl.h include file, unless ERRCODE_SRC is defined
also includes attribute.h and errsym.h.

Group calc error related builtin support functions together in func.c.

Make switch indenting in func.c consistent.

Passing an invalid argument to error(), errno() or strerror() will
set errno AND throw a math error.  Before errno would be set and
an error value was returned.  Before there was no way to tell if
the error value was a result of the arg or if an error detected.

Added E_STRING to error([errnum | "E_STRING"]) builtin function.
Added E_STRING to errno([errnum | "E_STRING"]) builtin function.
Added E_STRING to strerror([errnum | "E_STRING"]) builtin function.
Calling these functions with an E_STRING errsym is the same as calling
them with the matching errnum code.

Standardized on calc computation error related E_STRING strings
where there are a set of related codes.  Changed "E_...digits" into
"E_..._digits".  For example, E_FPUTC1 became E_FPUTC_1, E_FPUTC2
became E_FPUTC_2, and E_FPUTC3 became E_FPUTC_3.  In a few cases
such as E_APPR became E_APPR_1, because there was a E_APPR2 (which
became E_APPR_2) and E_APPR3 (which became E_APPR_3).  To other
special cases, E_ILOG10 became E_IBASE10_LOG and E_ILOG2 became
E_IBASE2_LOG because E_ILOG10 and E_ILOG2 are both independent calc
computation error related E_STRING strings.  Now related sets of
E_STRING strings end in _ (underscore) followed by digits.

The following is the list of E_STRING strings changes:

    E_APPR ==> E_APPR_1
    E_ROUND ==> E_ROUND_1
    E_SQRT ==> E_SQRT_1
    E_ROOT ==> E_ROOT_1
    E_SHIFT ==> E_SHIFT_1
    E_SCALE ==> E_SCALE_1
    E_POWI ==> E_POWI_1
    E_POWER ==> E_POWER_1
    E_QUO ==> E_QUO_1
    E_MOD ==> E_MOD_1
    E_ABS ==> E_ABS_1
    E_APPR2 ==> E_APPR_2
    E_APPR3 ==> E_APPR_3
    E_ROUND2 ==> E_ROUND_2
    E_ROUND3 ==> E_ROUND_3
    E_BROUND2 ==> E_BROUND_2
    E_BROUND3 ==> E_BROUND_3
    E_SQRT2 ==> E_SQRT_2
    E_SQRT3 ==> E_SQRT_3
    E_ROOT2 ==> E_ROOT_2
    E_ROOT3 ==> E_ROOT_3
    E_SHIFT2 ==> E_SHIFT_2
    E_SCALE2 ==> E_SCALE_2
    E_POWI2 ==> E_POWI_2
    E_POWER2 ==> E_POWER_2
    E_POWER3 ==> E_POWER_3
    E_QUO2 ==> E_QUO_2
    E_QUO3 ==> E_QUO_3
    E_MOD2 ==> E_MOD_2
    E_MOD3 ==> E_MOD_3
    E_ABS2 ==> E_ABS_2
    E_EXP1 ==> E_EXP_1
    E_EXP2 ==> E_EXP_2
    E_FPUTC1 ==> E_FPUTC_1
    E_FPUTC2 ==> E_FPUTC_2
    E_FPUTC3 ==> E_FPUTC_3
    E_FGETC1 ==> E_FGETC_1
    E_FGETC2 ==> E_FGETC_2
    E_FOPEN1 ==> E_FOPEN_1
    E_FOPEN2 ==> E_FOPEN_2
    E_FREOPEN1 ==> E_FREOPEN_1
    E_FREOPEN2 ==> E_FREOPEN_2
    E_FREOPEN3 ==> E_FREOPEN_3
    E_FCLOSE1 ==> E_FCLOSE_1
    E_FPUTS1 ==> E_FPUTS_1
    E_FPUTS2 ==> E_FPUTS_2
    E_FPUTS3 ==> E_FPUTS_3
    E_FGETS1 ==> E_FGETS_1
    E_FGETS2 ==> E_FGETS_2
    E_FPUTSTR1 ==> E_FPUTSTR_1
    E_FPUTSTR2 ==> E_FPUTSTR_2
    E_FPUTSTR3 ==> E_FPUTSTR_3
    E_FGETSTR1 ==> E_FGETSTR_1
    E_FGETSTR2 ==> E_FGETSTR_2
    E_FGETLINE1 ==> E_FGETLINE_1
    E_FGETLINE2 ==> E_FGETLINE_2
    E_FGETFIELD1 ==> E_FGETFIELD_1
    E_FGETFIELD2 ==> E_FGETFIELD_2
    E_REWIND1 ==> E_REWIND_1
    E_PRINTF1 ==> E_PRINTF_1
    E_PRINTF2 ==> E_PRINTF_2
    E_FPRINTF1 ==> E_FPRINTF_1
    E_FPRINTF2 ==> E_FPRINTF_2
    E_FPRINTF3 ==> E_FPRINTF_3
    E_STRPRINTF1 ==> E_STRPRINTF_1
    E_STRPRINTF2 ==> E_STRPRINTF_2
    E_FSCAN1 ==> E_FSCAN_1
    E_FSCAN2 ==> E_FSCAN_2
    E_FSCANF1 ==> E_FSCANF_1
    E_FSCANF2 ==> E_FSCANF_2
    E_FSCANF3 ==> E_FSCANF_3
    E_FSCANF4 ==> E_FSCANF_4
    E_STRSCANF1 ==> E_STRSCANF_1
    E_STRSCANF2 ==> E_STRSCANF_2
    E_STRSCANF3 ==> E_STRSCANF_3
    E_STRSCANF4 ==> E_STRSCANF_4
    E_SCANF1 ==> E_SCANF_1
    E_SCANF2 ==> E_SCANF_2
    E_SCANF3 ==> E_SCANF_3
    E_FTELL1 ==> E_FTELL_1
    E_FTELL2 ==> E_FTELL_2
    E_FSEEK1 ==> E_FSEEK_1
    E_FSEEK2 ==> E_FSEEK_2
    E_FSEEK3 ==> E_FSEEK_3
    E_FSIZE1 ==> E_FSIZE_1
    E_FSIZE2 ==> E_FSIZE_2
    E_FEOF1 ==> E_FEOF_1
    E_FEOF2 ==> E_FEOF_2
    E_FERROR1 ==> E_FERROR_1
    E_FERROR2 ==> E_FERROR_2
    E_UNGETC1 ==> E_UNGETC_1
    E_UNGETC2 ==> E_UNGETC_2
    E_UNGETC3 ==> E_UNGETC_3
    E_ISATTY1 ==> E_ISATTY_1
    E_ISATTY2 ==> E_ISATTY_2
    E_ACCESS1 ==> E_ACCESS_1
    E_ACCESS2 ==> E_ACCESS_2
    E_SEARCH1 ==> E_SEARCH_1
    E_SEARCH2 ==> E_SEARCH_2
    E_SEARCH3 ==> E_SEARCH_3
    E_SEARCH4 ==> E_SEARCH_4
    E_SEARCH5 ==> E_SEARCH_5
    E_SEARCH6 ==> E_SEARCH_6
    E_RSEARCH1 ==> E_RSEARCH_1
    E_RSEARCH2 ==> E_RSEARCH_2
    E_RSEARCH3 ==> E_RSEARCH_3
    E_RSEARCH4 ==> E_RSEARCH_4
    E_RSEARCH5 ==> E_RSEARCH_5
    E_RSEARCH6 ==> E_RSEARCH_6
    E_REWIND2 ==> E_REWIND_2
    E_STRERROR1 ==> E_STRERROR_1
    E_STRERROR2 ==> E_STRERROR_2
    E_COS1 ==> E_COS_1
    E_COS2 ==> E_COS_2
    E_SIN1 ==> E_SIN_1
    E_SIN2 ==> E_SIN_2
    E_EVAL2 ==> E_EVAL_2
    E_ARG1 ==> E_ARG_1
    E_ARG2 ==> E_ARG_2
    E_POLAR1 ==> E_POLAR_1
    E_POLAR2 ==> E_POLAR_2
    E_MATFILL1 ==> E_MATFILL_1
    E_MATFILL2 ==> E_MATFILL_2
    E_MATTRANS1 ==> E_MATTRANS_1
    E_MATTRANS2 ==> E_MATTRANS_2
    E_DET1 ==> E_DET_1
    E_DET2 ==> E_DET_2
    E_DET3 ==> E_DET_3
    E_MATMIN1 ==> E_MATMIN_1
    E_MATMIN2 ==> E_MATMIN_2
    E_MATMIN3 ==> E_MATMIN_3
    E_MATMAX1 ==> E_MATMAX_1
    E_MATMAX2 ==> E_MATMAX_2
    E_MATMAX3 ==> E_MATMAX_3
    E_CP1 ==> E_CP_1
    E_CP2 ==> E_CP_2
    E_CP3 ==> E_CP_3
    E_DP1 ==> E_DP_1
    E_DP2 ==> E_DP_2
    E_DP3 ==> E_DP_3
    E_SUBSTR1 ==> E_SUBSTR_1
    E_SUBSTR2 ==> E_SUBSTR_2
    E_INSERT1 ==> E_INSERT_1
    E_INSERT2 ==> E_INSERT_2
    E_DELETE1 ==> E_DELETE_1
    E_DELETE2 ==> E_DELETE_2
    E_LN1 ==> E_LN_1
    E_LN2 ==> E_LN_2
    E_ERROR1 ==> E_ERROR_1
    E_ERROR2 ==> E_ERROR_2
    E_EVAL3 ==> E_EVAL_3
    E_EVAL4 ==> E_EVAL_4
    E_RM1 ==> E_RM_1
    E_RM2 ==> E_RM_2
    E_BLK1 ==> E_BLK_1
    E_BLK2 ==> E_BLK_2
    E_BLK3 ==> E_BLK_3
    E_BLK4 ==> E_BLK_4
    E_BLKFREE1 ==> E_BLKFREE_1
    E_BLKFREE2 ==> E_BLKFREE_2
    E_BLKFREE3 ==> E_BLKFREE_3
    E_BLKFREE4 ==> E_BLKFREE_4
    E_BLKFREE5 ==> E_BLKFREE_5
    E_BLOCKS1 ==> E_BLOCKS_1
    E_BLOCKS2 ==> E_BLOCKS_2
    E_COPY1 ==> E_COPY_01
    E_COPY2 ==> E_COPY_02
    E_COPY3 ==> E_COPY_03
    E_COPY4 ==> E_COPY_04
    E_COPY5 ==> E_COPY_05
    E_COPY6 ==> E_COPY_06
    E_COPY7 ==> E_COPY_07
    E_COPY8 ==> E_COPY_08
    E_COPY9 ==> E_COPY_09
    E_COPY10 ==> E_COPY_10
    E_COPY11 ==> E_COPY_11
    E_COPY12 ==> E_COPY_12
    E_COPY13 ==> E_COPY_13
    E_COPY14 ==> E_COPY_14
    E_COPY15 ==> E_COPY_15
    E_COPY16 ==> E_COPY_16
    E_COPY17 ==> E_COPY_17
    E_COPYF1 ==> E_COPYF_1
    E_COPYF2 ==> E_COPYF_2
    E_COPYF3 ==> E_COPYF_3
    E_COPYF4 ==> E_COPYF_4
    E_PROTECT1 ==> E_PROTECT_1
    E_PROTECT2 ==> E_PROTECT_2
    E_PROTECT3 ==> E_PROTECT_3
    E_MATFILL3 ==> E_MATFILL_3
    E_MATFILL4 ==> E_MATFILL_4
    E_MATTRACE1 ==> E_MATTRACE_1
    E_MATTRACE2 ==> E_MATTRACE_2
    E_MATTRACE3 ==> E_MATTRACE_3
    E_TAN1 ==> E_TAN_1
    E_TAN2 ==> E_TAN_2
    E_COT1 ==> E_COT_1
    E_COT2 ==> E_COT_2
    E_SEC1 ==> E_SEC_1
    E_SEC2 ==> E_SEC_2
    E_CSC1 ==> E_CSC_1
    E_CSC2 ==> E_CSC_2
    E_SINH1 ==> E_SINH_1
    E_SINH2 ==> E_SINH_2
    E_COSH1 ==> E_COSH_1
    E_COSH2 ==> E_COSH_2
    E_TANH1 ==> E_TANH_1
    E_TANH2 ==> E_TANH_2
    E_COTH1 ==> E_COTH_1
    E_COTH2 ==> E_COTH_2
    E_SECH1 ==> E_SECH_1
    E_SECH2 ==> E_SECH_2
    E_CSCH1 ==> E_CSCH_1
    E_CSCH2 ==> E_CSCH_2
    E_ASIN1 ==> E_ASIN_1
    E_ASIN2 ==> E_ASIN_2
    E_ACOS1 ==> E_ACOS_1
    E_ACOS2 ==> E_ACOS_2
    E_ATAN1 ==> E_ATAN_1
    E_ATAN2 ==> E_ATAN_2
    E_ACOT1 ==> E_ACOT_1
    E_ACOT2 ==> E_ACOT_2
    E_ASEC1 ==> E_ASEC_1
    E_ASEC2 ==> E_ASEC_2
    E_ACSC1 ==> E_ACSC_1
    E_ACSC2 ==> E_ACSC_2
    E_ASINH1 ==> E_ASINH_1
    E_ASINH2 ==> E_ASINH_2
    E_ACOSH1 ==> E_ACOSH_1
    E_ACOSH2 ==> E_ACOSH_2
    E_ATANH1 ==> E_ATANH_1
    E_ATANH2 ==> E_ATANH_2
    E_ACOTH1 ==> E_ACOTH_1
    E_ACOTH2 ==> E_ACOTH_2
    E_ASECH1 ==> E_ASECH_1
    E_ASECH2 ==> E_ASECH_2
    E_ACSCH1 ==> E_ACSCH_1
    E_ACSCH2 ==> E_ACSCH_2
    E_GD1 ==> E_GD_1
    E_GD2 ==> E_GD_2
    E_AGD1 ==> E_AGD_1
    E_AGD2 ==> E_AGD_2
    E_BIT1 ==> E_BIT_1
    E_BIT2 ==> E_BIT_2
    E_SETBIT1 ==> E_SETBIT_1
    E_SETBIT2 ==> E_SETBIT_2
    E_SETBIT3 ==> E_SETBIT_3
    E_SEG1 ==> E_SEG_1
    E_SEG2 ==> E_SEG_2
    E_SEG3 ==> E_SEG_3
    E_HIGHBIT1 ==> E_HIGHBIT_1
    E_HIGHBIT2 ==> E_HIGHBIT_2
    E_LOWBIT1 ==> E_LOWBIT_1
    E_LOWBIT2 ==> E_LOWBIT_2
    E_HEAD1 ==> E_HEAD_1
    E_HEAD2 ==> E_HEAD_2
    E_TAIL1 ==> E_TAIL_1
    E_TAIL2 ==> E_TAIL_2
    E_XOR1 ==> E_XOR_1
    E_XOR2 ==> E_XOR_2
    E_INDICES1 ==> E_INDICES_1
    E_INDICES2 ==> E_INDICES_2
    E_EXP3 ==> E_EXP_3
    E_SINH3 ==> E_SINH_3
    E_COSH3 ==> E_COSH_3
    E_SIN3 ==> E_SIN_3
    E_COS3 ==> E_COS_3
    E_GD3 ==> E_GD_3
    E_AGD3 ==> E_AGD_3
    E_POWER4 ==> E_POWER_4
    E_ROOT4 ==> E_ROOT_4
    E_DGT1 ==> E_DGT_1
    E_DGT2 ==> E_DGT_2
    E_DGT3 ==> E_DGT_3
    E_PLCS1 ==> E_PLCS_1
    E_PLCS2 ==> E_PLCS_2
    E_DGTS1 ==> E_DGTS_1
    E_DGTS2 ==> E_DGTS_2
    E_ILOG10 ==> E_IBASE10_LOG
    E_ILOG2 ==> E_IBASE2_LOG
    E_COMB1 ==> E_COMB_1
    E_COMB2 ==> E_COMB_2
    E_ASSIGN1 ==> E_ASSIGN_1
    E_ASSIGN2 ==> E_ASSIGN_2
    E_ASSIGN3 ==> E_ASSIGN_3
    E_ASSIGN4 ==> E_ASSIGN_4
    E_ASSIGN5 ==> E_ASSIGN_5
    E_ASSIGN6 ==> E_ASSIGN_6
    E_ASSIGN7 ==> E_ASSIGN_7
    E_ASSIGN8 ==> E_ASSIGN_8
    E_ASSIGN9 ==> E_ASSIGN_9
    E_SWAP1 ==> E_SWAP_1
    E_SWAP2 ==> E_SWAP_2
    E_SWAP3 ==> E_SWAP_3
    E_QUOMOD1 ==> E_QUOMOD_1
    E_QUOMOD2 ==> E_QUOMOD_2
    E_QUOMOD3 ==> E_QUOMOD_3
    E_PREINC1 ==> E_PREINC_1
    E_PREINC2 ==> E_PREINC_2
    E_PREINC3 ==> E_PREINC_3
    E_PREDEC1 ==> E_PREDEC_1
    E_PREDEC2 ==> E_PREDEC_2
    E_PREDEC3 ==> E_PREDEC_3
    E_POSTINC1 ==> E_POSTINC_1
    E_POSTINC2 ==> E_POSTINC_2
    E_POSTINC3 ==> E_POSTINC_3
    E_POSTDEC1 ==> E_POSTDEC_1
    E_POSTDEC2 ==> E_POSTDEC_2
    E_POSTDEC3 ==> E_POSTDEC_3
    E_INIT1 ==> E_INIT_01
    E_INIT2 ==> E_INIT_02
    E_INIT3 ==> E_INIT_03
    E_INIT4 ==> E_INIT_04
    E_INIT5 ==> E_INIT_05
    E_INIT6 ==> E_INIT_06
    E_INIT7 ==> E_INIT_07
    E_INIT8 ==> E_INIT_08
    E_INIT9 ==> E_INIT_09
    E_INIT10 ==> E_INIT_10
    E_LIST1 ==> E_LIST_1
    E_LIST2 ==> E_LIST_2
    E_LIST3 ==> E_LIST_3
    E_LIST4 ==> E_LIST_4
    E_LIST5 ==> E_LIST_5
    E_LIST6 ==> E_LIST_6
    E_MODIFY1 ==> E_MODIFY_1
    E_MODIFY2 ==> E_MODIFY_2
    E_MODIFY3 ==> E_MODIFY_3
    E_MODIFY4 ==> E_MODIFY_4
    E_MODIFY5 ==> E_MODIFY_5
    E_FPATHOPEN1 ==> E_FPATHOPEN_1
    E_FPATHOPEN2 ==> E_FPATHOPEN_2
    E_LOG1 ==> E_LOG_1
    E_LOG2 ==> E_LOG_2
    E_LOG3 ==> E_LOG_3
    E_FGETFILE1 ==> E_FGETFILE_1
    E_FGETFILE2 ==> E_FGETFILE_2
    E_FGETFILE3 ==> E_FGETFILE_3
    E_TAN3 ==> E_TAN_3
    E_TAN4 ==> E_TAN_4
    E_COT3 ==> E_COT_3
    E_COT4 ==> E_COT_4
    E_SEC3 ==> E_SEC_3
    E_CSC3 ==> E_CSC_3
    E_TANH3 ==> E_TANH_3
    E_TANH4 ==> E_TANH_4
    E_COTH3 ==> E_COTH_3
    E_COTH4 ==> E_COTH_4
    E_SECH3 ==> E_SECH_3
    E_CSCH3 ==> E_CSCH_3
    E_ASIN3 ==> E_ASIN_3
    E_ACOS3 ==> E_ACOS_3
    E_ASINH3 ==> E_ASINH_3
    E_ACOSH3 ==> E_ACOSH_3
    E_ATAN3 ==> E_ATAN_3
    E_ACOT3 ==> E_ACOT_3
    E_ASEC3 ==> E_ASEC_3
    E_ACSC3 ==> E_ACSC_3
    E_ATANH3 ==> E_ATANH_3
    E_ACOTH3 ==> E_ACOTH_3
    E_ASECH3 ==> E_ASECH_3
    E_ACSCH3 ==> E_ACSCH_3
    E_D2R1 ==> E_D2R_1
    E_D2R2 ==> E_D2R_2
    E_R2D1 ==> E_R2D_1
    E_R2D2 ==> E_R2D_2
    E_G2R1 ==> E_G2R_1
    E_G2R2 ==> E_G2R_2
    E_R2G1 ==> E_R2G_1
    E_R2G2 ==> E_R2G_2
    E_D2G1 ==> E_D2G_1
    E_G2D1 ==> E_G2D_1
    E_D2DMS1 ==> E_D2DMS_1
    E_D2DMS2 ==> E_D2DMS_2
    E_D2DMS3 ==> E_D2DMS_3
    E_D2DMS4 ==> E_D2DMS_4
    E_D2DM1 ==> E_D2DM_1
    E_D2DM2 ==> E_D2DM_2
    E_D2DM3 ==> E_D2DM_3
    E_D2DM4 ==> E_D2DM_4
    E_G2GMS1 ==> E_G2GMS_1
    E_G2GMS2 ==> E_G2GMS_2
    E_G2GMS3 ==> E_G2GMS_3
    E_G2GMS4 ==> E_G2GMS_4
    E_G2GM1 ==> E_G2GM_1
    E_G2GM2 ==> E_G2GM_2
    E_G2GM3 ==> E_G2GM_3
    E_G2GM4 ==> E_G2GM_4
    E_H2HMS1 ==> E_H2HMS_1
    E_H2HMS2 ==> E_H2HMS_2
    E_H2HMS3 ==> E_H2HMS_3
    E_H2HMS4 ==> E_H2HMS_4
    E_H2HM1 ==> E_H2HM_1
    E_H2HM2 ==> E_H2HM_2
    E_H2HM3 ==> E_H2HM_3
    E_H2HM4 ==> E_H2HM_4
    E_DMS2D1 ==> E_DMS2D_1
    E_DMS2D2 ==> E_DMS2D_2
    E_DM2D1 ==> E_DM2D_1
    E_DM2D2 ==> E_DM2D_2
    E_GMS2G1 ==> E_GMS2G_1
    E_GMS2G2 ==> E_GMS2G_2
    E_GM2G1 ==> E_GM2G_1
    E_GM2G2 ==> E_GM2G_2
    E_HMS2H1 ==> E_HMS2H_1
    E_HMS2H2 ==> E_HMS2H_2
    E_HM2H1 ==> E_HM2H_1
    E_HM2H2 ==> E_HM2H_2
    E_VERSIN1 ==> E_VERSIN_1
    E_VERSIN2 ==> E_VERSIN_2
    E_VERSIN3 ==> E_VERSIN_3
    E_AVERSIN1 ==> E_AVERSIN_1
    E_AVERSIN2 ==> E_AVERSIN_2
    E_AVERSIN3 ==> E_AVERSIN_3
    E_COVERSIN1 ==> E_COVERSIN_1
    E_COVERSIN2 ==> E_COVERSIN_2
    E_COVERSIN3 ==> E_COVERSIN_3
    E_ACOVERSIN1 ==> E_ACOVERSIN_1
    E_ACOVERSIN2 ==> E_ACOVERSIN_2
    E_ACOVERSIN3 ==> E_ACOVERSIN_3
    E_VERCOS1 ==> E_VERCOS_1
    E_VERCOS2 ==> E_VERCOS_2
    E_VERCOS3 ==> E_VERCOS_3
    E_AVERCOS1 ==> E_AVERCOS_1
    E_AVERCOS2 ==> E_AVERCOS_2
    E_AVERCOS3 ==> E_AVERCOS_3
    E_COVERCOS1 ==> E_COVERCOS_1
    E_COVERCOS2 ==> E_COVERCOS_2
    E_COVERCOS3 ==> E_COVERCOS_3
    E_ACOVERCOS1 ==> E_ACOVERCOS_1
    E_ACOVERCOS2 ==> E_ACOVERCOS_2
    E_ACOVERCOS3 ==> E_ACOVERCOS_3
    E_TAN5 ==> E_TAN_5
    E_COT5 ==> E_COT_5
    E_COT6 ==> E_COT_6
    E_SEC5 ==> E_SEC_5
    E_CSC5 ==> E_CSC_5
    E_CSC6 ==> E_CSC_6
2023-09-19 18:34:21 -07:00
Landon Curt Noll
5e5656652f update error_table[] E_STRING symbols
Now the "E_STRING" errsym strings in error_table[], with exception
to the 1st E__BASE entry, all other errsym strings must match the
following regular expression:

	^E_[A-Z][A-Z0-9_]+$

Renamed "E_1OVER0" to "E_DIVBYZERO".
Renamed "E_0OVER0" to "E_ZERODIVZERO".
2023-09-13 21:38:07 -07:00
Landon Curt Noll
3b9393a8ac fix redundant #defines
Removed from errsym.h (as built by errcode -d via the Makefile),
E__NONE, E__BASE, E__USERDEF, and E__USERMAX.  These symbols were
also defined in errtbl.h, which is NOW the place of the #define.

Update .gitigore with another temporary file.
2023-09-13 20:55:22 -07:00
Landon Curt Noll
40c8f875c1 rename E__COUNT to ECOUNT
Rename the #define E__COUNT to ECOUNT to avoid confusion
with "E_STRING" error symbols.

Improve formatting of help/error, help/errno, and help/strerror.

Update .gitignore.
2023-09-13 20:20:46 -07:00
Landon Curt Noll
d943fda3eb clarify how old code may use the new error_table[] array
Code that used the old array error_table[] of error message strings
such as:

    #include "calcerr.h"

    char *msg;	/* calc computation error message */

    msg = error_table[errnum - E__BASE];

where errnum is the calc computation error code
E__BASE <= errnum <= E__HIGHEST, may now use:

    #include "errtbl.h"
    #include "errsym.h"

    char *msg;	/* calc computation error message */

    msg = error_table[errnum - E__BASE].errmsg;
2023-09-13 03:16:20 -07:00
Landon Curt Noll
a6824debbc improved calc computation error codes message array
Changed calc_errno a global int variable so that is may be directly
accessed by libcalc users.

Further improve help files for help/errno, help/error, help/newerror,
help/stoponerror and help/strerror by adding to documentation
of the calc error code system as well as libcalc interface
where applicable.

Changed #define E_USERDEF to #define E__USERDEF.

Removed use of E_USERDEF, E__BASE, E__COUNT, and E__HIGHEST
from custom/c_sysinfo because the c_sysinfo is just a demo
and this will simplify the custom/Makefile.

The include file calcerr.h is now the errsym.h include file.
The calcerr.tbl has been replaced by errtbl.c and errtbl.h.

The calcerr_c.awk, calcerr_c.sed, calcerr_h.awk, and
calcerr_h.sed files are now obsolete and have been removed.
The calcerr.c and calcerr.h now obsolete and are no longer built.

The calc computation error codes, symbols and messages are now in
a error_table[] array of struct errtbl.

An E_STRING is a string corresponds to an error code #define.
For example, the E_STRING for the calc error E_STRCAT,
is the string "E_STRING".  An E_STRING must now match
the regular expression: "^E_[A-Z0-9_]+$".

The old array error_table[] of error message strings has been
replaced by a new error_table[] array of struct errtbl.  The struct
errtbl array holds calc errnum error codes, the related E_STRING
symbol as a string, and the original related error message.
To add new computation error codes, add them near the bottom of the
error_table[] array, just before the NULL entry.

The ./errcode utility, when run, will verify the consistency of
the error_table[] array.

The Makefile uses ./errcode -e to generate the contents of
help/errorcodes file.  The help errorcodes now prints
information from the new cstruct errtbl error_table[] array.

The help/errorcodes.hdr and help/errorcodes.sed files are
now obsolete and have been removed.

The Makefile uses ./errcode -d to generate the contents of the
errsym.h include file.

Updated .gitignore and trailblank to support the above changes.
2023-09-13 02:45:33 -07:00
Landon Curt Noll
1507adb261 improve more of the calc error code system
Even Further improve help files for help/errno, help/error,
and help/newerror.
2023-09-12 16:09:28 -07:00
Landon Curt Noll
229a60e4d5 improve calc error code system
Changed calc_errno a global int variable so that is may be directly
accessed by libcalc users.

Further improve help files for help/errno, help/error, help/newerror,
help/stoponerror and help/strerror by adding to documentation
of the calc error code system as well as libcalc interface
where applicable.
2023-09-12 16:06:27 -07:00
Landon Curt Noll
19819340ff improve calc error code system
Added help/errorcodes rule to the top level Makefile.

Added E_USERMAX symbol (== 32767) to indicate the maximum value
allowed for user error codes.

Improve help/error.  Added text about error code ranges and
range symbols.
2023-09-12 14:08:49 -07:00
Landon Curt Noll
4c65986502 improve inverse trigonometric help files 2023-09-11 15:34:12 -07:00
Landon Curt Noll
81eb6eac11 update which calc error codes are unused
In calcerr.tbl, error codes that are no longer
used start their error message with "UNUSED ERROR:".
2023-09-10 23:20:39 -07:00
Landon Curt Noll
bf730f5518 add cmappr() and missing complex tan, cot, sec, csc in liblcac
Added complex multiple approximation function to commath.c so
that users of libcalc may directly round complex number to
nearest multiple of a given real number:

    E_FUNC COMPLEX *cmappr(COMPLEX *c, NUMBER *e, long rnd, bool cfree);

For example:

    COMPLEX *c;             /* complex number to round to nearest epsilon */
    NUMBER *eps;            /* epsilon rounding precision */
    COMPLEX *res;           /* c rounded to nearest epsilon */
    long rnd = 24L;         /* a common rounding mode */
    bool ok_to_free;        /* true ==> free c, false ==> do not free c */

    ...

    res = cmappr(c, eps, ok_to_free);

The complex trigonometric functions tan, cot, sec, csc were implemented
in func.c as calls to complex sin and complex cos.  We added the
direct calls to comfunc.c so that users of libcalc may
call them directly:

    E_FUNC COMPLEX *c_tan(COMPLEX *c, NUMBER *eps);
    E_FUNC COMPLEX *c_cot(COMPLEX *c, NUMBER *eps);
    E_FUNC COMPLEX *c_sec(COMPLEX *c, NUMBER *eps);
    E_FUNC COMPLEX *c_cot(COMPLEX *c, NUMBER *eps);
2023-09-10 22:54:50 -07:00
Landon Curt Noll
a722b5cca7 update major trigonometric help files and regression tests
Improved help files for sin, cos, tan, cot, sec, csc.  In case
of tan, cot, sec, csc corrected help file was corrected to
indicate that complex arguments are allowed.  This was a help
file oversight from long ago when those trigonometric functions

Expanded the calc regression test suite test 34dd to test various
real and complex values for sin, cos, tan, cot, sec, csc.
2023-09-10 16:33:31 -07:00
Landon Curt Noll
78d536140f fix rand pseudo-random number generator
Fixed more documentation and code comments that referred to the old
additive 55 (a55) shuffle pseudo-random number generator.  We have
been using the subtractive 100 shuffle pseudo-random number generator
in place of the additive 55 generator for a while now.
2023-09-10 15:10:40 -07:00
Landon Curt Noll
8caa8d8635 update cal/README and cal/Makefile
Updated the cal/README to reflect the new names
of the calc regression test suite files.

Updated cal/Makefile to remove, when installing,
old names for calc regression test suite files.

Added missing getpgid_tmp to .gitignore.
2023-09-08 12:33:50 -07:00
Landon Curt Noll
d8603d3980 rename regression test calc resource files
To make the meaning a bit more clear in cal/regress.cal, we have
renamed the following test calc resource files that are related to
the calc regression test suite:

cal/test1700.cal -> cal/test8000.read.cal
cal/test2300.cal -> cal/test2300.obj_incdec.cal
cal/test2600.cal -> cal/test2600.numfunc.cal
cal/test2700.cal -> cal/test2700.isqrt.cal
cal/test3100.cal -> cal/test3100.matobj.cal
cal/test3400.cal -> cal/test3400.trig.cal
cal/test4000.cal -> cal/test4000.ptest.cal
cal/test4100.cal -> cal/test4100.redc.cal
cal/test4600.cal -> cal/test4600.fileop.cal
cal/test5100.cal -> cal/test5100.newdecl.cal
cal/test5200.cal -> cal/test5200.globstat.cal
cal/test8400.cal -> cal/test8400.quit.cal
cal/test8500.cal -> cal/test8500.divmod.cal
cal/test8600.cal -> cal/test8600.maxargs.cal
cal/set8700.cal -> cal/test8700.dotest.cal
cal/test8900.cal -> cal/test8900.special.cal
cal/test9300.cal -> cal/test9300.frem.cal

Added to test 94dd, read of a number of new calc resource files
that are not already read as a result of the calc regression test suite.
2023-09-08 12:15:04 -07:00
Landon Curt Noll
3fd55f0431 improve the cal/regress.cal regress test suite structure
Improve comments about use of the ${CALC_ENV} Makefile variable.
Noted in Makefile.cal where and how the ${CALC_ENV} is used.
Use ${CALC_ENV} Makefile variable were needed.

Modified regression test cal/regress.cal: in some cases test numbers
were adjusted.  Add comments indicate which test numbers apply to
which code.  Indicated where there is room for new tests.
Expanded the end of test numbers from 9999 to  99999.
2023-09-07 22:11:36 -07:00
Landon Curt Noll
b67e20881a fix historical trigonometric functions for values of 0
Fixed how the historical trigonometric functions call
the underlying trigonometric functions.  This fixes a
number of issues where the function for values of 0.

Updated cal/regress.cal to test historical trigonometric functions
at the  0 value.
2023-09-06 18:02:46 -07:00
Landon Curt Noll
c153ac08b9 add covercos, acovercos, haversin, ahaversin to help Makefile 2023-09-06 01:01:36 -07:00
Landon Curt Noll
fdbf53d7e8 add vercos(), avercos(), covercos(), acovercos()
Improved trig help files.

Added new vercos(x, [,eps]) for versed cosine and covercos(x, [,eps])
for inverse versed cosine.

Added new avercos(x, [,eps]) for inverse versed cosine and acovercos(x, [,eps])
for inverse coversed cosine.
2023-09-06 00:52:37 -07:00
Landon Curt Noll
ea5b5e0b53 fix aversin() and acoversin() to not modify args 2023-09-05 22:27:14 -07:00
Landon Curt Noll
3abedd6713 fix aversin() and acoversin()
In cases where the real value to the inverse versed sine and the
inverse coversed sine function produces a complex value, the
conversion from real to complex was incorrect.

Added c_to_q(COMPLEX *c, bool cfree) to make is easier to convert
a COMPLEX value that is real (imag part is 0) into a NUMBER and
optionally free the COMPLEX value.

The func.c code now uses c_to_q().

NOTE: There is a XXX bug marked in the f_aversin() and f_acoversin()
that still needs to be fixed.
2023-09-05 16:09:22 -07:00
Landon Curt Noll
ed112997a7 improve output of make prep and the #! line of update_ver 2023-09-03 23:50:23 -07:00
Landon Curt Noll
86f1d9e029 add new aversin and acoversin builtin functions.
Added new aversin(x, [,eps]) for inverse versed sine and acoversin(x, [,eps])
for inverse coversed sine.

Improved trig function help files to reference use of complex arguments
that while supported were not documented.

Removed old Makefile testing rules for make dbx and make gdb.

Improved "make run" to execute calccalc using shared libraries
from the local directory, and with reading of the startup scripts
disabled.

Changed "make prep" to perform various tests that are used to
help verify that calc is ready for a release.

Added Makefile testing rule testfuncsort to check for the sort
of the builtin function list.  Changed the order that builtin
functions are listed by "show builtin" and the help/builtin to
match the sorting of "LANG=C LC_ALL=C sort -d -u".
2023-09-03 23:37:09 -07:00
Landon Curt Noll
8edff80826 improve comments for versed sine and coversed sine functions 2023-09-02 23:10:24 -07:00
Landon Curt Noll
b55d41c221 change cal/wf2.cal to cal/write2file.cal
Also fixed Makefile typo.
2023-09-02 21:14:54 -07:00
Landon Curt Noll
df11a211c9 add write2file.cal for an example of how to do file I/O 2023-09-02 21:13:36 -07:00
Landon Curt Noll
20ce75a06d move versin() and coversin() code
Moved versin() and coversin() to bottom of functions in func.c
(however the builtin function list remains sorted).

Created a historical trig functions section for cmath.h and qmath.h.

Moved cal/test3500.cal to cal/test9300.cal to make room
for future trip tests going from test 3427 thru 3599.
2023-09-01 23:53:30 -07:00
Landon Curt Noll
7398fbb2e9 rename vercos to coversin
The code to compute 1 - sin(x) belongs to coversin, not vercos.
2023-09-01 23:26:26 -07:00
Landon Curt Noll
b0a48a2b70 add new versin and vercos builtin functions
Added new versin(x, [,eps]) for versed sine and vercos(x, [,eps])
for versed cosine.

Updated trig help files.
2023-09-01 17:38:14 -07:00
Landon Curt Noll
1c839dfede add logn and error checking for invalue eps and epsilon values
Add new logn(x, n [,eps]) builtin to compute logarithms to base n.

Verify that eps arguments (error tolerance arguments that override
the default epsilon value) to builtin functions have proper values.
Previously the eps argument had little to no value checks for
many builtin functions.

Document in help files for builtin functions that take eps arguments,
the LIMIT range for such eps values.
2023-08-31 22:33:41 -07:00
Landon Curt Noll
4787199462 improve check for invalid epsilon
We added check_epsilon(NUMBER *q) so that later, builtin
functions can check the eps value as well.
2023-08-31 03:32:49 -07:00
Landon Curt Noll
b95a62c14e fix setting an invalid epsilon
Setting an invalid epsilon via the epsilon(value) or confiv("epsilon",
value) triggers an error.  The epsilon value must be: 0 < epsilon < 1.
2023-08-31 03:20:38 -07:00
Landon Curt Noll
e021e2130f add calv 3 wish to value.h 2023-08-31 02:15:51 -07:00
Landon Curt Noll
94d4c1ad64 fix Makefile use of ${EXT} for hsrc intermediates
Also improve .gitignore sort comment.  Sort generic excluded patterns
and added *.exe plus library exclusions.
2023-08-31 02:14:56 -07:00
Landon Curt Noll
5659ddbc4e remove CALC2_COMPAT symbol in source code
Removed CALC2_COMPAT in favor of ckecking if MAJOR_VER < 3.

The sign element in a ZVALUE is now of type SIGN, which is either
SB32 when MAJOR_VER < 3, or a bool otherwise.

The len element in a ZVALUE is of type LEN.  LEN type is SB32 when
MAJOR_VER < 3, or a uintptr_t otherwise.

Noted version.h symbols in README.RELEASE instead of CALC2_COMPAT.

Improve .gitignore.  Add excludes of hsrc temporary and test
programs.  Added note about how the list is sorted.
Moved the generic excludes to the top.
2023-08-31 02:02:40 -07:00
Landon Curt Noll
faa93bf085 add calc v3 wishlist for v_type to become an enum 2023-08-31 01:06:55 -07:00
Landon Curt Noll
0d2d5e3df3 add comment about turning off optimizer in .lldbinit 2023-08-31 01:02:21 -07:00
Landon Curt Noll
969e72b5c6 add .lldbinit improve debug comment in Makefile.local 2023-08-31 00:05:49 -07:00
Landon Curt Noll
4dbc4dfe9a add qispowerof2() to qfunc.c, improve log2() code
Change zispowerof2() interaface to take a FULL ptr as the 2nd arg:
zispowerof2(ZVALUE z, FULL *log2).

Added qispowerof2(NUMBER *q, NUMBER **qlog2) to qfunc.c.

Change log2() builtin to use the new qispowerof2() internal interface.

Update LIBRARY to reflect the new zispowerof2() internal interface
and the new qispowerof2() internal interface.
2023-08-27 23:50:44 -07:00
Landon Curt Noll
4e5fcc8812 add log2(x [,eps]) builtin function
Added log2(x [,eps]) builtin function.  When x is an integer
power of 2, log2(x) will return an integer, otherwise it will
return the equivalent of ln(x)/ln(2).
2023-08-27 19:02:37 -07:00
Landon Curt Noll
56c568060a updated ver_calc command line
Removed `-R release_file` and `-r release_file` command
line options from `ver_calc`.  Add `-h` option.  Updated
comments in "README.RELEASE", which serves as the contents
of the calc command "help release".
2023-08-27 16:18:12 -07:00
Landon Curt Noll
61206172f1 add NULL pre firewall to ZVALUE code
The z*.c functions that take pointers that cannot be NULL are checked
for NULL pointers at the beginning of the function.

While calc is not known to pass bogus NULL pointers to ZVALUE related
code, libcalc could be called by external code that might do so by
mistake.  If that happens, math_error() is called with the name of
the function and the name of the arg that was NULL.
2023-08-23 15:46:46 -07:00
Landon Curt Noll
0bb66cff74 change int.h to check MAJOR_VER < 3 when CHK_C is undefined
The int.h will trigger an error when CHK_C is undefined and MAJOR_VER
>= 3.  Improved the int.h error message in this case.

Added some comments and C integers to int.h.
2023-08-23 14:53:15 -07:00
Landon Curt Noll
0353aba275 add int.h
Added int.h as a centeral place for calc integer types and integer macros.

Currently zmath.c includes int.h but does not yet use it.

Added missing ptr type checks to chk_c.c.
2023-08-22 22:37:08 -07:00
Landon Curt Noll
2d5339fc51 update make chk_c rule to form status.chk_c.h
The make chk_c file also forms status.chk_c.h which either
defines CHK_C when the C compiler and select include files
appear to meet calc requirements, or undefines CHK_C
when it does not.
2023-08-21 20:18:30 -07:00
Landon Curt Noll
6abdd8ef3f restore old fake boolean typedef when no <stdbool.h> 2023-08-21 04:05:24 -07:00
Landon Curt Noll
8c6d2b2e07 improve comment about use of += in Makefile.local 2023-08-21 03:59:03 -07:00
Landon Curt Noll
999ad61a78 fix bool.h dependency on have_stdbool.h, make depend 2023-08-21 03:51:28 -07:00
Landon Curt Noll
1cf05b660c add missing min and max checks to chk_c.c 2023-08-21 03:30:31 -07:00
Landon Curt Noll
4fddf82106 add C compiler and C include checks for calc
Fixed have_statfs optional executable file extension ${EXT{ in
the ${UTIL_PROGS} make variable.

Prevented the "fake boolean value" when <stdbool.h> is missing,
from complicating C compilers post c17 standard.

Test if <stdint.h> exists and set HAVE_STDINT_H accordingly
in have_stdint.h.  Added HAVE_STDINT_H to allow one to force
this value.

Test if <inttypes.h> exists and set HAVE_INTTYPES_H accordingly
in have_inttypes.h.  Added HAVE_INTTYPES_H to allow one to force
this value.

Added c_chk.c to check the compiler and C include for calc
requirements.  If you are unable to compile this program, or
if this program when compiles does not exit 0, then your C
compiler and/or C include fails to meet calc requirements.
Compilers that are at least c99 MUST be able to compile this
program such that when run will exit 0.

The "make hsrc" file will attempt to compile and run c_chk and
will warn if the C compiler and/or C include fails to meet
calc requirements.  The "make debug" system will run c_chk -c
to print information about the C compiler and C include.
Currently failure to compile cc_chk.c or c_chk exiting non-0
will just print "WARNING!!" strings to stderr.
2023-08-21 03:10:39 -07:00
Landon Curt Noll
b0aa949ad5 simplify booleans when <stdbool.h> header file is missing 2023-08-19 22:02:16 -07:00
Landon Curt Noll
3c18e6e25b changed C source to use C booleans with backward compatibility
Fix "Under source code control" date for new version.h file.

Sorted the order of symbols printed by "make env".

Test if <stdbool.h> exists and set HAVE_STDBOOL_H accordingly
in have_stdbool.h.  Added HAVE_STDBOOL_H to allow one to force
this value.

Added "bool.h" include file to support use of boolean symbols,
true and false for pre-c99 C compilers.  The "bool.h" include
file defines TRUE as true, FALSE as false, and BOOL as bool:
for backward compatibility.

The sign in a ZVALUE is now of type SIGN, whcih is either
SB32 when CALC2_COMPAT is defined, or a bool.

Replaced in C source, TRUE with true, FALSE with false, and
BOOL with bool.
2023-08-19 19:20:32 -07:00
Landon Curt Noll
e18b715f3f fix function decls for stringrel() and stringcaserel() 2023-08-19 18:20:15 -07:00
Landon Curt Noll
a0687079f4 fix MAXDATA for non-CALC2_COMPAT small pointer case 2023-08-19 17:34:55 -07:00
Landon Curt Noll
91c0c99a2c add CALC2_COMPAT and version.h
Moved calc version definition from version.c to version.h.
Added CALC2_COMPAT, that when defined attempts to maintain calc
version 2 compatibility.  When MAJOR_VER <= 2, CALC2_COMPAT is
defined.  This is anticipation for a future calc version 3 code.
2023-08-19 17:32:42 -07:00
Landon Curt Noll
a7597cdf6f improve use of fposval.h.def warning in Makefile
When `./fposval` fails to form `fposval.h` and
the fallback file `fposval.h.def` is used, issue
a suggestion for how to see the `./fposval` failure.
2023-08-19 16:22:07 -07:00
Landon Curt Noll
4b5c0e7574 fix format of examples in help/log2 and help/logn 2023-08-19 14:14:52 -07:00
Landon Curt Noll
f60a1d6bc5 add PTR_LEN and PTR_BITS to longbits.h
Added PTR_LEN (length of a pointer) and PTR_BITS (bit length
of a pointer) to longbits.h.
2023-08-19 12:53:31 -07:00
Landon Curt Noll
f2e4f638f6 change custom_compiled() to return BOOL
Also make slight improvements on error messages produced
when custom_compiled() returns an unexpected value.
2023-08-19 11:56:10 -07:00
Landon Curt Noll
c705b74e67 ignore built file: help/ilogn in .gitignore 2023-08-19 11:42:17 -07:00
Landon Curt Noll
5a117d542a add help in advance for new log2 and logn builtins
NOTE: The `log2(x [,eps])` and `logn(x, n [,eps])`
builtin functions are NOT yet implemented.
2023-08-19 11:23:02 -07:00
Landon Curt Noll
ea57d2f24f drop support for DJGPP and drop support for win32
Support for win32 and DJGPP has been dropped.  Calc version
2.14.3.5 was the last to make references to win32 and make
references to DJGPP.  Future versions of calc may work under
those systems, we just elected to remove the somewhat out of
date and awkward `win32.mkdef` and related win32 references.

If you are a win32 user, please feel free to create a win32
target in Makefile.target and submit as a pull request.
If you are a DJGPP user, please feel free to create a DJGPP
target in Makefile.target and submit as a pull request.
Until someone can test such systems, we prefer to wait
until someone is able to test and supply a pull request.
2023-08-18 17:05:49 -07:00
Landon Curt Noll
7ad1448a1a further clarify that Msys2 is a fork of Cygwin 2023-08-18 16:28:31 -07:00
Landon Curt Noll
96f925bede Merge pull request #96 from iahung2/master 2023-08-18 14:38:42 -07:00
iahung2
8055bf07c2 Update Makefile.config
Fix build on MSYS2 (MSYS)
2023-08-18 12:38:31 +07:00
Landon Curt Noll
28449fd187 Release v2.14.3.5
The following are the changes in this release:

    Under macOS, to reduce dependency chains, we remove functions
    and data that are unreachable by the entry point or exported
    symbols.  In particular, the macOS linker is used with both
    "-dead_strip" and "-dead_strip_dylibs".

    The libcalc shared library is now linked with libcustcalc.
2023-08-17 14:37:50 -07:00
Landon Curt Noll
d88b128b2d remove excess empty line from CHANGES 2023-08-17 14:30:30 -07:00
Landon Curt Noll
bc048bc029 prep CHANGES for the next release of calc 2023-08-17 14:28:52 -07:00
Landon Curt Noll
4d32b138ed change libcalc dynamic library to link with libcustcalc
Under macOS, to reduce dependency chains, we remove functions
and data that are unreachable by the entry point or exported
symbols.  In particular, the macOS linker is used with both
"-dead_strip" and "-dead_strip_dylibs".

The libcalc shared library is now linked with libcustcalc.
2023-08-17 14:23:29 -07:00
Landon Curt Noll
3cd8fd7053 Release v2.14.3.4
Fixed rpm spec file.

The following are the changes in this release:

    Fix typo in the `make debug` Makefile rule.

    Improved .gitignore to ignore .static, calc-static,
    sample_many-static and sample_rand-static.

    Improved error messages when trying to compile with
    with one calc type (when BLD_TYPE=calc-dynamic-only or
    BLD_TYPE=calc-static-only) and install with the other.

    When installing with BLD_TYPE=calc-static-only, the
    installed calc and calc-static are links to each other.
    Thanks to GitHub user @TurtleWilly for this suggestion.

    The dynamic shared libraries are not installed if they are not
    built.  So when installing with BLD_TYPE=calc-static-only, the
    install rule will not attempt to install dynamic shared libraries.
    Thanks to GitHub user @TurtleWilly for bringing to our attention,
    problems related to building a statically linked calc under macOS.

    Updated comments in Makefile.local for how to Diagnosing memory,
    thread, and crash issues under RHEL and macOS.

    We no longer support the Makefile variable ${ALLOW_CUSTOM} to be empty.
    Normally ${ALLOW_CUSTOM} is:

	ALLOW_CUSTOM= -DCUSTOM

    Now, to disable custom disable custom even if -C is given, use:

	ALLOW_CUSTOM="-UCUSTOM"

    Dropped support of Makefile.simple and custom/Makefile.simple.
    The calc version 2.14.3.0 is the last release that supported
    the Makefile.simple and custom/Makefile.simple files.
    Now, a make that supports makefile conditional syntax is required.
    The simple target, a target that only was used for Makefile.simple
    was removed.

    Moved makefile variables that configure calc and configure how to
    compile calc from Makefile into a new Makefile.config file.

    The Makeifle includes the Makefile.config file.
    The cal/Makeifle includes the Makefile.config file.
    The cscript/Makeifle includes the Makefile.config file.
    The custom/Makeifle includes the Makefile.config file.
    The help/Makeifle includes the Makefile.config file.

    Now, the Makefile.config file will consistently configure
    calc and how calc is compiled and built by all calc Makefiles.
    The custom/Makefile no longer includes Makefile.

    The platform target section from the old Makefile has been moved
    to a new file, Makefile.target.  Improved the format and comments
    in target information.

    The Makeifle includes the Makefile.target file.
    The cal/Makeifle includes the Makefile.target file.
    The cscript/Makeifle includes the Makefile.target file.
    The custom/Makeifle includes the Makefile.target file.
    The help/Makeifle includes the Makefile.target file.

    Now, the Makefile.target file will consistently set
    target information for all calc Makefiles.

    The cal/Makeifle includes the Makefile.local file.
    The cscript/Makeifle includes the Makefile.local file.
    The custom/Makeifle includes the Makefile.local file.
    The help/Makeifle includes the Makefile.local file.

    Thus, one may modify or append many Makefile variables
    in all calc Makefiles.

    Removed the ${CAL_PASSDOWN}, ${HELP_PASSDOWN}, ${HELP_PASSDOWN},
    ${CSCRIPT_PASSDOWN} Makefile variables as the new Makefile
    include files keep Makefile variables in sync.

    Fixed the ability of calc to compile when CUSTOM is undefined
    (i.e., -UCUSTOM).  The libcustcalc is always built, regardless
    of the $(ALLOW_CUSTOM} Makefile variable.  However when CUSTOM
    is undefined, the bulk of custom functions are not defined.

    Dropped the use of Makefile variable ${SET_INSTALL_NAME}.
    Under macOS it was always needed, elsewhere it was not.

    Added Makefile variable ${VER} to hold the calc major release version.
    The calc major release version is a 3 level version (x.y.z).

    Under macOS, the current version of both libcalc and libcustcalc
    shared libraries are set to the current calc major release version.

    Under macOS, to reduce dependency chains, we remove functions and
    data that are unreachable by the entry point or exported symbols.
    In particular, the macOS linker is used with "-dead_strip" by default.

    While calc on macOS will execute if linker used with "-dead_strip_dylibs"
    and CUSTOM is defined, other applications that use libcalc but not
    libcustcalc (such as sample_many and sample_rand) will fail to execute
    due to missile symbols.  Therefore "-dead_strip_dylibs" is not used
    by default when ALLOW_CUSTOM is "-DCUSTOM" under macOS.
    Thanks to GitHub user @TurtleWilly for bringing to our attention,
    problems related to use of  "-dead_strip_dylibs".

    When installing shared libraries, libcalc.x.y.z will be a link
    to the libcalc shared library and libcustcalc.x.y.z will be a link
    to the libcustcal shared library.
2023-08-14 23:09:46 -07:00
Landon Curt Noll
b0f19c1011 Release v2.14.3.4
Fixed rpm spec file.

The following are the changes in this release:

    Fix typo in the `make debug` Makefile rule.

    Improved .gitignore to ignore .static, calc-static,
    sample_many-static and sample_rand-static.

    Improved error messages when trying to compile with
    with one calc type (when BLD_TYPE=calc-dynamic-only or
    BLD_TYPE=calc-static-only) and install with the other.

    When installing with BLD_TYPE=calc-static-only, the
    installed calc and calc-static are links to each other.
    Thanks to GitHub user @TurtleWilly for this suggestion.

    The dynamic shared libraries are not installed if they are not
    built.  So when installing with BLD_TYPE=calc-static-only, the
    install rule will not attempt to install dynamic shared libraries.
    Thanks to GitHub user @TurtleWilly for bringing to our attention,
    problems related to building a statically linked calc under macOS.

    Updated comments in Makefile.local for how to Diagnosing memory,
    thread, and crash issues under RHEL and macOS.

    We no longer support the Makefile variable ${ALLOW_CUSTOM} to be empty.
    Normally ${ALLOW_CUSTOM} is:

	ALLOW_CUSTOM= -DCUSTOM

    Now, to disable custom disable custom even if -C is given, use:

	ALLOW_CUSTOM="-UCUSTOM"

    Dropped support of Makefile.simple and custom/Makefile.simple.
    The calc version 2.14.3.0 is the last release that supported
    the Makefile.simple and custom/Makefile.simple files.
    Now, a make that supports makefile conditional syntax is required.
    The simple target, a target that only was used for Makefile.simple
    was removed.

    Moved makefile variables that configure calc and configure how to
    compile calc from Makefile into a new Makefile.config file.

    The Makeifle includes the Makefile.config file.
    The cal/Makeifle includes the Makefile.config file.
    The cscript/Makeifle includes the Makefile.config file.
    The custom/Makeifle includes the Makefile.config file.
    The help/Makeifle includes the Makefile.config file.

    Now, the Makefile.config file will consistently configure
    calc and how calc is compiled and built by all calc Makefiles.
    The custom/Makefile no longer includes Makefile.

    The platform target section from the old Makefile has been moved
    to a new file, Makefile.target.  Improved the format and comments
    in target information.

    The Makeifle includes the Makefile.target file.
    The cal/Makeifle includes the Makefile.target file.
    The cscript/Makeifle includes the Makefile.target file.
    The custom/Makeifle includes the Makefile.target file.
    The help/Makeifle includes the Makefile.target file.

    Now, the Makefile.target file will consistently set
    target information for all calc Makefiles.

    The cal/Makeifle includes the Makefile.local file.
    The cscript/Makeifle includes the Makefile.local file.
    The custom/Makeifle includes the Makefile.local file.
    The help/Makeifle includes the Makefile.local file.

    Thus, one may modify or append many Makefile variables
    in all calc Makefiles.

    Removed the ${CAL_PASSDOWN}, ${HELP_PASSDOWN}, ${HELP_PASSDOWN},
    ${CSCRIPT_PASSDOWN} Makefile variables as the new Makefile
    include files keep Makefile variables in sync.

    Fixed the ability of calc to compile when CUSTOM is undefined
    (i.e., -UCUSTOM).  The libcustcalc is always built, regardless
    of the $(ALLOW_CUSTOM} Makefile variable.  However when CUSTOM
    is undefined, the bulk of custom functions are not defined.

    Dropped the use of Makefile variable ${SET_INSTALL_NAME}.
    Under macOS it was always needed, elsewhere it was not.

    Added Makefile variable ${VER} to hold the calc major release version.
    The calc major release version is a 3 level version (x.y.z).

    Under macOS, the current version of both libcalc and libcustcalc
    shared libraries are set to the current calc major release version.

    Under macOS, to reduce dependency chains, we remove functions and
    data that are unreachable by the entry point or exported symbols.
    In particular, the macOS linker is used with "-dead_strip" by default.

    While calc on macOS will execute if linker used with "-dead_strip_dylibs"
    and CUSTOM is defined, other applications that use libcalc but not
    libcustcalc (such as sample_many and sample_rand) will fail to execute
    due to missile symbols.  Therefore "-dead_strip_dylibs" is not used
    by default when ALLOW_CUSTOM is "-DCUSTOM" under macOS.
    Thanks to GitHub user @TurtleWilly for bringing to our attention,
    problems related to use of  "-dead_strip_dylibs".

    When installing shared libraries, libcalc.x.y.z will be a link
    to the libcalc shared library and libcustcalc.x.y.z will be a link
    to the libcustcal shared library.
2023-08-14 23:07:51 -07:00
Landon Curt Noll
fe520975cf Release v2.14.3.3
The following are the changes in this release:

    Fix typo in the `make debug` Makefile rule.

    Improved .gitignore to ignore .static, calc-static,
    sample_many-static and sample_rand-static.

    Improved error messages when trying to compile with
    with one calc type (when BLD_TYPE=calc-dynamic-only or
    BLD_TYPE=calc-static-only) and install with the other.

    When installing with BLD_TYPE=calc-static-only, the
    installed calc and calc-static are links to each other.
    Thanks to GitHub user @TurtleWilly for this suggestion.

    The dynamic shared libraries are not installed if they are not
    built.  So when installing with BLD_TYPE=calc-static-only, the
    install rule will not attempt to install dynamic shared libraries.
    Thanks to GitHub user @TurtleWilly for bringing to our attention,
    problems related to building a statically linked calc under macOS.

    Updated comments in Makefile.local for how to Diagnosing memory,
    thread, and crash issues under RHEL and macOS.

    We no longer support the Makefile variable ${ALLOW_CUSTOM} to be empty.
    Normally ${ALLOW_CUSTOM} is:

	ALLOW_CUSTOM= -DCUSTOM

    Now, to disable custom disable custom even if -C is given, use:

	ALLOW_CUSTOM="-UCUSTOM"

    Dropped support of Makefile.simple and custom/Makefile.simple.
    The calc version 2.14.3.0 is the last release that supported
    the Makefile.simple and custom/Makefile.simple files.
    Now, a make that supports makefile conditional syntax is required.
    The simple target, a target that only was used for Makefile.simple
    was removed.

    Moved makefile variables that configure calc and configure how to
    compile calc from Makefile into a new Makefile.config file.

    The Makeifle includes the Makefile.config file.
    The cal/Makeifle includes the Makefile.config file.
    The cscript/Makeifle includes the Makefile.config file.
    The custom/Makeifle includes the Makefile.config file.
    The help/Makeifle includes the Makefile.config file.

    Now, the Makefile.config file will consistently configure
    calc and how calc is compiled and built by all calc Makefiles.
    The custom/Makefile no longer includes Makefile.

    The platform target section from the old Makefile has been moved
    to a new file, Makefile.target.  Improved the format and comments
    in target information.

    The Makeifle includes the Makefile.target file.
    The cal/Makeifle includes the Makefile.target file.
    The cscript/Makeifle includes the Makefile.target file.
    The custom/Makeifle includes the Makefile.target file.
    The help/Makeifle includes the Makefile.target file.

    Now, the Makefile.target file will consistently set
    target information for all calc Makefiles.

    The cal/Makeifle includes the Makefile.local file.
    The cscript/Makeifle includes the Makefile.local file.
    The custom/Makeifle includes the Makefile.local file.
    The help/Makeifle includes the Makefile.local file.

    Thus, one may modify or append many Makefile variables
    in all calc Makefiles.

    Removed the ${CAL_PASSDOWN}, ${HELP_PASSDOWN}, ${HELP_PASSDOWN},
    ${CSCRIPT_PASSDOWN} Makefile variables as the new Makefile
    include files keep Makefile variables in sync.

    Fixed the ability of calc to compile when CUSTOM is undefined
    (i.e., -UCUSTOM).  The libcustcalc is always built, regardless
    of the $(ALLOW_CUSTOM} Makefile variable.  However when CUSTOM
    is undefined, the bulk of custom functions are not defined.

    Dropped the use of Makefile variable ${SET_INSTALL_NAME}.
    Under macOS it was always needed, elsewhere it was not.

    Added Makefile variable ${VER} to hold the calc major release version.
    The calc major release version is a 3 level version (x.y.z).

    Under macOS, the current version of both libcalc and libcustcalc
    shared libraries are set to the current calc major release version.

    Under macOS, to reduce dependency chains, we remove functions and
    data that are unreachable by the entry point or exported symbols.
    In particular, the macOS linker is used with "-dead_strip" by default.

    While calc on macOS will execute if linker used with "-dead_strip_dylibs"
    and CUSTOM is defined, other applications that use libcalc but not
    libcustcalc (such as sample_many and sample_rand) will fail to execute
    due to missile symbols.  Therefore "-dead_strip_dylibs" is not used
    by default when ALLOW_CUSTOM is "-DCUSTOM" under macOS.
    Thanks to GitHub user @TurtleWilly for bringing to our attention,
    problems related to use of  "-dead_strip_dylibs".

    When installing shared libraries, libcalc.x.y.z will be a link
    to the libcalc shared library and libcustcalc.x.y.z will be a link
    to the libcustcal shared library.
2023-08-14 22:45:24 -07:00
Landon Curt Noll
f097dd7dc1 update calc rpm to relase 14
Sort .gitignore.  Add calc.spec to .gitignore.

Update format of header part of Makefiles.

Modify calc.spec.in to handle dynamic shared libraries with 3-digit
version numbers.
2023-08-14 22:39:40 -07:00
Landon Curt Noll
3a7e763b28 Release v2.14.3.2
The following are the changes in this release:

    Fix typo in the `make debug` Makefile rule.

    Improved .gitignore to ignore .static, calc-static,
    sample_many-static and sample_rand-static.

    Improved error messages when trying to compile with
    with one calc type (when BLD_TYPE=calc-dynamic-only or
    BLD_TYPE=calc-static-only) and install with the other.

    When installing with BLD_TYPE=calc-static-only, the
    installed calc and calc-static are links to each other.
    Thanks to GitHub user @TurtleWilly for this suggestion.

    The dynamic shared libraries are not installed if they are not
    built.  So when installing with BLD_TYPE=calc-static-only, the
    install rule will not attempt to install dynamic shared libraries.
    Thanks to GitHub user @TurtleWilly for bringing to our attention,
    problems related to building a statically linked calc under macOS.

    Updated comments in Makefile.local for how to Diagnosing memory,
    thread, and crash issues under RHEL and macOS.

    We no longer support the Makefile variable ${ALLOW_CUSTOM} to be empty.
    Normally ${ALLOW_CUSTOM} is:

	ALLOW_CUSTOM= -DCUSTOM

    Now, to disable custom disable custom even if -C is given, use:

	ALLOW_CUSTOM="-UCUSTOM"

    Dropped support of Makefile.simple and custom/Makefile.simple.
    The calc version 2.14.3.0 is the last release that supported
    the Makefile.simple and custom/Makefile.simple files.
    Now, a make that supports makefile conditional syntax is required.
    The simple target, a target that only was used for Makefile.simple
    was removed.

    Moved makefile variables that configure calc and configure how to
    compile calc from Makefile into a new Makefile.config file.

    The Makeifle includes the Makefile.config file.
    The cal/Makeifle includes the Makefile.config file.
    The cscript/Makeifle includes the Makefile.config file.
    The custom/Makeifle includes the Makefile.config file.
    The help/Makeifle includes the Makefile.config file.

    Now, the Makefile.config file will consistently configure
    calc and how calc is compiled and built by all calc Makefiles.
    The custom/Makefile no longer includes Makefile.

    The platform target section from the old Makefile has been moved
    to a new file, Makefile.target.  Improved the format and comments
    in target information.

    The Makeifle includes the Makefile.target file.
    The cal/Makeifle includes the Makefile.target file.
    The cscript/Makeifle includes the Makefile.target file.
    The custom/Makeifle includes the Makefile.target file.
    The help/Makeifle includes the Makefile.target file.

    Now, the Makefile.target file will consistently set
    target information for all calc Makefiles.

    The cal/Makeifle includes the Makefile.local file.
    The cscript/Makeifle includes the Makefile.local file.
    The custom/Makeifle includes the Makefile.local file.
    The help/Makeifle includes the Makefile.local file.

    Thus, one may modify or append many Makefile variables
    in all calc Makefiles.

    Removed the ${CAL_PASSDOWN}, ${HELP_PASSDOWN}, ${HELP_PASSDOWN},
    ${CSCRIPT_PASSDOWN} Makefile variables as the new Makefile
    include files keep Makefile variables in sync.

    Fixed the ability of calc to compile when CUSTOM is undefined
    (i.e., -UCUSTOM).  The libcustcalc is always built, regardless
    of the $(ALLOW_CUSTOM} Makefile variable.  However when CUSTOM
    is undefined, the bulk of custom functions are not defined.

    Dropped the use of Makefile variable ${SET_INSTALL_NAME}.
    Under macOS it was always needed, elsewhere it was not.

    Added Makefile variable ${VER} to hold the calc major release version.
    The calc major release version is a 3 level version (x.y.z).

    Under macOS, the current version of both libcalc and libcustcalc
    shared libraries are set to the current calc major release version.

    Under macOS, to reduce dependency chains, we remove functions and
    data that are unreachable by the entry point or exported symbols.
    In particular, the macOS linker is used with "-dead_strip" by default.

    While calc on macOS will execute if linker used with "-dead_strip_dylibs"
    and CUSTOM is defined, other applications that use libcalc but not
    libcustcalc (such as sample_many and sample_rand) will fail to execute
    due to missile symbols.  Therefore "-dead_strip_dylibs" is not used
    by default when ALLOW_CUSTOM is "-DCUSTOM" under macOS.
    Thanks to GitHub user @TurtleWilly for bringing to our attention,
    problems related to use of  "-dead_strip_dylibs".

    When installing shared libraries, libcalc.x.y.z will be a link
    to the libcalc shared library and libcustcalc.x.y.z will be a link
    to the libcustcal shared library.
2023-08-14 18:32:28 -07:00
Landon Curt Noll
661e99829e prep CHANGES for the next release of calc 2023-08-14 18:25:46 -07:00
Landon Curt Noll
faf3a4fab6 fix macOS use of -dead_strip_dylibs, install major version lib symlinks.
Under macOS, to reduce dependency chains, we remove functions and
data that are unreachable by the entry point or exported symbols.
In particular, the macOS linker is used with "-dead_strip" by default.

While calc on macOS will execute if linker used with "-dead_strip_dylibs"
and CUSTOM is defined, other applications that use libcalc but not
libcustcalc (such as sample_many and sample_rand) will fail to execute
due to missile symbols.  Therefore "-dead_strip_dylibs" is not used
by default when ALLOW_CUSTOM is "-DCUSTOM" under macOS.
Thanks to GitHub user @TurtleWilly for bringing to our attention,
problems related to use of  "-dead_strip_dylibs".

When installing shared libraries, libcalc.x.y.z will be a link
to the libcalc shared library and libcustcalc.x.y.z will be a link
to the libcustcal shared library.
2023-08-14 17:40:29 -07:00
Landon Curt Noll
7d8d4cb5ea change macOS to not use "-dead_strip_dylibs" when CUSTOM is defined
Under macOS, to reduce dependency chains, we remove functions and
data that are unreachable by the entry point or exported symbols.
In particular, the macOS linker is used with "-dead_strip".

While calc on macOS will execute if linker used with "-dead_strip_dylibs"
and CUSTOM is defined, other applications that use libcalc but not
libcustcalc (such as sample_many and sample_rand) will fail to execute
due to missile symbols.  Therefore "-dead_strip_dylibs" is not used
by default when ALLOW_CUSTOM is "-DCUSTOM" under macOS.
2023-08-14 17:08:28 -07:00
Landon Curt Noll
af9b052fe9 fixed -dead_strip_dylibs for macOS, fixed macOS lib version numbers
Added Makefile variable ${VER} to holdthe calc major release version.
The calc major release version is a 3 level version (x.y.z).

Under macOS, the current version of both libcalc and
libcustcalc are set to the current calc major release version.

Under macOS, to reduce dependency chains, we remove functions and
data that are unreachable by the entry point or exported symbols.
In particular, the linker is run with "-dead_strip" and with
"-dead_strip_dylibs".
2023-08-14 15:27:22 -07:00
Landon Curt Noll
40f8654aa4 fix use of -dead_strip_dylibs for macOS linker 2023-08-14 14:58:22 -07:00
Landon Curt Noll
92c8d89ed1 cleanup Makefile comments 2023-08-14 05:02:48 -07:00
Landon Curt Noll
1e2d02e449 changed macOS to not use "-dead_strip_dylibs"
The macOS ld documentation states that option should not be used
when linking against a dylib which is required at runtime for some
indirect reason such as the dylib has an important initializer.
The libcustcalc appears to have such an initializer.
2023-08-14 04:28:59 -07:00
Landon Curt Noll
e0df1646fc add -dead_strip_dylibs by default to the macOS linker
Under macOS, to reduce dependency chains, we remove functions and
data that are unreachable by the entry point or exported symbols.
In particular, the linker is run with "-dead_strip" and with
"-dead_strip_dylibs".
2023-08-14 04:11:33 -07:00
Landon Curt Noll
ee900ec6ec improve macOS shared library building and use by calc
Dropped the use of Makefile variable ${SET_INSTALL_NAME}.
Under macOS it was always needed, elsewhere it was not.

Under macOS, the current version of both libcalc and
libcustcalc are set to the current calc release version.

Under macOS, to reduce dependency chains, we remove functions and
data that are unreachable by the entry point or exported symbols.
In particular, the linker is run with "-dead_strip".
2023-08-14 03:27:17 -07:00
Landon Curt Noll
6ee34e709d fix calc when CUSTOM is undefined, remove PASSDOWN values
Removed the ${CAL_PASSDOWN}, ${HELP_PASSDOWN}, ${HELP_PASSDOWN},
${CSCRIPT_PASSDOWN} Makefile variables as the new Makefile
include files keep Makefile variables in sync.

Fixed the ability of calc to compile when CUSTOM is undefined
(i.e., -UCUSTOM).  The libcustcalc is always built, regardless
of the $(ALLOW_CUSTOM} Makefile variable.  However when CUSTOM
is undefined, the bulk of custom functions are not defined.
2023-08-14 01:26:52 -07:00
Landon Curt Noll
f81d67b322 add missing edits to cscript/Makefile 2023-08-13 23:48:50 -07:00
Landon Curt Noll
21ab25d1c9 add Makefile.config, change all Makefile includes
Moved makefile variables that configure calc and configure how to
compile calc from Makefile into a new Makefile.config file.

The Makeifle includes the Makefile.config file.
The cal/Makeifle includes the Makefile.config file.
The cscript/Makeifle includes the Makefile.config file.
The custom/Makeifle includes the Makefile.config file.
The help/Makeifle includes the Makefile.config file.

Now, the Makefile.config file will consistently configure
calc and how calc is compiled and built by all calc Makefiles.

The platform target section from the old Makefile has been moved to
a new file, Makefile.target.  The custom/Makefile no longer includes
Makefile.

The Makeifle includes the Makefile.target file.
The cal/Makeifle includes the Makefile.target file.
The cscript/Makeifle includes the Makefile.target file.
The custom/Makeifle includes the Makefile.target file.
The help/Makeifle includes the Makefile.target file.

Now, the Makefile.target file will consistently set
target information for all calc Makefiles.

The cal/Makeifle includes the Makefile.local file.
The cscript/Makeifle includes the Makefile.local file.
The custom/Makeifle includes the Makefile.local file.
The help/Makeifle includes the Makefile.local file.

Thus, one may modify or append many Makefile variables
in all calc Makefiles.
2023-08-13 23:40:33 -07:00
Landon Curt Noll
06dcb3e51e Release v2.14.3.1
IMPORTANT: This is just a test release.  Please do not use.
2023-08-13 21:09:51 -07:00
Landon Curt Noll
6e0e48e17e fixed trailing blank in HOWTO.INSTALL 2023-08-13 21:04:28 -07:00
Landon Curt Noll
f416973a31 remove Makefile.simple and add Makefile.target
Dropped support of Makefile.simple and custom/Makefile.simple.
The calc version 2.14.3.0 is the last release that supported
the Makefile.simple and custom/Makefile.simple files.
Now, a make that supports makefile conditional syntax is required.

The platform target section from the old Makefile has been moved
to a new file, Makefile.target.  The Makefile.target is shared
by both Makefile and custom/Makefile.  The custom/Makefile no
longer includes Makefile (instead it includes ../Makefile.target).
2023-08-13 20:48:06 -07:00
Landon Curt Noll
b408b59d8d checkpoint on ALLOW_CUSTOM use
Updated comments in Makefile.local for how to Diagnosing memory,
thread, and crash issues under RHEL and macOS.

We no longer support the Makefile variable ${ALLOW_CUSTOM} to be empty.
Normally ${ALLOW_CUSTOM} is:

    ALLOW_CUSTOM= -DCUSTOM

Now, to disable custom disable custom even if -C is given, use:

    ALLOW_CUSTOM="-UCUSTOM"

Added comments in Makefile.local for how to reduce dependency chains
under macOS.  XXX - this doesn't yet work so don't uncomment - XXX.
2023-08-13 16:17:10 -07:00
Landon Curt Noll
77405e1d84 fix macOS comment to reduce dependency chains under macOS 2023-08-12 16:18:15 -07:00
Landon Curt Noll
da623e13cb add Makefile.local comments for macOS reduce dependency chains 2023-08-12 16:14:11 -07:00
Landon Curt Noll
f025dcf0d8 update comments in Makefile.local about using -fsanitize 2023-08-12 16:02:31 -07:00
Landon Curt Noll
3bfcaae767 fix typo in CHANGES 2023-08-12 00:41:21 -07:00
Landon Curt Noll
bf5b56d263 fixed install of statically linked calc under macOS
Improved .gitignore to ignore .static, calc-static,
sample_many-static and sample_rand-static.

Improved error messages when trying to compile with
with one calc type (when BLD_TYPE=calc-dynamic-only or
BLD_TYPE=calc-static-only) and install with the other.

When installing with BLD_TYPE=calc-static-only, the
installed calc and calc-static are links to each other.
Thanks to GitHub user @urtleWilly for this suggestion.

The dynamic shared libraries are not installed if they are not
built.  So when installing with BLD_TYPE=calc-static-only, the
install rule will not attempt to install dynamic shared libraries.
Thanks to GitHub user @urtleWilly for bringing to our attention,
problems related to building a statically linked calc under macOS.
2023-08-12 00:28:53 -07:00
Landon Curt Noll
0b044ce972 Fix typo in the make debug Makefile rule. 2023-08-03 14:11:35 -07:00
Landon Curt Noll
e2686911ae Release v2.14.3.0
The following are the changes in this release:

    Updated COPYING to include the actual text of "The Unlicense".
    Made minor formatting changes to the file.

    The Darwin specific ${DARWIN_ARCH}, thay by default was unset,
    is now the ${ARCH_CFLAGS} Makefile variable.  Comments about
    various "-arch name" have been moved to the ${ARCH_CFLAGS} area.

    For old Apple Power PC systems, the following is added:

	COMMON_CFLAGS+= -std=gnu99
	COMMON_LDFLAGS+= -std=gnu99
	ARCH_CFLAGS+= -arch ppc

    Old Apple Power PC systems should be detected by the
    "uname -p" command returning "powerpc".  One may force the
    Power PC mode by adding to the end of any make command:

	make ...make_args... target=Darwin arch=powerpc

    or by adding the following in the Makefile.local file:

	target= Darwin
	arch= powerpc

    Improved the output of the calcinfo rule by adding echos
    of various uname values as well as some top Makefile variables.

    Fixed the BUGS file with respect to using `make debug`.

    Added a final ls of `debug.out` for `make debug`.
2023-08-02 16:09:00 -07:00
Landon Curt Noll
544b873914 document changes to make debug 2023-08-02 15:29:23 -07:00
Landon Curt Noll
948d9e807b minor wording change about make debug 2023-08-02 01:12:11 -07:00
Landon Curt Noll
6d020b7fbe fix PowerPC detection under Darwin
Test if the arch value (`uname -p`) is "powerpc".

PowerPC based systems no longer try to use xcrun to determine where
things like INCDIR (include files) are located.
2023-08-02 00:40:53 -07:00
Landon Curt Noll
9fcdd80549 update fnv_tool.cal about no FNV primes for some sizes.
FNV primes for bit size powers of 2  > 1024 are extremely rare.
There are no FNV primes for bit size powers of 2 >= 2048 and <= 1048576.
2023-07-31 13:35:50 -07:00
Landon Curt Noll
3148ce06a0 improve how Apple Power PC systems compile, improve make calcinfo 2023-07-30 02:57:48 -07:00
Landon Curt Noll
945977f1f4 Updated COPYING to include the "The Unlicense" text. 2023-07-30 00:24:52 -07:00
Landon Curt Noll
b03e71f0ce Release v2.14.2.2
The following are the changes in this release:

    Removed references to obsolete Email addresses.

    macOS Darwin defaults LCC to "cc".
2023-07-28 21:33:59 -07:00
Landon Curt Noll
db799aac10 changed macOS Darwin to default LCC to "cc" 2023-07-28 21:19:02 -07:00
Landon Curt Noll
adecf7d76e Remove references to obsolete Email addresses. 2023-07-28 10:08:40 -07:00
Landon Curt Noll
94bf264088 minor speed change to fnv_tool.cal
Also note that 2^19 bits does not have a FNV prime.
2023-07-26 15:47:19 -07:00
Landon Curt Noll
80e841eded Release v2.14.2.1
The following are the changes in this release:

    Added cal/fnv_tool.cal, a calc resource file defining:

	find_fnv_prime(bits)
	deprecated_fnv0(bits,fnv_prime,string)
	fnv_offset_basis(bits,fnv_prime)
	fnv1a_style_hash(bits,fnv_prime,prev_hash,string)

    Fixed sorted order of cal/README.
2023-07-25 23:09:39 -07:00
Landon Curt Noll
3f78fc20d7 fix make picky errors found in cal/fnv_tool.cal 2023-07-25 23:06:11 -07:00
Landon Curt Noll
c26460b255 add cal/fnv_tool.cal
Added cal/fnv_tool.cal, a calc resource file defining:

    find_fnv_prime(bits)
    deprecated_fnv0(bits,fnv_prime,string)
    fnv_offset_basis(bits,fnv_prime)
    fnv1a_style_hash(bits,fnv_prime,prev_hash,string)

Fixed sorted order of cal/README.
2023-07-25 22:58:58 -07:00
Landon Curt Noll
3ec7b39366 Release v2.14.2.0
The following are the changes in this release:

    Ported calc to the s390x IBM Mainframe running RHEL9.1.

    Added cal/splitbits.cal:

	splitbits(x, b)

	Given an integer x, split the value into a list of integers,
	each of which is at most b bits long.

	The value b must be an integer > 0.

	The number of elements in the returned list is:

	    ceil((highbit(x) + 1) / b)

	If x == 0, then a list of 1 element containing 0 is returned.

	If x < 0, then the two's compliment of abs(x) is returned.
	Even though calc represents negative integers as positive values
	with sign bit, the bits returned by this function are as if
	the integer converted as if the integer was a two's compliment value.

	See also the help command:

	    ; help resource
2023-07-21 23:22:20 -07:00
Landon Curt Noll
49c599aec9 updated via git commit 2023-07-21 23:05:23 -07:00
Landon Curt Noll
a582511002 updated with make depend 2023-07-21 23:04:09 -07:00
Landon Curt Noll
e05d904821 add cal/splitbits.cal 2023-07-21 23:02:51 -07:00
Landon Curt Noll
ccd579ecda ported calc to the s390x IBM Mainframe running RHEL9.1 2023-07-21 22:38:17 -07:00
Landon Curt Noll
15be1dec4d fix typos from previous commit
TL;DR :-)
2023-07-20 16:48:06 -07:00
Landon Curt Noll
f34c659877 expand on top section of README.md
Added TL;DR section at the top along the lines of pull request #80.
We expanded it to include a number of other common systems.
2023-07-20 16:44:39 -07:00
Landon Curt Noll
2ad27e7909 Merge pull request #80 from john-peterson/patch-1
Print usage on top
2023-07-20 16:33:56 -07:00
John Sebastian Peterson
a4d3c8ff9d Print usage on top
It's common practice nowadays to out this on the very top

A text that can be copied to the terminal an "it just works"

Will bring many back to the roots of computers after over commercialisation of the over hyped "desktop experience" of the 90s
2023-07-20 06:35:10 +02:00
Landon Curt Noll
bd64a6cc36 Release v2.14.1.6
The following are the changes in this release:

    Fixed version numbers in two cases in CHANGES that referred
    to the 2.14.2.x instead of 2.14.1.x.

    Rename MINGW Makefile variable (a holdover from MINGW32_NT-5.0)
    to OSNAME.

    Fixed FUNCPTR typedef in hist.c to fix deprecated compiler warnings.

    Fixed when USE_READLINE, READLINE_LIB, READLINE_EXTRAS, and
    READLINE_INCLUDE are set to empty (disable use of the GNU-readline
    facility).

    Fix cases of spaces before tabs in Makefile and Makefile.simple.

    Fixed obsolete references to the atoz() in LIBRARY to use the
    correct internal function name of str2z().

    Fixed obsolete references to the atoq() in LIBRARY to use the
    correct internal function name of str2q().

    Document in help/unexpected that * operator has has a higher
    precedence than << in calc, which differs from C.  Thanks
    goes to GitHub user @inguin for pointing put this difference.
2023-05-31 18:55:56 -07:00
Landon Curt Noll
e2b2976d18 document that * operator has has a higher precedence than << 2023-05-31 18:30:26 -07:00
Landon Curt Noll
3ea51ea937 Corrected LIBRARY to refer to str2z() and str2()
Fixed obsolete references to the atoz() in LIBRARY to use the
correct internal function name of str2z().

Fixed obsolete references to the atoq() in LIBRARY to use the
correct internal function name of str2q().
2023-05-31 18:22:09 -07:00
Landon Curt Noll
5fa732b869 Release v2.14.1.5
The following are the changes in this release:

    Fixed version numbers in two cases in CHANGES that referred
    to the 2.14.2.x instead of 2.14.1.x.

    Rename MINGW Makefile variable (a holdover from MINGW32_NT-5.0)
    to OSNAME.

    Fixed FUNCPTR typedef in hist.c to fix deprecated compiler warnings.

    Fixed when USE_READLINE, READLINE_LIB, READLINE_EXTRAS, and
    READLINE_INCLUDE are set to empty (disable use of the GNU-readline
    facility).

    Fix cases of spaces before tabs in Makefile and Makefile.simple.
2023-03-12 20:52:45 -07:00
Landon Curt Noll
6a54caf1c2 Fixed when disabling use of the GNU-readline facility
Fixed FUNCPTR typedef in hist.c to fix deprecated compiler warnings.

Fixed when USE_READLINE, READLINE_LIB, READLINE_EXTRAS, and
READLINE_INCLUDE are set to empty (disable use of the GNU-readline
facility).

Fix cases of spaces before tabs in Makefile and Makefile.simple.
2023-03-12 19:27:11 -07:00
Landon Curt Noll
cce930987b improve hist.c FUNCPTR type to use in arg 2023-03-12 18:16:36 -07:00
Landon Curt Noll
7c806f13ea Fixed FUNCPTR typedef in hist.c to fix deprecated compiler warnings 2023-03-12 18:10:38 -07:00
Landon Curt Noll
616bcd8d46 rename MINGW to OSNAME in Makefile
Rename MINGW Makefile variable (a holdover from MINGW32_NT-5.0)
to OSNAME.

Fixed some incorrect version number comments in CHANGES.
2023-03-11 01:05:01 -08:00
Landon Curt Noll
36a1a042f3 fix warnings while forming builtin list 2023-03-06 04:17:31 -08:00
Landon Curt Noll
75159fcbc2 Release v2.14.1.4
The following are the changes in this release:

    Updated COPYING file to indicate that these files are now
    covered under "The Unlicense" (see https://unlicense.org):

	    sha1.c
	    sha1.h
	    cal/dotest.cal
	    cal/screen.cal

    Updated help/credit to match the above changes to COPYING.

    Updated CONTRIB-CODE and calc.man to refer to using GitHub pull requests
    for contributing to calc (instead of using Email).

    Updated BUGS and calc.man to refer to using GitHub issues
    for reporting calc bugs (instead of using Email).

    Updated QUESTIONS and calc.man to refer to using GitHub issues
    for asking calc questions (instead of using Email).

    Fixed Makefile.local command example to refer to overriding the
    Makefile variable DEBUG (instead of CDEBUG).

    Fixed all make chk ASAN warnings under macOS 13.2.1 when calc is compiled
    with the following uncommented lines in Makefile.local:

	DEBUG:= -O0 -g
	CFLAGS+= -fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined
	LDFLAGS+= -fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined
	CALC_ENV+= ASAN_OPTIONS=detect_stack_use_after_return=1

    Improved how pointers to functions are declared for the builtins
    array in func.c to avoid function declarations without a prototype
    that is now deprecated in C.

    Improved how pointers to functions are declared for the opcodes
    array in opcodes.c to avoid function declarations without a prototype

    Replaced use of egrep with grep -E in Makefiles.

    Fixed cases where variables were set but not used in symbol.c, calc.c,
    and the main function in func.c as used by funclist.c.

    Added rule name to "DO NOT EDIT -- generated by the Makefile" lines
    in constructed files.

    Test if <sys/vfs.h> exists and set HAVE_SYS_VFS_H accordingly
    in have_sys_vfs.h.  Added HAVE_SYS_VFS_H to allow one to force
    this value.

    Test if <sys/param.h> exists and set HAVE_SYS_PARAM_H accordingly
    in have_sys_param.h.  Added HAVE_SYS_PARAM_H to allow one to force
    this value.

    Test if <sys/mount.h> exists and set HAVE_SYS_MOUNT_H accordingly
    in have_sys_mount.h.  Added HAVE_SYS_MOUNT_H to allow one to force
    this value.

    Test if the system as the statfs() system call and set HAVE_STATFS
    accordingly in have_statfs.h.  Added HAVE_STATFS to allow one
    to force this value.

    The pseudo_seed() function will also try to call statfs() if
    possible and permitted by the HAVE_STATFS value.

    Test if makedepend command is available before trying to build
    the Makefile dependency list via "make depend".
2023-03-06 03:45:03 -08:00
Landon Curt Noll
8ef7b5311e fix make depend 2023-03-06 03:39:40 -08:00
Landon Curt Noll
d5a11b3df4 update via make depend 2023-03-06 03:10:22 -08:00
Landon Curt Noll
74c299ad4e minor improvements to the calc man page 2023-03-06 02:49:47 -08:00
Landon Curt Noll
d89ea78104 prep for calc version 2.14.1.4
Updated COPYING file to indicate that these files are now
covered under "The Unlicense" (see https://unlicense.org):

	sha1.c
	sha1.h
	cal/dotest.cal
	cal/screen.cal

Updated help/credit to match the above changes to COPYING.

Updated CONTRIB-CODE and calc.man to refer to using GitHub pull requests
for contributing to calc (instead of using Email).

Updated BUGS and calc.man to refer to using GitHub issues
for reporting calc bugs (instead of using Email).

Updated QUESTIONS and calc.man to refer to using GitHub issues
for asking calc questions (instead of using Email).

Fixed Makefile.local command example to refer to overriding the
Makefile variable DEBUG (instead of CDEBUG).

Fixed all make chk ASAN warnings under macOS 13.2.1 when calc is compiled
with the following uncommented lines in Makefile.local:

    DEBUG:= -O0 -g
    CFLAGS+= -fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined
    LDFLAGS+= -fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined
    CALC_ENV+= ASAN_OPTIONS=detect_stack_use_after_return=1

Improved how pointers to functions are declared for the builtins
array in func.c to avoid function declarations without a prototype
that is now deprecated in C.

Improved how pointers to functions are declared for the opcodes
array in opcodes.c to avoid function declarations without a prototype

Replaced use of egrep with grep -E in Makefiles.

Fixed cases where variables were set but not used in symbol.c, calc.c,
and the main function in func.c as used by funclist.c.

Added rule name to "DO NOT EDIT -- generated by the Makefile" lines
in constructed files.

Test if <sys/vfs.h> exists and set HAVE_SYS_VFS_H accordingly
in have_sys_vfs.h.  Added HAVE_SYS_VFS_H to allow one to force
this value.

Test if <sys/param.h> exists and set HAVE_SYS_PARAM_H accordingly
in have_sys_param.h.  Added HAVE_SYS_PARAM_H to allow one to force
this value.

Test if <sys/mount.h> exists and set HAVE_SYS_MOUNT_H accordingly
in have_sys_mount.h.  Added HAVE_SYS_MOUNT_H to allow one to force
this value.

Test if the system as the statfs() system call and set HAVE_STATFS
accordingly in have_statfs.h.  Added HAVE_STATFS to allow one
to force this value.

The pseudo_seed() function will also try to call statfs() if
possible and permitted by the HAVE_STATFS value.
2023-03-06 02:17:40 -08:00
Landon Curt Noll
644b348bcb minor Makefile changes
Changes #! lines in Makefiles to "#!/usr/bin/env make".

Set SHELL in Makefiles to the basename of the shell.
2023-02-16 16:47:01 -08:00
Landon Curt Noll
11ddc30528 Release v2.14.1.3
The following are the changes in this release:

    Fixed missing <string.h include in have_fpos_pos.c.

    Change calc version from 2.14.1.2 to 2.14.2.3 as part of a test to
    build calc RPMs on a reference RHEL8.7 platform (formerly a RHEL7.9
    platform).
2023-02-14 15:49:05 -08:00
Landon Curt Noll
f5fc06fbd4 update make depend 2023-02-14 15:42:57 -08:00
Landon Curt Noll
8a4c12d2be add missing have_fpos_pos.c fix to CHANGES 2023-02-14 15:41:11 -08:00
Landon Curt Noll
d2139064cb Merge branch 'master' of github.com:lcn2/calc 2023-02-14 15:39:53 -08:00
Landon Curt Noll
774060944b prep for calc version 2.14.1.3
Change calc version from 2.14.1.2 to 2.14.2.3 as part of a test to
build calc RPMs on a reference RHEL8.7 platform (formerly a RHEL7.9
platform).
2023-02-14 15:39:11 -08:00
Landon Curt Noll
61c268f1c2 Merge pull request #68 from fweimer-rh/c99
Avoid implicit declaration memset in have_fpos_pos.c probe
2023-01-21 19:36:01 -08:00
Florian Weimer
dcf360d688 Avoid implicit declaration memset in have_fpos_pos.c probe
Otherwise, the probe result changes with compilers which do not
support implicit function declarations, a language feature that
was removed from C in 1999.
2023-01-18 10:54:55 +01:00
Landon Curt Noll
fddd24d6c6 Update CodeQL Action to v2
See: https://github.blog/changelog/2022-04-27-code-scanning-deprecation-of-codeql-action-v1/
2022-12-08 14:40:03 -08:00
Landon Curt Noll
bcae90959e Enable Dependabot version updateo
See also: https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabots
2022-12-08 14:36:15 -08:00
Landon Curt Noll
5b42c557b0 Add missing copyright example to COPYING 2022-12-08 14:29:01 -08:00
Landon Curt Noll
1b0e6c4462 Improve README.WINDOWS
Expand on the notes made by GitHub user @Leoongithub.

Re-order a few README.WINDOWS sections.

Add a number of 'NOTE:" notes to README.WINDOWS.
2022-12-08 14:11:04 -08:00
Landon Curt Noll
f0396fccde Merge pull request #67 from Leoongithub/patch-1
Update latest information about compile under Windows
2022-12-08 13:21:17 -08:00
Leoongithub
21be7adb82 Fix Cygwin compile error 2022-12-07 18:14:11 +08:00
Leoongithub
6317991f2b Update README.WINDOWS 2022-12-07 18:08:44 +08:00
Landon Curt Noll
f4f19f21dc Add config("complex_space") to control spaces around + or - in complex values
Added config("fraction_space", boolean) to help/config, along with
a few few minor text improvements.  Updated cal/regress to test
config("tilde_space").

Added config("complex_space", boolean).  The "complex_space" controls
whether or not a space (' ') is printed before and after the + or -
in complex values.

By default, config("complex_space") is false.

For example, with the default, config("complex_space", 0):

    ; asin(2)
	    1.57079632679489661923-1.31695789692481670863i

With config("complex_space", 1):

    ; asin(2)
	    1.57079632679489661923 - 1.31695789692481670863i

NOTE: Use of config("complex_space", 1) can break printing and scanning
      of fractional values via "%r".

NOTE: Use of config("complex_space", 1) can break printing and scanning
      of complex values via "%c".

Added config("complex_space", boolean) to help/config, along with
a few few minor text improvements.  Updated cal/regress to test
config("complex_space").
2022-12-04 00:53:15 -08:00
Landon Curt Noll
348f3ed427 Clarified -a and -f in calc man page
Clarify in the calc man page, the relationship between -q and
calc start scripts such as the ~/.calcrc file.

Fixed in the calc man page, the issue of -f not implying -q.
2022-12-03 16:36:46 -08:00
Landon Curt Noll
542a263de6 Improve show config and help config order 2022-12-03 16:09:03 -08:00
Landon Curt Noll
17702a4799 Add config("fraction_space") to control spaces around printing fractions
Added config("tilde_space", boolean) to help/config, along with
a few few minor text improvements.  Updated cal/regress to test
config("tilde_space").

Added config("fraction_space", boolean).  The "fraction_space" controls
whether or not a space (' ') is printed before and after fractions.
By default, config("fraction_space") is false.

For example, with the default, config("fraction_space", 0):

    ; base(1/3),
    ; 1/7
            1/7

With config("fraction_space", 1):

    ; base(1/3),
    ; 1/7
            1 / 7

NOTE: Use of config("fraction_space", 1) can break printing and scanning
      of fractional values via "%r".

NOTE: Use of config("fraction_space", 1) can break printing and scanning
      of complex values via "%c".

Added config("fraction_space", boolean) to help/config, along with
a few few minor text improvements.  Updated cal/regress to test
config("tilde_space").
2022-12-03 14:39:25 -08:00
Landon Curt Noll
7c6723db88 Change tilde_space to be 0 by default 2022-12-03 14:02:49 -08:00
Landon Curt Noll
0d99ba54d8 Change default to print space after the approximation tilde
Added config("tilde_space", boolean).  The "tilde_space" controls
whether or not a space (' ') is printed after leading tilde ('~').
By default, config("tilde_space") is true, which is a change
from past behavior.  For example, now:

    ; 1/3
	    ~ 0.33333333333333333333

With config("tilde_space", 0):

    ; 1/3
	    ~0.33333333333333333333

To disable "tilde_space", use config("tilde_space", 0) on the
command line and/or use config("tilde_space", 0),; in your ~/.calcrc.
Thanks goes to <GitHub use ljramalho> for this suggestion.

Added config("tilde_space", boolean) to help/config, along with
a few few minor text improvements.  Updated cal/regress to test
config("tilde_space") and to account for the new default.
2022-12-03 12:22:55 -08:00
Landon Curt Noll
83adfaa720 Removed compiler confusing setjmp() call
In pseudo_seed(), we removed a call to setjmp() that was only
there to add more information to mix into the seed.  For compilers
such as gcc that used -Wclobbered, the call to setjmp() gave the
impression that the hash_val might be clobbered by a longjmp().
Where there is no longjmp() that would use the previous setjmp(),
the gcc compiler has nil ways to notice that. So to avoid confusion
we removed the setjmp() call.  Thanks to <GitHub user mattdm> for
raising this potential concern.
2022-12-03 10:47:05 -08:00
Landon Curt Noll
ef6a30c9c9 Fixed how the original TTY state is preserved
In find_tty_state(), we changed how we expand fd_orig as an original
pre-modified copy of fd_setup.  We realloc the fd_orig array and copy
the fd_setup into it first, before touching the fd_setup array.
2022-12-03 10:25:43 -08:00
Landon Curt Noll
3aaad95443 Fixed a use after free bug
Fixed a -Wuse-after-free warning that identified a call to realloc() in
find_tty_state() could move the fd_setup array.  Thanks goes to <GitHub
user mattdm> for reporting this bug!
2022-12-03 10:10:21 -08:00
Landon Curt Noll
74b833977b Use calloc in swap_HALF_in_ZVALUE() to help with compiler paranoia 2022-12-03 09:34:32 -08:00
Landon Curt Noll
333f0c4332 Add a Makefile comment about how to turn on all messages 2022-12-03 09:33:15 -08:00
Landon Curt Noll
d91ace6091 Release v2.14.1.2
The following are the changes in this release:

    Restored use of the #define FPOS_POS_LEN symbol.  This refers to
    the length of the __pos element (if the __pos element exists),
    the fpos_t type (if that type exists).

    Changed SWAP_HALF_IN_FILEPOS(dest, src) mato to use FILEPOS_LEN Little
    Endian when FILEPOS is a simple scalar type (i.e., HAVE_FILEPOS_SCALAR
    is defined).

    Changed #define HAVE_FPOS to HAVE_FGETSETPOS.

    Corrected comment in have_fpos_pos.h.  The HAVE_FPOS_POS symbol was
    NOT related to fgetpos & fsetpos but rather if we we have an __pos
    element in FILEPOS.

    Changed #define HAVE_NO_FPOS to HAVE_NO_FGETSETPOS.

    Improved comments in have_fpos_pos.h to show why and how
    HAVE_FPOS_POS, FPOS_POS_BITS, and FPOS_POS_LEN were defined or undefed.

    Changed showfiles builtin to print sizes cast to (long int) with
    the "%ld" printf format to avoid implementations that do not support
    the "%lld" printf format specifier.

    Renamed have_fpos.h to have_fgetsetpos.h.  Renamed CALC_HAVE_FPOS_H
    to CALC_HAVE_FGETSETPOS_H.  The make install and the olduninstall
    rules remove the any old have_fpos.h that was previously installed.

    Added swap_HALFs(dest, src, len) function to byteswap.c.

    Calc can now handle Big Engian file position sizes that are a
    multiple of BASEB bits in length.  Before handle Big Engian file
    positions could only be 32 and 64 bits in length.  This will allow,
    for example, a Big Engian file position size of 128 (assuming that
    128/BASEB is is an integer).

    Temporary workaround for musl libc systems such as gentoo Linux that
    allows them to compile calc and successfully run the regression test.
2022-11-29 13:10:33 -08:00
Landon Curt Noll
49c6a8218c Release calc v2.14.1.2
Restored use of the #define FPOS_POS_LEN symbol.  This refers to
the length of the __pos element (if the __pos element exists),
the fpos_t type (if that type exists).

Changed SWAP_HALF_IN_FILEPOS(dest, src) mato to use FILEPOS_LEN Little
Endian when FILEPOS is a simple scalar type (i.e., HAVE_FILEPOS_SCALAR
is defined).

Changed #define HAVE_FPOS to HAVE_FGETSETPOS.

Corrected comment in have_fpos_pos.h.  The HAVE_FPOS_POS symbol was
NOT related to fgetpos & fsetpos but rather if we we have an __pos
element in FILEPOS.

Changed #define HAVE_NO_FPOS to HAVE_NO_FGETSETPOS.

Improved comments in have_fpos_pos.h to show why and how
HAVE_FPOS_POS, FPOS_POS_BITS, and FPOS_POS_LEN were defined or
undefed.

Changed showfiles builtin to print sizes cast to (long int) with
the "%ld" printf format to avoid implementations that do not support
the "%lld" printf format specifier.

Renamed have_fpos.h to have_fgetsetpos.h.  Renamed CALC_HAVE_FPOS_H
to CALC_HAVE_FGETSETPOS_H.  The make install and the olduninstall
rules remove the any old have_fpos.h that was previously installed.

Added swap_HALFs(dest, src, len) function to byteswap.c.

Calc can now handle Big Engian file position sizes that are a
multiple of BASEB bits in length.  Before handle Big Engian file
positions could only be 32 and 64 bits in length.  This will allow,
for example, a Big Engian file position size of 128 (assuming that
128/BASEB is is an integer).

Temporary workaround for musl libc systems such as gentoo Linux that
allows them to compile calc and successfully run the regression
test.
2022-11-29 13:04:00 -08:00
Landon Curt Noll
def203f273 Release calc v2.14.1.2 2022-11-29 12:59:36 -08:00
Landon Curt Noll
5b2983f421 Improve format of SWAP_HALF_IN_FILEPOS in fposval.h 2022-11-28 15:24:31 -08:00
Landon Curt Noll
e6fc1a92a9 Improve file position handling on Big Engian machines
Added swap_HALFs(dest, src, len) function to byteswap.c.

Calc can now handle Big Engian file position sizes that are a
multiple of BASEB bits in length.  Before handle Big Engian file
positions could only be 32 and 64 bits in length.  This will allow,
for example, a Big Engian file position size of 128 (assuming that
128/BASEB is is an integer).
2022-11-28 15:13:16 -08:00
Landon Curt Noll
3e084d9fb9 Rename have_fpos.h to have_fgetsetpos.h
Renamed have_fpos.h to have_fgetsetpos.h.

Renamed CALC_HAVE_FPOS_H to CALC_HAVE_FGETSETPOS_H.
2022-11-28 14:07:47 -08:00
Landon Curt Noll
340c1990ce Checkpoint on fixing compiling with musl gentoo
Restored use of the #define FPOS_POS_LEN symbol.  This refers to the
length of the __pos element (if the __pos element exists), the fpos_t type
(if that type exists).

Changed SWAP_HALF_IN_FILEPOS(dest, src) mato to use FILEPOS_LEN Little
Endian when FILEPOS is a simple scalar type (i.e., HAVE_FILEPOS_SCALAR
is defined).

Changed #define HAVE_FPOS to HAVE_FGETSETPOS.

Corrected comment in have_fpos_pos.h.  The HAVE_FPOS_POS symbol was NOT
related to fgetpos & fsetpos but rather if we we have an __pos element
in FILEPOS.

Changed #define HAVE_NO_FPOS to HAVE_NO_FGETSETPOS.

Improved comments in have_fpos_pos.h to show why and how HAVE_FPOS_POS,
FPOS_POS_BITS, and FPOS_POS_LEN were defined or undefed.

Changed showfiles builtin to print sizes cast to (long int) with the
"%ld" printf format to avoid implementations that do not support the
"%lld" printf format specifier.
2022-11-28 12:55:29 -08:00
Landon Curt Noll
5acd67c704 Updated calc bug report template version: 1.3 2022-11-27 2022-11-27 19:07:54 -08:00
Landon Curt Noll
083011c9e3 Changed full_debug rule to not stop on sub-task error 2022-11-27 19:01:15 -08:00
Landon Curt Noll
dce2c6f0ee Improve the make debug rule
Added full_debug rule to Makefile.  This does the work of the
old debug rule in a more verbose mode by using Q= H=@ S= E= V=@.

The debug rule in the Makefile now pre-removes debug.out and then
runs make full_debug sending stdout and stderr to debug.out.  It then
prints a few instructions about filing a GitHub issue bug report.
2022-11-27 18:45:58 -08:00
Landon Curt Noll
827988c553 Fixed FILEPOS_LEN symbol and macro problems 2022-11-27 17:05:49 -08:00
Landon Curt Noll
25dcd8cb80 Release v2.14.1.1
The following are the changes in this release:

    Added a few remarks on calc version numbers to version.c.

    Fixed how fposval.h is built.  On a number of systems, the fposval.c
    file failed to compile incorrectly.  This caused problems for systems in
    which fposval.h.def was not correct.

    Fixed how have_memmv.h is built.  On a number of systems, the have_memmv.c
    file failed to compile incorrectly, producing a potentially incorrect
    have_memmv.h file for such systems.

    Fixed how align32.h is built.  On a number of systems, the align32.c
    file failed to compile incorrectly, producing a potentially incorrect
    align32.h file for such systems.

    Fixed how have_newstr.h is built.  On a number of systems, the have_newstr.c
    failed to compile incorrectly, producing a potentially incorrect
    have_newstr.h file for such systems.

    Fixed how have_strdup.h is built.  On a number of systems, the have_strdup.c
    file failed to compile incorrectly, producing a potentially incorrect
    have_strdup.h file for such systems.

    Fixed how have_strlcat.h is built.  On a number of systems, the have_strlcat.c
    file failed to compile incorrectly, producing a potentially incorrect
    have_strlcat.h file for such systems.

    Fixed how have_strlcpy.h is built.  On a number of systems, the have_strlcpy.c
    file failed to compile incorrectly, producing a potentially incorrect
    have_strlcpy.h file for such systems.

    Fixed how have_uid_t.h is built.  On a number of systems, the have_uid_t.c
    file failed to compile incorrectly, producing a potentially incorrect
    have_uid_t.h file for such systems.

    Fixed how have_uid_t.h is built.  On a number of systems, the have_uid_t.c
    file failed to compile incorrectly, producing a potentially incorrect
    have_uid_t.h file for such systems.
2022-11-27 13:41:32 -08:00
Landon Curt Noll
3b3bfb3f74 Proposed changes for v2.14.1.1
Added a few remarks on calc version numbers to version.c.

Fixed how fposval.h is built.  On a number of systems, the fposval.c
file failed to compile incorrectly.  This caused problems for systems in
which fposval.h.def was not correct.

Fixed how have_memmv.h is built.  On a number of systems, the have_memmv.c
file failed to compile incorrectly, producing a potentially incorrect
have_memmv.h file for such systems.

Fixed how align32.h is built.  On a number of systems, the align32.c
file failed to compile incorrectly, producing a potentially incorrect
align32.h file for such systems.

Fixed how have_newstr.h is built.  On a number of systems, the have_newstr.c
failed to compile incorrectly, producing a potentially incorrect
have_newstr.h file for such systems.

Fixed how have_strdup.h is built.  On a number of systems, the have_strdup.c
file failed to compile incorrectly, producing a potentially incorrect
have_strdup.h file for such systems.

Fixed how have_strlcat.h is built.  On a number of systems, the have_strlcat.c
file failed to compile incorrectly, producing a potentially incorrect
have_strlcat.h file for such systems.

Fixed how have_strlcpy.h is built.  On a number of systems, the have_strlcpy.c
file failed to compile incorrectly, producing a potentially incorrect
have_strlcpy.h file for such systems.

Fixed how have_uid_t.h is built.  On a number of systems, the have_uid_t.c
file failed to compile incorrectly, producing a potentially incorrect
have_uid_t.h file for such systems.

Fixed how have_uid_t.h is built.  On a number of systems, the have_uid_t.c
file failed to compile incorrectly, producing a potentially incorrect
have_uid_t.h file for such systems.
2022-11-27 13:28:32 -08:00
Landon Curt Noll
3e4391e2af Fix another comment in comma.cal 2022-06-20 19:39:11 -07:00
Landon Curt Noll
cfc6a6669c Improve comments in comma.cal 2022-06-20 19:36:54 -07:00
Landon Curt Noll
fa457db3cd Fix more comments in cal/comma.cal 2022-06-20 19:30:45 -07:00
Landon Curt Noll
d08b958a15 Fix typo in comma.cal comment 2022-06-20 19:28:16 -07:00
Landon Curt Noll
5f28e5b851 Removed training newline from fprint_comma in comma.cal 2022-06-20 19:26:35 -07:00
Landon Curt Noll
8dc52a532a Fix comma.cal to avoid leading 0's and tilde's 2022-06-20 19:20:34 -07:00
Landon Curt Noll
6fc14730c0 Fix the forming of fraction part in comma.cal 2022-06-20 19:10:20 -07:00
Landon Curt Noll
b97093e58c Fix calc man page \-escape, add cal/comma.cal
Fixed a \-escape bug in calc(1) man page.

Added cal/comma.cal:

    Convert numbers into strings with 3-digit group and integer-fraction
    separators.

    If the value is an integer, the integer-fraction separator is not used.

    str_comma(x, [group, [decimal]])

	Convert x into a string.

	If group is given and is a string, group will be used as
	the 3-digit group separator, otherwise the default 3-digit
	group separator will be used.

	If decimal is given and is a string, group will be used as
	the integer-fraction separator, otherwise the default
	integer-fraction separator will be used.

	The decimal and group arguments are optional.

    set_default_group_separator(group)

	Change the default 3-digit group separator if group is a string,
	otherwise the default 3-digit group separator will not be
	changed.  Return the old 3-digit group separator.

    set_default_decimal_separator(decimal)

	Change the default 3-digit group separator if decimal is a
	string, otherwise the default integer-fraction separator
	will not be changed.  Return the old integer-fraction separator.

    print_comma(x, [group, [decimal]])

	Print the value produced by str_comma(x, [group, [decimal]])
	followed by a newline.

	If the str_comma() does not return a string, nothing is printed.

	The decimal and group arguments are optional.

	The value produced by str_comma() is returned.

    fprint_comma(fd, x, [group, [decimal]])

	Print the value produced by str_comma(x, [group, [decimal]]),
	without a trailing newline, on file fd.

	If the str_comma() does not return a string, nothing is printed.

	If fd is not an open file, nothing is printed.

	The decimal and group arguments are optional.

	The value produced by str_comma() is returned.
2022-06-20 18:25:12 -07:00
Landon Curt Noll
923c36e475 Remove excess whitespace under SECURITY.md 2022-04-08 00:24:42 -07:00
Landon Curt Noll
741ea46853 Release v2.14.1.0
The following are the changes from calc version 2.14.1.0 to date:

    Fixed alignment of show item section of help command.

    Bug fix: While 0^0 == 1, now for y > 0, 0^y == 0.
    Adjusted cal/test8900.cal to reflect this bug fix.
    Added tests to cal/regress.cal to help verify bug fix is fixed.
2022-04-08 00:02:44 -07:00
Landon Curt Noll
56b6613da8 Fixed 0^y for y > 0
While 0^0 == 1, now for y > 0, 0^y == 0.

Adjusted cal/test8900.cal to reflect the this bug fix.

Added tests to cal/regress.cal to help verify bug fix is fixed.
2022-04-07 23:54:06 -07:00
Landon Curt Noll
e9eef2dfa2 Merge branch 'master' of github.com:lcn2/calc 2022-04-07 23:44:38 -07:00
Landon Curt Noll
0dbf258696 Fixed alignment of show item section of help command 2022-04-07 23:44:05 -07:00
Landon Curt Noll
f6d558783a Improved security issue template
create a calc GitHub repo issue for a security issue
2022-02-24 13:58:56 -08:00
Landon Curt Noll
6f27a32f79 Calc bug report template version: 1.2 2022-02-24
Added template version and made a minor edit
2022-02-24 12:42:32 -08:00
Landon Curt Noll
d58f605866 Update issue templates
Updated calc Bug report
2022-02-24 12:30:36 -08:00
Landon Curt Noll
b83c5be515 Update issue templates
Add default GitHub Bug and Feature templates
2022-02-15 13:35:46 -08:00
Landon Curt Noll
561928a45c Checkpint disbale use of gettime() under _WIN32 or _WIN64 2022-02-12 13:52:06 -08:00
Landon Curt Noll
7f89af37f5 Checkpoint more Windows 11 Cygwin MINGW64 changes 2022-02-12 13:41:16 -08:00
Landon Curt Noll
4470f1f62e Checkpoint - Windows 11 with Cygwin and MinGW64 packages. 2022-02-12 12:44:32 -08:00
Landon Curt Noll
8217c49b94 Fix lack of quotes in PASSDOWN variables 2022-02-12 11:37:53 -08:00
Landon Curt Noll
d2cb03b4cc Add ${MSYS} to Makefile for Windows 11 MINGW64_NT users 2022-02-12 11:18:49 -08:00
Landon Curt Noll
80f13a4e45 Changed Makefiles as per make depend 2022-01-22 02:52:02 -08:00
Landon Curt Noll
1658343227 Changes to use attributes for noreturn and printf-like functions 2022-01-22 02:48:50 -08:00
Landon Curt Noll
3f177f2d81 Improved source code flow
Changed /*NOTREACHED*/ to not_reached(); and use "attribute.h".

Added .PHONY rule, just after all rule, to Makefiles.

Fixed an improper indentation issue.
2022-01-22 01:16:07 -08:00
Landon Curt Noll
dcd5a987af Added better examples of asan debugging use with gcc and clang 2022-01-13 11:11:32 -08:00
Landon Curt Noll
cb77888045 Expand certain table sizes, add comments to Makefile.local
Expanded the globalsymbol string table size: from 1024 to 65536.

    Expanded the how often to reallocate string table is performed:
    from 100 to 1024.

    Expanded the number env_pool elements to allocate at a time:
    from 10 to 256.

    Improve comments on Makefile.local and add a few more examples
    of how it might be used.
2022-01-02 18:01:21 -08:00
Landon Curt Noll
ce17b267be Minor changes to Makefile, HOWTO.INSTALL, CONTRIBUTING.md
Changed Makefile to set shell before setting the SHELL Makefile
    variable.

    Added text to HOWTO.INSTALL to help people with systems that
    lack the readline package.

    Trimmed long line in the CONTRIBUTING.md file.
2021-12-29 15:16:40 -08:00
Landon Curt Noll
738dd0334e Create CONTRIBUTING.md
Create initial CONTRIBUTING.md file.
2021-12-27 20:01:26 -08:00
Landon Curt Noll
7ba1dbdc65 Create CODE_OF_CONDUCT.md
Initial release of CODE_OF_CONDUCT.md
2021-12-27 19:56:02 -08:00
Landon Curt Noll
ee70c12481 Release v2.14.0.14
The following are the changes in this release:

    Fixed typo in Makefile.local comment.

    Established a tagging procedure for a production release.
    Production git tags will be of the form:

	prod-2.x.y.z
2021-12-27 19:10:56 -08:00
Landon Curt Noll
d4970d66ce Merge branch 'master' of github.com:lcn2/calc 2021-12-27 19:04:53 -08:00
Landon Curt Noll
c3ea3d28a4 Added 2.14.0.14 CHANGES 2021-12-27 19:04:08 -08:00
Landon Curt Noll
3fa34dabfe Fixed typo in comment for Makefile.local 2021-12-13 22:12:03 -08:00
Landon Curt Noll
ffd4422870 Release v2.14.0.13
We apologize for the calc v2.14.0.12 source tarball that was missing
critical files.  While the executable was well tested, our release
process was deficient.

We are improved our release process and added tests during the release
procedure to help verify that we are not regressing in to the
"v2.14.0.12 source tarball" issue, among other things.

Depending on how things do, you might is several releases come out over
a short period of time.  The core of calc isn't changing, so the calc
executable will be the same as we focus on the Makefiles, our release
procedure, and related documentation / help files.

Removed constructed help file that incorrectly added as a src file.

=-=

The following are the changes in this release:

    Made major changes to our release process in order to avoid
    missing critical files that happened in calc v2.4.0.12.

    Minor tweak to seed() builtin.  Updated help/srand and help/srandom.

    Moved Makefile.ship into Makefile.

    Removed custom/Makefile.head and custom/Makefile.tail.

    The custom/Makefile is now part of source and includes Makefile.
    In particular, custom/Makefile makes use of the 'middle' of
    the new top level Makefile where calc's top level Makefile
    variables are defined.

    Makefile.simple and custom/Makefile.simple are now part of the source
    and are constructed from Makefile and custom/Makefile respectively.
    The Makefile.simple and custom/Makefile.simple avoid using GNU
    conditionals. They may be used with older/classic make commands.

    Makefile.local will include comments about how to better use
    it. Between releases, Makefile.local at the top of the master branch
    will contain how we typically build calc and test calc (FYI: we
    normally enable things such as -Werror -Wextra -pedantic).  When we
    push out a release, Makefile.local will be stripped of non-comment
    lines.  Thus, releases of calc, and, released "calc*.src.rpm"
    files and the source tarballs, will have a Makefile.local with
    only comments.

    The "README.*" files and "HOWTO.INSTALL" file have been updated.

    By default, compiler warnings have been turned up.  The Makefile
    variable ${CCWARN} now defaults to:

	CCWARN= -Wall -Wextra -pedantic

    The previous level of compiler warnings can be easily restored by
    adding to Makefile.local:

	CCWARN:= -Wall

    The readline, history and ncurses libraries are now default.
    The Makefile variables ${USE_READLINE}, ${READLINE_LIB}, and
    ${READLINE_EXTRAS} now default to:

	USE_READLINE= -DUSE_READLINE
	READLINE_LIB= -lreadline
	READLINE_EXTRAS= -lhistory -lncurses

    The previous mode where readline, history and ncurses libraries
    were not compiled in by default can be easily restored by
    adding to Makefile.local:

	USE_READLINE:=
	READLINE_LIB:=
	READLINE_EXTRAS:=

    We have renamed "stable" as "production".
    We have renamed "unstable" as "tested".

    On the web site:

	http://www.isthe.com/chongo/src/calc/

    these files has been renamed:

	2.x.y.z_IS_LATEST_STABLE   ==> 2.x.y.z_IS_LATEST_PRODUCTION
	2.x.y.z_IS_LATEST_UNSTABLE ==> 2.x.y.z_IS_LATEST_TESTED

    The terms 'stable' and 'unstable' were both misleading and
    inaccurate.  For details see the new documention file:

	README.RELEASE

    See also the help command:

	; help release

    Fixed bug impacting how have_ustat.h was formed.

    Updated help/archive, BUGS, HOWTO.INSTALL to reflect GitHub use.
2021-12-13 17:41:35 -08:00
Landon Curt Noll
b5b2c3f812 Updated CHANGES to reflect recent commits 2021-12-13 17:00:01 -08:00
Landon Curt Noll
f7dadbf1f8 Improve how Makefiles are formed, updated related doc 2021-12-13 16:54:45 -08:00
Landon Curt Noll
22e123140c Fix to add missing Makefiles to distlist
The output of the distlist rule was used to form the source tarball.
2021-12-13 16:27:37 -08:00
Landon Curt Noll
1242700601 Fix how Makefile.simple and custom/Makefile.simple are formed 2021-12-13 16:11:38 -08:00
Landon Curt Noll
5b7dfeaf11 Release v2.14.0.13
We apologize for the calc v2.14.0.12 source tarball that was missing
critical files.  While the executable was well tested, our release
process was deficient.

We are improved our release process and added tests during the release
procedure to help verify that we are not regressing in to the "v2.14.0.12
source tarball" issue, among other things.

Depending on how things do, you might is several releases come out over
a short period of time.  The core of calc isn't changing, so the calc
executable will be the same as we focus on the Makefiles, our release
procedure, and related documentation / help files.

Removed constructed help file that incorrectly added as a src file.

=-=

The following are the changes in this release:

    Minor tweak to seed() builtin.  Updated help/srand and help/srandom.

    Moved Makefile.ship into Makefile.

    Removed custom/Makefile.head and custom/Makefile.tail.

    The custom/Makefile is now part of source and includes Makefile.
    In particular, custom/Makefile makes use of the 'middle' of
    the new top level Makefile where calc's top level Makefile
    variables are defined.

    Makefile.simple and custom/Makefile.simple are now part of the source
    and are constructed from Makefile and custom/Makefile respectively.
    The Makefile.simple and custom/Makefile.simple avoid using GNU
    conditionals. They may be used with older/classic make commands.

    Makefile.local will include comments about how to better use
    it. Between releases, Makefile.local at the top of the master branch
    will contain how we typically build calc and test calc (FYI: we
    normally enable things such as -Werror -Wextra -pedantic).  When we
    push out a release, Makefile.local will be stripped of non-comment
    lines.  Thus, releases of calc, and, released "calc*.src.rpm"
    files and the source tarballs, will have a Makefile.local with
    only comments.

    The "README.*" files and "HOWTO.INSTALL" file have been updated.

    By default, compiler warnings have been turned up.  The Makefile
    variable ${CCWARN} now defaults to:

	CCWARN= -Wall -Wextra -pedantic

    The previous level of compiler warnings can be easily restored by
    adding to Makefile.local:

	CCWARN:= -Wall

    The readline, history and ncurses libraries are now default.
    The Makefile variables ${USE_READLINE}, ${READLINE_LIB}, and
    ${READLINE_EXTRAS} now default to:

	USE_READLINE= -DUSE_READLINE
	READLINE_LIB= -lreadline
	READLINE_EXTRAS= -lhistory -lncurses

    The previous mode where readline, history and ncurses libraries
    were not compiled in by default can be easily restored by
    adding to Makefile.local:

	USE_READLINE:=
	READLINE_LIB:=
	READLINE_EXTRAS:=

    We have renamed "stable" as "production".
    We have renamed "unstable" as "tested".

    On the web site:

	http://www.isthe.com/chongo/src/calc/

    these files has been renamed:

	2.x.y.z_IS_LATEST_STABLE   ==> 2.x.y.z_IS_LATEST_PRODUCTION
	2.x.y.z_IS_LATEST_UNSTABLE ==> 2.x.y.z_IS_LATEST_TESTED

    The terms 'stable' and 'unstable' were both misleading and
    inaccurate.  For details see the new documention file:

	README.RELEASE

    See also the help command:

	; help release

    Fixed bug impacting how have_ustat.h was formed.

    Updated help/archive to reflect GitHub use.
2021-12-13 14:43:37 -08:00
Landon Curt Noll
b3c015d338 Release v2.14.0.13
We apologize for the calc v2.14.0.12 source tarball that was missing
critical files.  While the executable was well tested, our release
process was deficient.

We are improved our release process and added tests during the release
procedure to help verify that we are not regressing in to the "v2.14.0.12
source tarball" issue, among other things.

Depending on how things do, you might is several releases come out over
a short period of time.  The core of calc isn't changing, so the calc
executable will be the same as we focus on the Makefiles, our release
procedure, and related documentation / help files.

=-=

The following are the changes in this release:

    Minor tweak to seed() builtin.  Updated help/srand and help/srandom.

    Moved Makefile.ship into Makefile.

    Removed custom/Makefile.head and custom/Makefile.tail.

    The custom/Makefile is now part of source and includes Makefile.
    In particular, custom/Makefile makes use of the 'middle' of
    the new top level Makefile where calc's top level Makefile
    variables are defined.

    Makefile.simple and custom/Makefile.simple are now part of the source
    and are constructed from Makefile and custom/Makefile respectively.
    The Makefile.simple and custom/Makefile.simple avoid using GNU
    conditionals. They may be used with older/classic make commands.

    Makefile.local will include comments about how to better use
    it. Between releases, Makefile.local at the top of the master branch
    will contain how we typically build calc and test calc (FYI: we
    normally enable things such as -Werror -Wextra -pedantic).  When we
    push out a release, Makefile.local will be stripped of non-comment
    lines.  Thus, releases of calc, and, released "calc*.src.rpm"
    files and the source tarballs, will have a Makefile.local with
    only comments.

    The "README.*" files and "HOWTO.INSTALL" file have been updated.

    By default, compiler warnings have been turned up.  The Makefile
    variable ${CCWARN} now defaults to:

	CCWARN= -Wall -Wextra -pedantic

    The previous level of compiler warnings can be easily restored by
    adding to Makefile.local:

	CCWARN:= -Wall

    The readline, history and ncurses libraries are now default.
    The Makefile variables ${USE_READLINE}, ${READLINE_LIB}, and
    ${READLINE_EXTRAS} now default to:

	USE_READLINE= -DUSE_READLINE
	READLINE_LIB= -lreadline
	READLINE_EXTRAS= -lhistory -lncurses

    The previous mode where readline, history and ncurses libraries
    were not compiled in by default can be easily restored by
    adding to Makefile.local:

	USE_READLINE:=
	READLINE_LIB:=
	READLINE_EXTRAS:=

    We have renamed "stable" as "production".
    We have renamed "unstable" as "tested".

    On the web site:

	http://www.isthe.com/chongo/src/calc/

    these files has been renamed:

	2.x.y.z_IS_LATEST_STABLE   ==> 2.x.y.z_IS_LATEST_PRODUCTION
	2.x.y.z_IS_LATEST_UNSTABLE ==> 2.x.y.z_IS_LATEST_TESTED

    The terms 'stable' and 'unstable' were both misleading and
    inaccurate.  For details see the new documention file:

	README.RELEASE

    See also the help command:

	; help release

    Fixed bug impacting how have_ustat.h was formed.

    Updated help/archive to reflect GitHub use.
2021-12-13 14:23:47 -08:00
Landon Curt Noll
5985ad2f33 Updated Makefile.simple due to recent changes in Makefile 2021-12-13 14:16:02 -08:00
Landon Curt Noll
e401c9abf1 Added code to handle HomeBrew macOS libs, added a few #'s 2021-12-13 14:07:51 -08:00
Landon Curt Noll
ad79b6384d Remove leading spaces before a tab in CHANGES 2021-12-13 12:33:35 -08:00
Landon Curt Noll
862dbd6777 Improve the calc build and release process
We apologize for the calc v2.14.0.12 source tarball that was missing
critical files.  While the executable was well tested, our release
process was deficient.

We are improved our release process and added tests during the release
procedure to help verify that we are not regressing in to the "v2.14.0.12
source tarball" issue, among other things.

Depending on how things do, you might is several releases come out over
a short period of time.  The core of calc isn't changing, so the calc
executable will be the same as we focus on the Makefiles, our release
procedure, and related documentation / help files.

We made several changes to the Makefiles.  We also added a new
README.RELEASE document (see "help release") that is a work in
progress. Along the way we discovered a few things that needed to be
updated in documentation.

See the CHANGES file for details.
2021-12-13 12:17:51 -08:00
Landon Curt Noll
0d31eb6828 Recommend calling srand() or srandom() with seed() 2021-12-09 01:34:58 -08:00
Landon Curt Noll
c0be37d4e3 Added paranoia size limited code for seed() builtin.
Just to be padanticly sure, we prevent seed() from
ever returning a value >= 2^64.
2021-12-09 01:12:44 -08:00
Landon Curt Noll
4344532c28 Improve how a seed is loaded into ZVALUE 2021-12-09 00:49:16 -08:00
Landon Curt Noll
0f6efb29bb Release v2.14.0.12
The following are the changes in this release:

    Fixed a number of typos.

    Drop support for SunOS, IRIX and MINGW32_NT-5.0 targets.
    Drop support for CLOCK_SGI_CYCLE.  Drop testing for __MSDOS__.

    Minor improvement of various help files.  Made format of help
    files more consistent.

    Corrected a few comments in zrandom.c, including a case where
    the comment referred to 1007 when it should have used 2^32.

    Improved seed() generation.  Improved some comments in seed.c.
    Added have_environ.c to build have_environ.h in order to
    determine if:

	extern char **environ;	/* user environment */

    is an valid external symbol.

    Fixed documentation that referred to the old additive 55
    generator.  We have been using the subtractive 100 in place
    of the additive 55 generator for a while now.

    Fixed depend rule for custom/Makefile.

    Fixed how Makefile variable SHELL is set on macOS vs. Linux.
    Using /bin/sh on macOS due to how zsh treats globs by default.

    Added charbit.h to define CALC_CHARBIT which is either CHAR_BIT
    from <limits.h> or 8 or a value set by the Makefile variable
    CALC_CHARBIT.  Added have_limits.h to determine if <limits.h>
    is a system include file.

    Compiling now tests for _WIN64 as well when testing for _WIN32.

    Now assuming that <stdio.h> is available under _WIN32 and _WIN64.

    Added some preliminary notes about attempts to compile calc
    under Windows 11.

	BTW: While we are unable to use Windows 11, we welcome
	     Windows 11 developers to try compiling calc natively
	     (instead of via a Linux virtual machine).  If you are
	     able to compile Windows 11 natively, we would welcome
	     GitHub pull requests showing any needed modifications:

		https://github.com/lcn2/calc/pulls

	     Please also add notes to the 'Compiling calc under Windows 11'
	     section in README.WINDOWS file.

    We added Makefile.simple as part of the master branch source
    to help those who may be using a make tool that does not support
    GNU Make-like features such as "ifeq" and ":=".

    Fixed incorrect ustat_dev member ref in seed() builtin that
    was part of the unreleased calc v2.12.0.11.
2021-12-08 16:04:40 -08:00
Landon Curt Noll
39c0cba1ca Release v2.14.0.12
The following are the changes in this release:

    Fixed a number of typos.

    Drop support for SunOS, IRIX and MINGW32_NT-5.0 targets.
    Drop support for CLOCK_SGI_CYCLE.  Drop testing for __MSDOS__.

    Minor improvement of various help files.  Made format of help
    files more consistent.

    Corrected a few comments in zrandom.c, including a case where
    the comment referred to 1007 when it should have used 2^32.

    Improved seed() generation.  Improved some comments in seed.c.
    Added have_environ.c to build have_environ.h in order to
    determine if:

	extern char **environ;	/* user environment */

    is an valid external symbol.

    Fixed documentation that referred to the old additive 55
    generator.  We have been using the subtractive 100 in place
    of the additive 55 generator for a while now.

    Fixed depend rule for custom/Makefile.

    Fixed how Makefile variable SHELL is set on macOS vs. Linux.
    Using /bin/sh on macOS due to how zsh treats globs by default.

    Added charbit.h to define CALC_CHARBIT which is either CHAR_BIT
    from <limits.h> or 8 or a value set by the Makefile variable
    CALC_CHARBIT.  Added have_limits.h to determine if <limits.h>
    is a system include file.

    Compiling now tests for _WIN64 as well when testing for _WIN32.

    Now assuming that <stdio.h> is available under _WIN32 and _WIN64.

    Added some preliminary notes about attempts to compile calc
    under Windows 11.

	BTW: While we are unable to use Windows 11, we welcome
	     Windows 11 developers to try compiling calc natively
	     (instead of via a Linux virtual machine).  If you are
	     able to compile Windows 11 natively, we would welcome
	     GitHub pull requests showing any needed modifications:

		https://github.com/lcn2/calc/pulls

	     Please also add notes to the 'Compiling calc under Windows 11'
	     section in README.WINDOWS file.

    We added Makefile.simple as part of the master branch source
    to help those who may be using a make tool that does not support
    GNU Make-like features such as "ifeq" and ":=".

    Fixed incorrect ustat_dev member ref in seed() builtin that
    was part of the unreleased calc v2.12.0.11.
2021-12-08 15:52:34 -08:00
Landon Curt Noll
a68e41248f Fixed incorrect ustat_dev member ref in seed() 2021-12-08 15:43:27 -08:00
Landon Curt Noll
e213cc5072 Release v2.14.0.11
The following are the changes in this release:

    Fixed a number of typos.

    Drop support for SunOS, IRIX and MINGW32_NT-5.0 targets.
    Drop support for CLOCK_SGI_CYCLE.  Drop testing for __MSDOS__.

    Minor improvement of various help files.  Made format of help
    files more consistent.

    Corrected a few comments in zrandom.c, including a case where
    the comment referred to 1007 when it should have used 2^32.

    Improved seed() generation.  Improved some comments in seed.c.
    Added have_environ.c to build have_environ.h in order to
    determine if:

	extern char **environ;	/* user environment */

    is an valid external symbol.

    Fixed documentation that referred to the old additive 55
    generator.  We have been using the subtractive 100 in place
    of the additive 55 generator for a while now.

    Fixed depend rule for custom/Makefile.

    Fixed how Makefile variable SHELL is set on macOS vs. Linux.
    Using /bin/sh on macOS due to how zsh treats globs by default.

    Added charbit.h to define CALC_CHARBIT which is either CHAR_BIT
    from <limits.h> or 8 or a value set by the Makefile variable
    CALC_CHARBIT.  Added have_limits.h to determine if <limits.h>
    is a system include file.

    Compiling now tests for _WIN64 as well when testing for _WIN32.

    Now assuming that <stdio.h> is available under _WIN32 and _WIN64.

    Added some preliminary notes about attempts to compile calc
    under Windows 11.

	BTW: While we are unable to use Windows 11, we welcome
	     Windows 11 developers to try compiling calc natively
	     (instead of via a Linux virtual machine).  If you are
	     able to compile Windows 11 natively, we would welcome
	     GitHub pull requests showing any needed modifications:

		https://github.com/lcn2/calc/pulls

	     Please also add notes to the 'Compiling calc under Windows 11'
	     section in README.WINDOWS file.

    We added Makefile.simple as part of the master branch source
    to help those who may be using a make tool that does not support
    GNU Make-like features such as "ifeq" and ":=".
2021-12-08 15:30:08 -08:00
Landon Curt Noll
95ebb60619 Remove old MSDOS code in favor of _WIN32 & _WIN64 2021-12-08 15:02:36 -08:00
Landon Curt Noll
e5c8f00adc Ship with Makefile.simple & custom/Makefile.simple 2021-12-08 14:55:23 -08:00
Landon Curt Noll
265713778f Improved top level documentation 2021-12-08 14:12:23 -08:00
Landon Curt Noll
4b08a896b0 Fix comments about _WIN64 2021-12-08 12:51:10 -08:00
Landon Curt Noll
44f3778af1 More DJGPP cleanup 2021-12-08 12:33:46 -08:00
Landon Curt Noll
8db8f93ae0 Change -DWINDOZ to -D_WIN32 for DJGPP 2021-12-08 12:25:16 -08:00
Landon Curt Noll
e688c22c0e Add missing have_limits.h rule for Makefile 2021-12-08 12:18:23 -08:00
Landon Curt Noll
af72992ead Added testing for _WIN64 when testing for _WIN32 2021-12-08 12:04:13 -08:00
Landon Curt Noll
9f3a7817d3 Improve seed()
Do not rehash the hash.
2021-12-07 22:05:47 -08:00
Landon Curt Noll
dd0610db0a Improve seed()
xor-fold FNV hashes as seeds.
2021-12-07 22:01:23 -08:00
Landon Curt Noll
177a5d00d1 Improve seed()
Added charbit.h to define CALC_CHARBIT which is either CHAR_BIT
from <limits.h> or 8 or a value set by the Makefile variable
CALC_CHARBIT.  Added have_limits.h to determine if <limits.h>
is a system include file.
2021-12-07 21:41:28 -08:00
Landon Curt Noll
a02f8aa9f9 Improve seed() builtin
Increase size of random() data used by seed().
2021-12-07 13:47:00 -08:00
Landon Curt Noll
b7d1fb096d Improve the seed() builtin
Set seed() use of arc4random to same level as /dev/urandom.
Restore state size for initstated random().
2021-12-07 13:42:03 -08:00
Landon Curt Noll
48c4f3b948 Improve seed() builtin 2021-12-07 13:39:07 -08:00
Landon Curt Noll
2023175fcc Change how SHELL is set for all calc Makefiles
Using /bin/sh on macOS due to how zsh treats globs by default.
2021-12-07 04:45:23 -08:00
Landon Curt Noll
c54e2648dc Set SHELL=/bin/sh for macOS in Makefiles 2021-12-07 04:35:42 -08:00
Landon Curt Noll
faf40b7149 Fixed how SHELL is set in Makefiles, fix make depend on linux 2021-12-07 04:18:39 -08:00
Landon Curt Noll
4b2ae40c86 Fixed make depend on linux 2021-12-07 04:00:36 -08:00
Landon Curt Noll
af57104e25 Fixed depend rule for custom/Makefile 2021-12-07 03:01:46 -08:00
Landon Curt Noll
5ae3ca059a Fixed old references additive 55
Fixed documentation that referred to the old additive 55
generator.  We have been using the subtractive 100 in place
of the additive 55 generator for a while now.
2021-12-07 02:24:50 -08:00
Landon Curt Noll
cc5fb9a45b Improve the seed() function 2021-12-07 01:56:46 -08:00
Landon Curt Noll
5dcadad8b6 Fix long line in have_arc4random.c 2021-12-07 01:54:55 -08:00
Landon Curt Noll
9c67ceeed8 Fix have_arc4random.h generation 2021-12-07 00:48:28 -08:00
Landon Curt Noll
7ffbaf922e Improve seed() function 2021-12-07 00:44:57 -08:00
Landon Curt Noll
f9464652fe Improve seed() even more 2021-12-06 23:30:52 -08:00
Landon Curt Noll
b30c5c1855 Improved seed() generation
Drop support for CLOCK_SGI_CYCLE.

Improved seed() generation.  Improved some comments in seed.c.
Added have_environ.c to build have_environ.h in order to
determine if:

    extern char **environ;	/* user environment */

is an valid external symbol.
2021-12-06 21:16:08 -08:00
Landon Curt Noll
7417f2e776 Remove excess blank line from calc.c 2021-12-06 21:13:53 -08:00
Landon Curt Noll
71138215a9 Noted changes to zrandom.c comments 2021-12-05 23:38:28 -08:00
Landon Curt Noll
241f777d07 Minor updates to comments
We also corrected a comment mistake where 1007 should have been 2^32.
2021-12-05 23:36:05 -08:00
Landon Curt Noll
9d27f0aaa7 Update security policy. 2021-12-05 23:12:24 -08:00
Landon Curt Noll
a28edba4e9 Improve help files
Minor improvement of various help files.  Made format of help
files more consistent.
2021-12-05 23:02:12 -08:00
Landon Curt Noll
de47c960d3 Change remaining Email addresses to use at and dot 2021-12-05 21:29:46 -08:00
Landon Curt Noll
c3a51f42e2 Drop support for SunOS, IRIX and MINGW32_NT-5.0 targets 2021-12-05 19:02:09 -08:00
Landon Curt Noll
f5c5cea8b0 Correct typos 2021-12-05 18:23:27 -08:00
Landon Curt Noll
769ac51f8c Release v2.14.0.10 2021-12-01 23:38:56 -08:00
Landon Curt Noll
cdda633369 Update CHANGES file to note previous 2 commits 2021-12-01 23:34:40 -08:00
Landon Curt Noll
50f349f4d7 Update copyright dates to account for 2021 mods 2021-12-01 23:28:59 -08:00
Landon Curt Noll
ef00e00328 Remove unnecessary spaces inbetween or next to tabs 2021-12-01 23:25:49 -08:00
Landon Curt Noll
bb041098bc Reduce the length of long lines 2021-12-01 23:15:06 -08:00
Landon Curt Noll
f794b8d859 Reduce global status constants
The constants:

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

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

The constants:

	3, 4

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

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

	ARCH_CFLAGS=

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

	make all ARCH_CFLAGS='-march=native'

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

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

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

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

    Fizzbin is a better word. :-)

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

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

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

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

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

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

    Fixed typo in cal/statistics.cal thanks to a report by <GitHub user
    dennisaldea>.

    Fixed an old Windoz pun in README.WINDOWS as requested by <GitHub
    user marcodegio>.

    Fixed a really obscure bug in the internal initconstants()
    function of const.c that has been sitting for over 31 years!

	We are amazed that nobody has encountered this bug before
	now.  Nevertheless, our very extensive regression and
	multi-architecture testing found the bug.  Now, after all
	those years, it is fixed.

    Fixed issues identied by the default CodeUL GitHub security code scan:

	Wrong type of arguments to printf in have_fpos_pos.c
	Multiplication result converted to larger type in zfunc.c
2021-10-22 03:36:40 -07:00
Landon Curt Noll
f0f6171354 Release v2.14.0.5
Fixed a really obscure bug in the internal initconstants()
function of const.c that has been sitting for over 31 years!

    We are amazed that nobody has encountered this bug before
    now.  Nevertheless, our very extensive regression and
    multi-architecture testing found the bug.  Now, after all
    those years, it is fixed.

Fixed issues identied by the default CodeUL GitHub security code
scan:

    Wrong type of arguments to printf in have_fpos_pos.c
    Multiplication result converted to larger type in zfunc.c
2021-10-22 03:20:58 -07:00
Landon Curt Noll
94861cc6d2 Improved an internal allocation
Improved the way that the internal array,
consttable, is allocated.
2021-10-22 03:09:08 -07:00
Landon Curt Noll
286233e28f Fixed internal code bugs
Fixed a really obscure bug in the internal initconstants()
function of const.c that has been sitting for over 31 years!

    We are amazed that nobody has encountered this bug before
    now.  Nevertheless, our very extensive regression and
    multi-architecture testing found the bug.  Now, after all
    those years, it is fixed.

Fixed issues identied by the default CodeUL GitHub security code scan:

    Wrong type of arguments to printf in have_fpos_pos.c
    Multiplication result converted to larger type in zfunc.c
2021-10-22 03:05:12 -07:00
Landon Curt Noll
99ac7836aa Create SECURITY.md 2021-10-22 01:46:12 -07:00
Landon Curt Noll
6c0c8e0ef6 Fixed issues noted by default GitHub code scan 2021-10-22 01:39:07 -07:00
Landon Curt Noll
8aa5f140bf Release v2.12.0.4 2021-10-22 01:26:25 -07:00
Landon Curt Noll
2fcb9a5995 Create codeql-analysis.yml 2021-10-22 01:25:16 -07:00
Landon Curt Noll
8b018b697d Updated CHANGES as per GitHub pull request #35 2021-10-21 12:21:10 -07:00
Landon Curt Noll
0e269ecd67 Merge pull request #35 from marcodegio/patch-1
Update README.WINDOWS
2021-10-21 12:15:56 -07:00
Landon Curt Noll
a640bc4656 Fixed typo in cal/statistics.cal
Thanks to a report by <GitHub user dennisaldea>.
2021-10-21 12:12:31 -07:00
Marco Degiovanni
62a95499ef Update README.WINDOWS
i changed the first line from Windoz to Windows
2021-10-21 20:05:11 +02:00
Landon Curt Noll
9e92d4a35a Change initnumbs[] to be NULL terminated 2021-09-28 22:32:06 -07:00
672 changed files with 116733 additions and 96342 deletions

View File

@@ -0,0 +1,70 @@
---
name: Calc bug report
about: Create a report to help us improve
title: 'Bug: XXX-change-this-part-XXX'
labels: bug
assignees: ''
---
Calc bug report template version: 1.3 2022-11-27
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
0. How you started calc
I.e., provide the command line you used to launch calc
1. Calc commands and their output
Please provide any calc commands you entered on the terminal.
Please provide the calc command line output inline as well.
If the above is long, please attach a file.
Or if you cannot compile calc: The make command you used try and compile calc
and all error and warning messages produced during that action. If long, consider
attaching a file.
2. Indicate where the problem is
Referring to the information for step 1 above, indicate where the problem is to be found
**Expected behavior**
A clear and concise description of what you expected to happen.
**Attach debug.out**
IMPORTANT: Please run `make debug` and then attach the `debug.out` file.
**Screen shots**
If applicable, attach screen shots to help explain your problem.
**Execution environment (please complete the following information):**
- OS:
E.g., macOS, FreeBSD, Linux, Windows 11, etc.
- OS version:
E.g., Preferred: give the output of `uname -a`
or if no uname command, a description of the OS version/release you are using
- OS distribution:
E.g., macOS 13.0.1, contents of /etc/redhat-release, or /etc/os-release, etc.
- Calc Version
E.g., output of calc -v
or if you cannot compile calc, the version you downloaded and from where it came from
- Shell and shell version
E.g., bash, zsh, power shell, etc.
and the version of the shell you are using, if known
**Calc mods**
If you have modified the calc source for some reason, please description what you modified.
Please consider attaching a patch (diff -u) between an official calc release and the source
you are using.
**Patch**
If you have a recommended code patch to address the problem, please attach your file
**Additional context**
Add any other context about the problem here.

View File

@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

12
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,12 @@
# Set update schedule for GitHub Actions
#
# See https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
# Check for updates to GitHub Actions every week
interval: "weekly"

80
.github/workflows/codeql-analysis.yml vendored Normal file
View File

@@ -0,0 +1,80 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ "master" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "master" ]
schedule:
- cron: '41 1 * * 6'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'cpp' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Use only 'java' to analyze code written in Java, Kotlin or both
# Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: '20'
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v3
# Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"

134
.gitignore vendored
View File

@@ -1,66 +1,132 @@
# generic excluded patterns
#
# We sort the list below via: sort -d -u
#
*~
*.BAK
core*
.DS_Store
*.dSYM/
*.exe
*.[oa]
*.o.tmp
.*.swp
*,v
# files and directories created during the building of calc and other Makefile actions
#
# NOTE: While many of these might be part of a released calc tarball, they are
# not consider development source. Some other file(s) and/or programs
# generate these files.
# not consider development source. Some other file(s) and/or programs
# generate these files.
#
.dynamic
.hsrc
Makefile.simple
NOTES
# We sort the list below via: sort -d -u
#
align32
align32.h
align32_tmp
arc4random_tmp
args.h
cal/.all
calc
calc.1
calc.cat1
calc.spec
calc-static
calc.usage
calcerr.c
calcerr.h
cal/test082.cal
charbit.h
chatbit
chk_c
conf.h
cscript/.all
const_tmp
cscript/4dsphere
cscript/README
cscript/.all
cscript/fproduct
cscript/mersenne
cscript/piforever
cscript/plus
cscript/powerterm
cscript/README
cscript/simple
cscript/square
custom/.all
custom/Makefile.simple
custom/libcustcalc*
debug.out
.dynamic
endian
endian_calc.h
environ_tmp
errcode
errsym.h
fpos_tmp
fposval
fposval.h
fposval_tmp
func.show
func.sort
getpgid_tmp
getprid_tmp
getsid_tmp
gettime_tmp
have_arc4random
have_arc4random.h
have_ban_pragma
have_ban_pragma.h
have_const
have_const.h
have_fpos.h
have_environ
have_environ.h
have_fgetsetpos.h
have_fpos
have_fpos_pos
have_fpos_pos.h
have_getpgid
have_getpgid.h
have_getprid
have_getprid.h
have_getsid
have_getsid.h
have_gettime
have_gettime.h
have_inttypes.h
have_limits.h
have_memmv
have_memmv.h
have_newstr
have_newstr.h
have_offscl
have_offscl.h
have_posscl
have_posscl.h
have_rusage
have_rusage.h
have_statfs
have_statfs.h
have_stdbool.h
have_stdint.h
have_stdlib.h
have_stdvs
have_strdup
have_strdup.h
have_string.h
have_strlcat
have_strlcat.h
have_strlcpy
have_strlcpy.h
have_sys_mount.h
have_sys_param.h
have_sys_vfs.h
have_times.h
have_uid_t
have_uid_t.h
have_unistd.h
have_unused
have_unused.h
have_urandom.h
have_ustat
have_ustat.h
have_varvs
help/.all
help/COPYING
help/COPYING-LGPL
help/binding
help/bindings
help/bug
@@ -70,6 +136,8 @@ help/change
help/changes
help/contrib
help/copy
help/COPYING
help/COPYING-LGPL
help/cscript
help/custom_cal
help/errorcode
@@ -77,31 +145,43 @@ help/errorcodes
help/full
help/funclist
help/funclist.c
help/ilogn
help/libcalc
help/man
help/new_custom
help/question
help/questions
help/releases
help/resource
help/type
help/usage
libcalc*
libcustcalc*
.hsrc
libcalc.*
libcustcalc.*
ll_tmp
longbits
longbits.h
Makefile.our
memmv_tmp
newstr_tmp
NOTES
offscl_tmp
outfile
posscl_tmp
rusage_tmp
sample_many
sample_many-static
sample_rand
sample_rand-static
statfs_tmp
.static
status.chk_c.h
strdup_tmp
tags
terminal.h
uid_tmp
unused_tmp
ustat_tmp
ver_calc
# other commonly excluded patterns
#
*~
*.BAK
core*
.DS_Store
*.dSYM/
*.[oa]
.*.swp
*,v
vs_tmp
win32/

23
.lldbinit Normal file
View File

@@ -0,0 +1,23 @@
#
# lldb calc
#
# IMPORTANT: Under macOS, use this local ./lldbinit file, your home directory file:
#
# ~/.lldbinit
#
# must contain this line (w/o the leading # and whitespace):
#
# settings set target.load-cwd-lldbinit true
#
# Optimizing calc may make it harder to trace what calc is doing,
# To turn off optimization while debugging, try:
#
# make clobber all DEBUG="-g3"
#
# To debug calc with lldb from this directory, just run:
#
# lldb
#
target create "./calc"
process launch -tty --environment CALCPATH=./cal --environment LD_LIBRARY_PATH=. --environment DYLD_LIBRARY_PATH=. --environment CALCHELP=./help --environment CALCCUSTOMHELP=./custom -- -q -d
b main

143
BUGS
View File

@@ -15,19 +15,37 @@ Look at the end of the output, it should say something like:
If it does not, then something is really broken!
To be sure that your version of calc is up to date, check out:
To be sure that your version of calc is up to date.
Look for the latest release on GitHub:
http://www.isthe.com/chongo/tech/comp/calc/calc-mirror.html
https://github.com/lcn2/calc/releases
Just below latest GitHub release sectiop is something called:
> Assets
Click in the triangle to open up the Assets then click on
the approptiate package to download.
If you made and modifications to calc beyond the simple Makefile
configuration, try backing them out and see if things get better.
configuration, try backing those changes out and see if things get
better.
If you have tried all of the above and things still are not right,
then it may be time to send in a bug report.
=-=
The BEST WAY TO SEND IN A BUG REPORT is via calc GitHub issue URL:
If you encounter a warning or error in compiling, or if you
find a calc bug and you wish to send is a fix, we recommend
that you submit your change using the GitHub pull request:
https://github.com/lcn2/calc/pulls
=-=
If you just want to send us a bug report, we recommend
doing so via the GitHub issue process:
https://github.com/lcn2/calc/issues
@@ -42,56 +60,19 @@ GitHub web page, click on this button:
((New Issue))
=-=
If you prefer to not use GitHub, then you
may send bug and bug fixes reports to:
calc-bugrept-mail at asthe dot com
NOTE: Remove spaces and replace 'at' with @, 'dot' with .
NOTE: This replaces the old calc-bugs at asthe dot com address.
PLEASE put following the SPECIAL PHRASE somewhere in your Email Subject line:
calc bug report
You may add additional words to your subject line.
Suggestion:
From time to time, the Email address and Subject SPECIAL PHRASE
may change so verify you have the current info by visiting:
http://www.isthe.com/chongo/tech/comp/calc/calc-bugrept.html
IMPORTANT:
PLEASE use the above SPECIAL PHRASE somewhere in the Subject line or
the mail system won't deliver your Email message.
Keep in mind that the best way to report on a calc bug is
via the above mentioned calc GitHub issue URL.
Please be patient as we cannot always respond to Email messages quickly.
=-=
When you send your report, via the calc GitHub issue URL or Email,
please include the following information:
Please include the following information in the new issue:
* A description of the problem
* Version of calc you are using
If you cannot compile calc, then look at version.c
and report the #define that start with:
If you cannot compile calc, then look at version.c
and report the #define that start with:
#define MAJOR_VER
#define MINOR_VER
#define MAJOR_PATCH
#define MINOR_PATCH
#define MAJOR_VER
#define MINOR_VER
#define MAJOR_PATCH
#define MINOR_PATCH
* If you modified calc from an official patch,
send us the mods you made
@@ -105,12 +86,13 @@ please include the following information:
* If calc dumped core, try to send us a core dump stack trace
* cd to the calc source directory, and send the contents
of debug.out produced by this command:
of debug.out.txt produced by this command:
make debug > debug.out 2>&1
make debug
Fell free to use the above address to send in bug fixes (in the form
of a context diff patch).
PLEASE attach the debug.out.txt file to your GitHub issue (bug report)!!
Please be patient as we cannot always respond to pull requests quickly.
=-=
@@ -119,6 +101,10 @@ Known bugs in calc:
The output of the alg_config.cal resource file is bogus.
We would welcome a replacement for this code.
Calc may not compile natively under Windows 11, however with
MSYS2 Software Distribution (a fork of Cygwin) people compile
calc under Windiws just fine. See README.WINDOWS.
We are sure some more bugs exist. When you find them, please let
us know! See the above for details on how to report and were to
Email your bug reports and hopefully patches to fix them.
@@ -136,16 +122,16 @@ mis-features in calc:
This works as expected:
if (expr) {
...
}
if (expr) {
...
}
However this WILL NOT WORK AS EXPECTED:
if (expr)
{
...
}
if (expr)
{
...
}
This needs to be changed. See also "help statement", "help unexpected",
and "help todo".
@@ -157,24 +143,33 @@ mis-features in calc:
integers to/from files the hard way. It does NOT use blkcpy. The
following code:
i = (ord("\n") << 16) | (ord("i") << 8) | ord("H")
b = blk()
copy(i, b)
fd = fopen("file", "w")
copy(b, fd);
fclose(fd)
i = (ord("\n") << 16) | (ord("i") << 8) | ord("H")
b = blk()
copy(i, b)
fd = fopen("file", "w")
copy(b, fd);
fclose(fd)
will write an extra NUL octet to the file. Where as:
read intfile
i = (ord("\n") << 16) | (ord("i") << 8) | ord("H")
be2file(i, "file2")
read intfile
i = (ord("\n") << 16) | (ord("i") << 8) | ord("H")
be2file(i, "file2")
will not.
* The numerator is assumed
The numerator value of 1 appears to be assumed. In calc:
/ 2
will produce a value of 0.5 as if the numerator 1 was given.
=-=
## Copyright (C) 1999-2014,2021 Landon Curt Noll
## Copyright (C) 1999-2014,2021,2023 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
@@ -182,7 +177,7 @@ mis-features in calc:
##
## 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
## 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
@@ -190,8 +185,8 @@ mis-features in calc:
## 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: 1994/03/18 14:06:13
## File existed as early as: 1994
## Under source code control: 1994/03/18 14:06:13
## File existed as early as: 1994
##
## chongo <was here> /\oo/\ http://www.isthe.com/chongo/
## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
## chongo <was here> /\oo/\ http://www.isthe.com/chongo/
## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/

5451
CHANGES

File diff suppressed because it is too large Load Diff

128
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,128 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
https://github.com/lcn2/calc/blob/master/QUESTIONS.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.

View File

@@ -1,73 +1,37 @@
Calc is open source. Contributions of code are welcome.
We welcome and encourage you to send us:
In order to consider integrating your contributions, we need:
* calc resource files (cal/*.cal files)
* calc shell scripts (cscript/*.calc files)
* builtin functions that you have modified or written, i.e.:
assocfunc.c comfunc.c func.c func.h
listfunc.c matfunc.c qfunc.c zfunc.c
* custom functions that you have modified or written
* help files modified or written (help/*)
* Makefile improvements (Makefile, */Makefile)
* other source code modifications (*.c, *.h)
* etc. (* */* :) )
* your changes applied agsinst the top of the calc master branch:
In order to consider integrating your code, we need:
https://github.com/lcn2/calc/
* calc version you are working with (please try use the latest version)
* new help files or help file patches, if applicable (documentation)
* proposed text for the CHANGES file (brief description of what it does)
* regress.cal test patch as needed
* your source code and/or source code changes (:-))
If you add functionality to calc, please be sure to modify/patch/add
* Update CHANGES file (brief description of what it does)
* regress.cal test patch as needed
If you add functionality to calc, please be sure to modify
Makefiles, help files, cal/regress.cal test code as well.
Regression test cases are vital to maintaining calc's level
of correctness and helps us avoid code bug regression.
Please try to generate a patch against the most recent
version of calc, and if you use GitHub, the top of the
master branch:
https://github.com/lcn2/calc
The best way contribute to calc bug is to generate calc
GitHub pull request:
GitHub pull request against the calc GitHub repo:
https://github.com/lcn2/calc/pulls
Please be patient as we cannot always respond pull requests quickly.
=-=
IMPORTANT:
Your code needs to be contributed under either the 2.1 of the GNU
Lesser General Public License (LGPL 2.1) or in the public domain.
Lesser General Public License (LGPL 2.1) or under "The Unlicense":
If you do not want to use calc GitHub, then send Email to:
calc-contrib-mail at asthe dot com
NOTE: Remove spaces and replace 'at' with @, 'dot' with .
You MUST use following SPECIAL PHRASE in your Email Subject line:
calc contribution
You may add additional words to your subject line.
Suggestion:
From time to time, the Email address and Subject SPECIAL PHRASE
may change so verify you have the current info by visiting:
http://www.isthe.com/chongo/tech/comp/calc/calc-contrib.html
IMPORTANT: If your Email doesn't contain the above phrase,
then we WILL NOT SEE your Email.
PLEASE BE SURE you have that SPECIAL PHRASE somewhere in the subject line!
Keep in mind that the best way to report on a calc bug is to use
the above mentioned calc GitHub procedure.
Please be patient as we cannot always respond to Email messages quickly.
https://unlicense.org
=-=
@@ -77,7 +41,7 @@ See also the calc wishlist by running the calc command:
=-=
## Copyright (C) 1999,2014,2021 Landon Curt Noll
## Copyright (C) 1999,2014,2021,2023 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 +49,7 @@ See also the calc wishlist by running the calc command:
##
## 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
## 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
@@ -93,8 +57,8 @@ See also the calc wishlist by running the calc command:
## 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: 1997/03/09 16:33:22
## File existed as early as: 1997
## Under source code control: 1997/03/09 16:33:22
## File existed as early as: 1997
##
## chongo <was here> /\oo/\ http://www.isthe.com/chongo/
## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
## chongo <was here> /\oo/\ http://www.isthe.com/chongo/
## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/

7
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,7 @@
# How to contribue code to calc
## CONTRIB-CODE
See the file
<A HREF="https://github.com/lcn2/calc/blob/master/CONTRIB-CODE">CONTRIB-CODE</A>
for how to contribue code to calc.

145
COPYING
View File

@@ -1,16 +1,16 @@
calc - arbitrary precision calculator
calc - arbitrary precision calculator
This file is Copyrighted
------------------------
This file is not covered under version 2.1 of the GNU LGPL.
This file is covered under the following Copyright:
Copyright (C) 1999-2021 Landon Curt Noll
All rights reserved.
Copyright (C) 1999-2023 Landon Curt Noll
All rights reserved.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
-=-
@@ -33,21 +33,21 @@ Calc is covered by the GNU Lesser General Public License
A copy of the GNU Lesser General Public License is distributed with
calc under the filename:
COPYING-LGPL
COPYING-LGPL
You may display this file by the calc command: help copying
You may display this file by the calc command: help copying
You may display the GNU Lesser General
Public License by the calc command: help copying-lgpl
Public License by the calc command: help copying-lgpl
You should have received a copy of the version 2.1 GNU Lesser General
Public License with calc; if not, write to the following address:
Free Software Foundation, Inc.
51 Franklin Street
Fifth Floor
Boston, MA 02110-1301
USA
Free Software Foundation, Inc.
51 Franklin Street
Fifth Floor
Boston, MA 02110-1301
USA
Calc's relationship to the GNU Lesser General Public License
------------------------------------------------------------
@@ -55,53 +55,53 @@ Calc's relationship to the GNU Lesser General Public License
In section 0 of the GNU Lesser General Public License, one finds
the following definition:
The "Library", below, refers to any such software library or
work which has been distributed under these terms.
The "Library", below, refers to any such software library or
work which has been distributed under these terms.
Calc is distributed under the terms of the GNU Lesser
General Public License.
In the same section 0, one also find the following:
For a library, complete source code means all the source code
for all modules it contains, plus any associated interface
definition files, plus the scripts used to control compilation
and installation of the library.
For a library, complete source code means all the source code
for all modules it contains, plus any associated interface
definition files, plus the scripts used to control compilation
and installation of the library.
There are at least two calc binary link libraries found in calc:
libcalc.a libcustcalc.a
libcalc.a libcustcalc.a
Clearly all files that go into the creation of those binary link
libraries are covered under the License.
The ``scripts used to control compilation and installation of the
of the library'' include:
The "scripts used to control compilation and installation of the
of the library" include:
* Makefiles
* source files created by the Makefiles
* source code used in the creation of intermediate source files
* Makefiles
* source files created by the Makefiles
* source code used in the creation of intermediate source files
All of those files are covered under the License.
The ``associated interface definition files'' are those files that:
The "associated interface definition files" are those files that:
* show how the calc binary link libraries are used
* test the validity of the binary link libraries
* document routines found in the binary link libraries
* show how one can interactively use the binary link libraries
* show how the calc binary link libraries are used
* test the validity of the binary link libraries
* document routines found in the binary link libraries
* show how one can interactively use the binary link libraries
Calc provides an extensive set of files that perform the above
functions.
* files under the sample sub-directory
* files under the help sub-directory
* files under the lib sub-directory
* the main calc.c file
* files under the sample sub-directory
* files under the help sub-directory
* files under the lib sub-directory
* the main calc.c file
The ``complete source code'' includes ALL files shipped with calc,
except for the exception files explicitly listed in the ``Calc
copyrights and exception files'' section below.
The "complete source code" includes ALL files shipped with calc,
except for the exception files explicitly listed in the "Calc
copyrights and exception files" section below.
-=-
@@ -111,20 +111,22 @@ Calc copyrights and exception files
With the exception of the files listed below, Calc is covered under
the following GNU Lesser General Public License Copyrights:
Copyright (C) year David I. Bell
Copyright (C) year David I. Bell and Landon Curt Noll
Copyright (C) year David I. Bell and Ernest Bowen
Copyright (C) year David I. Bell, Landon Curt Noll and Ernest Bowen
Copyright (C) year Landon Curt Noll
Copyright (C) year Ernest Bowen and Landon Curt Noll
Copyright (C) year Ernest Bowen
Copyright (C) year Petteri Kettunen and Landon Curt Noll
Copyright (C) year Christoph Zurnieden
Copyright (C) year David I. Bell
Copyright (C) year David I. Bell and Landon Curt Noll
Copyright (C) year David I. Bell and Ernest Bowen
Copyright (C) year David I. Bell, Landon Curt Noll and Ernest Bowen
Copyright (C) year Landon Curt Noll
Copyright (C) year Ernest Bowen and Landon Curt Noll
Copyright (C) year Ernest Bowen
Copyright (C) year Petteri Kettunen and Landon Curt Noll
Copyright (C) year Christoph Zurnieden
Copyright (C) year Landon Curt Noll and Thomas Jones-Low
Copyright (C) year Klaus Alexander Seistrup and Landon Curt Noll
These files are not covered under one of the Copyrights listed above:
sha1.c sha1.h COPYING
COPYING-LGPL cal/qtime.cal cal/screen.cal
sha1.c sha1.h COPYING
COPYING-LGPL cal/screen.cal
The file COPYING-LGPL, which contains a copy of the version 2.1
GNU Lesser General Public License, is itself Copyrighted by the
@@ -136,8 +138,39 @@ Calc copyrights and exception files
top of this file. It is important to note that you may distribute
verbatim copies of this file but you may not modify this file.
Some of these exception files are in the public domain. Other files
are under the LGPL but have different authors that those listed above.
These files are covered under "The Unlicense":
sha1.c
sha1.h
cal/dotest.cal
cal/screen.cal
"The Unlicense" is as follows:
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>
In all cases one may use and distribute these exception files freely.
And because one may freely distribute the LGPL covered files, the
@@ -150,12 +183,12 @@ General Copyleft and License info
For general information on Copylefts, see:
http://www.gnu.org/copyleft/
http://www.gnu.org/copyleft/
For information on GNU Lesser General Public Licenses, see:
http://www.gnu.org/copyleft/lesser.html
http://www.gnu.org/copyleft/lesser.txt
http://www.gnu.org/copyleft/lesser.html
http://www.gnu.org/copyleft/lesser.txt
-=-
@@ -165,10 +198,10 @@ Why calc did not use the GNU General Public License
It has been suggested that one should consider using the GNU General
Public License instead of the GNU Lesser General Public License:
http://www.gnu.org/philosophy/why-not-lgpl.html
http://www.gnu.org/philosophy/why-not-lgpl.html
As you can read in the above URL, there are times where a library
cannot give free software any particular advantage. One of those
cannot give free software any particular advantage. One of those
times is when there is significantly similar versions available
that are not covered under a Copyleft such as the GNU General Public
License.

View File

@@ -1,433 +1,390 @@
# Installing a pre-compiled calc from an RPM
IMPORTANT: Please see the section at the bottom of this file for
some important information on Makefiles used in calc.
If your platform supports RPMs, you may want to go to:
###################################################################
# IMPORTANT: DO NOT run GNU make in parallel mode!!! #
###################################################################
# Unfortunately due to the complex dependency issues between #
# Makefile, Makefile.ship and custom/Makefile, parallel GNU make #
# is NOT recommended. Sorry (tm Canada) :) #
###################################################################
https://github.com/lcn2/calc/releases
Installing calc from the bzip2-ed tarball in 4 easy steps:
and see if there is a pre-compiled version of calc that you may install.
(0) If your platform supports i686 RPMs, you may want to go to:
Open up the 'Assets' tag below a given release and download these RPMs:
http://www.isthe.com/chongo/src/calc/
* calc*.rpm
and use these RPMs:
- all that is needed if you just want to use calc
* calc*.i686.rpm
- all that is needed if you just want to use calc
If your platform supports rpm and matches one of the "calc*.rpm" files, you
may just install that "calc*.rpm". For exammple on an x86_64 system:
* calc-devel-*.i686.rpm
- calc *.h header and *.a lib files for use in other programs
dnf install calc-x.y.z.cv-ww.x86_64.rpm
* calc.*.src.rpm
- calc source in RPM package form
where "calc-x.y.z.cv-ww.x86_64.rpm" is the name of the calc RPM.
The following 4 steps apply to calc source tree that comes from either:
In addition, if your platform supports rpm and matches one of the
"calc*.rpm" files, you may also install the calc *.h header and *.a lib
files for use in other programs:
bunzip2 -c calc-*.tar.bz2 | tar -xvf -
* calc-devel-*.rpm
or from:
- calc *.h header and *.a lib files for use in other programs
rpm -ivh calc-*.src.rpm
cd /var/tmp
bunzip2 -c /usr/src/redhat/SOURCES/calc-*.tar.bz2 | tar -xvf -
Alternately to the above github link, you might try looking at the RPMs under:
(1) Look at the makefile, and adjust it to suit your needs.
http://www.isthe.com/chongo/src/calc/
The top level Makefile and the custom/Makefile require a modern
Make (such as gmake) or an equivalently advanced make. On many
targets, the default make is sufficient. On FreeBSD for example,
probably want to use gmake instead of make.
Some report that under macOS, one has to declare the target
to be Darwin. So for macOS, one might have to do:
# for macOS users only, force the target to be Darwin
#
make target=Darwin clobber
make target=Darwin all
make target=Darwin chk
make target=Darwin install
# Building calc from a source tree
If your target system does not have a moderm Makefile (such as gmake),
then you should try using the Makefile.simple and custom/Makefile.simple
files:
mv Makefile Makefile.gmake
cp Makefile.simple Makefile
mv custom/Makefile custom/Makefile.gmake
cp custom/Makefile.simple custom/Makefile
The Makefile, as shipped, is suitable for installation under
Linux and Un*x-like environments. For the most part, the default
values should work. If in doubt, follow the 'When in doubt'
suggestion.
## Step 0: Obtain the calc source tree
If you are using a modern make (such as gmake), you may override
any values set in the Mkefile by adding them to Makefile.local
using the := directive. For example:
Go to the site:
HAVE_STRING_H:= YES
HAVE_TIMES_H:= YES
SED:= /usr/local/bin/nsed
https://github.com/lcn2/calc/releases
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! If you are building under Windoz or a Windoz-like environment !
! (such as Cygwin or DJGPP), read the README.WINDOWS file. !
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Look for release with a file of the form:
You should determine if these Makefile variables are reasonable:
calc-x.y.z.v.tar.bz2
INCDIR Where the system include (.h) files are kept.
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.
A release marked with a green "(Latest)" is a production release
that as undergone a fair amount of testing.
You may want to change the default installation locations for
these values, which are based on the 4 values listed above:
A release marked with an orange "(Pre-release)" is likly to be
more stable than the top of the master branch, as they do undergo
thru a reasonable level of regression testing, just not to
the level of a "(Latest)" production release.
HELPDIR where the help directory is installed
CALC_INCDIR where the calc include files are installed
CUSTOMCALDIR where custom *.cal files are installed
CUSTOMHELPDIR where custom help files are installed
CUSTOMINCDIR where custom .h files are installed
SCRIPTDIR where calc shell scripts are installed
Use the followig command to uncompress the bzip2 compressed tarball:
If you want to install calc files under a top level directory,
then set the T value:
bunzip2 -c calc-*.tar.bz2 | tar -xvf -
The calc install is performed under ${T}, the calc build is
performed under /. The purpose for ${T} is to allow someone
to install calc somewhere other than into the system area.
NOTE: An alternate location for calc bzip2 compressed tarballs is:
For example, if:
http://www.isthe.com/chongo/src/calc/
BINDIR= /usr/bin
LIBDIR= /usr/lib
CALC_SHAREDIR= /usr/share/calc
and if:
T= /var/tmp/testing
### Obtaining the experimental top of the master branch calc source
Then the installation locations will be:
You may also fetch the top of the master branch of the GitHub repo
if you wish to see what the latest source code looks like:
calc binary files: /var/tmp/testing/usr/bin
calc link library: /var/tmp/testing/usr/lib
calc help, .cal ...: /var/tmp/testing/usr/share/calc
... etc ... /var/tmp/testing/...
git clone https://github.com/lcn2/calc.git
If ${T} is empty, calc is installed under /, which is the same
top of tree for which it was built. If ${T} is non-empty, then
calc is installed under ${T}, as if one had to chroot under
${T} for calc to operate.
IMPORTANT:
Look for the section that starts:
The latest source code may be "experimental in nature". You may be
better off using a released bzip2 compressed tarball instead.
Released bzip2 compressed tarballs tend to be more well tested
than the top of the master branch.
################
# compiler set #
################
Select a compiler set by commenting in the appropriate set
of cc options. As shipped the Makefile assumes a gcc-like
environment such as Linux. If a more appropriate cc set if
found below, comment out the Linux set and comment in that
set or edit the gcc set or the common cc set as needed.
You may want to change these Makefile variables from their defaults:
## Step 1: Makefile considerations
RANLIB
You may or may not need RANLIB when building libraries.
As shipped the Makefile assumes RANLIB is needed.
Comment the in/out the RANLIB value if ranlib does
not work or does not exist.
### IMPORTANT: Make support of conditional syntax required:
CALCPAGER
To compile calc, you must use a make that supports the use of
"Conditional syntax". As nearly all modern make tools
support "Conditional syntax", thus should not be a problem
for you. If for some reason your make tool does not support
"Conditional syntax", consider upgraded to a make that does,
such as the Gnu Make tool:
You may want to change the default pager used by calc.
As shipped the Makefile assumes 'more'. On your system
you may find 'less' to be a better pager.
https://www.gnu.org/software/make/
DEBUG
The Gnu Make is not required per-se, just a modern make tool
that supports "Conditional syntax".
Some compilers (to put it mildly) have bugs. Sometimes the
DEBUG Makefile variable causes the compiler / optimizer to
produce bad code. Other compilers do just fine.
If possible try to use DEBUG=-O3 -g3 (maximum optimization
and debug symbols). If the calc test fails (see step 3),
try lowering either the -O value and/or the -g3. Also try
using -Osomething without -g.
### Review Makefiles
Adjust other Makefile variables as needed.
Review Makefile.config and Makefile.target.
(2) build calc:
If you are curious, review Makefile as well, although
there may be little in the main Makefile that you may
want to change.
The top level Makefile and the custom/Makefile require a GNU
Make (such as gmake) or an equivalently advanced make. On many
targets, the default make is sufficient. On FreeBSD for example,
one must use gmake instead of make.
Consider modifying Makefile.local by replace values or
appending values found in Makefile.config and Makefile.target.
If your target system does not have GNU Make (or equivalent), then
you should try using the Makefile.simple and custom/Makefile.simple
files:
If you are adding custom functions, review custom/Makefile
and modify custom/Makefile as needed.
mv Makefile Makefile.gmake
cp Makefile.simple Makefile
mv custom/Makefile custom/Makefile.gmake
cp custom/Makefile.simple custom/Makefile
make all
==> We are interested in any compiler warnings (and errors) that
you may find. See the BUGS file if you find any compiler
warning or errors.
### Suggestion: Modify Makefile.local
NOTE: You can force calc to build with only static libs:
All Makefiles include Makefile.local just before the
first and default all rule. So Makefile.local may be
used to modify, replace or append values to Makefile variables.
make clobber
make calc-static-only BLD_TYPE=calc-static-only
In most cases, to change the way that calc is made, consider
adding lines to Makefile.local instead of modifying other Makefiles.
or force calc to build with only dynamic libs:
A recommended way to adjust it is to add lines to: Makefile.local
using the := syntax to replace values such as:
make clobber
make calc-dynamic-only BLD_TYPE=calc-dynamic-only
DEBUG:= -O0 -g
(3) test calc:
or by using the += syntax to append to values such as:
make check
DEBUG+= -ipa
==> If you run into problems, read the BUGS file and follow
the instructions found in there.
You can, of course, modify other Makefiles. We only
suggest using Makefile.local to minimize the number
of source files you modify.
NOTE: For a quiet check which only prints if something goes wrong:
And finally, you can always just add arguments to your
make command line instead of modifying a Makefile. For example:
make chk
make clobber all DEBUG="-O0 -g"
(4) install calc:
make install
## readline package assumed by default:
By "readline package" we refer to the combination of the
readline library, the history library, and the ncurses library.
By default, calc assumes you have the readline package installed.
The readline package (-lreadline, -lhistory, -lncurses) used by and
linked into calc by default.
If your system (such as macOS) does NOT have those libaraies, then
you have two options:
### Install the readline package:
We recommend that you install the readline package first, then compile calc.
For information on the readline package, see:
https://tiswww.case.edu/php/chet/readline/rltop.html
MacOS users can use MacPorts or HomeBrew to install readline:
https://www.macports.org
https://brew.sh
Or compile from the readline.git repo:
http://git.savannah.gnu.org/cgit/readline.git/
### Compile calc without readline:
Why do we not recommend this option because using calc with readline
provides a beter user experience.
If you feel you must use calc without the readline package, then you
will need to compile with:
make clobber all USE_READLINE= READLINE_EXTRAS= READLINE_INCLUDE= READLINE_LIB=
or add to Makefile.local, these lines:
USE_READLINE=
READLINE_EXTRAS=
READLINE_INCLUDE=
READLINE_LIB=
See the "Suggestion: Modify Makefile.local" section above for
information on the Makefile.local file.
### Windows or a Windows-like environments:
Currently Windows is not a well supported platform for calc. There are
people within Microsoft who plan to assist us in being able to allow
the standard Microsoft Windows developor environment to compile calc.
### Makefile variables to consider:
You should determine if these Makefile variables are reasonable:
INCDIR Where the system include (.h) files are kept.
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.
You may want to change the default installation locations for
these values, which are based on the 4 values listed above:
HELPDIR where the help directory is installed
CALC_INCDIR where the calc include files are installed
CUSTOMCALDIR where custom *.cal files are installed
CUSTOMHELPDIR where custom help files are installed
CUSTOMINCDIR where custom .h files are installed
SCRIPTDIR where calc shell scripts are installed
If you want to install calc files under a top level directory, then set the T value:
The calc install is performed under ${T}, the calc build is
performed under /. The purpose for ${T} is to allow someone
to install calc somewhere other than into the system area.
For example, if:
BINDIR= /usr/bin
LIBDIR= /usr/lib
CALC_SHAREDIR= /usr/share/calc
and if:
T= /var/tmp/testing
Then the installation locations will be:
calc binary files: /var/tmp/testing/usr/bin
calc link library: /var/tmp/testing/usr/lib
calc help, .cal ...: /var/tmp/testing/usr/share/calc
... etc ... /var/tmp/testing/...
If ${T} is empty, calc is installed under /, which is the same
top of tree for which it was built. If ${T} is non-empty, then
calc is installed under ${T}, as if one had to chroot under
${T} for calc to operate.
Again, consider adding replacement lines or append linbes to
the Makefile.local file. See "Suggestion Modify Makefile.local
instead of Makefile" above. For example:
T:= /var/tmp/testing
See the "Suggestion: Modify Makefile.local" section above for
information on the Makefile.local file.
### platform target section
The file, Makefile.target, contains information about various platforms.
The current list of targets in Makefile.target are:
- Linux target
- Apple macOS / Darwin target
- FreeBSD target
- OpenBSD target
- Cygwin target (as well as Msys2 / Msys OSNAME)
- simple target
- default target (when target is empty)
If you wish to modiy your target platform, consider doing
so via the Makefile.local file. See "Suggestion Modify Makefile.local
instead of Makefile" above.
## Step 2: compile calc
Remove any previous compile attempts and compile by default:
make clobber all
### Force calc to build with only static libs:
You may force calc to build with only static libs:
make clobber calc-static-only BLD_TYPE=calc-static-only
### Force calc to build with only dynamic shared libs:
You may force calc to build with only dynamic libs:
make clobber calc-dynamic-only BLD_TYPE=calc-dynamic-only
### Reports of compiler warnings (and errors) as welcome
We are interested learning about any compiler warnings (and errors) that you may find.
See the BUGS file if you find any compiler warning or errors.
### Step 3: test calc
You may run the calc regression test suite, after successfully compiling, by:
make check
For a more quiet check which only prints if something goes wrong, use:
make chk
### Step 4: install calc
Depending on permissions, you may need to become the super-user:
sudo -s
before you install:
make install
### Step n: calc help - getting started
Calc is distributed with an extensive collection of help files that
are accessible from the command line. The following assume that you
are running calc from the distribution directory or that you have
installed calc. In these examples, the "; " is the calc prompt, not
something that you type.
For list of help topics:
; help
For overview of calc overview:
; help intro
; help overview
; help command
; help define
; help statement
; help variable
; help usage
For list of builtin functions:
; help builtin
C programmers should note some unexpected differences with the calc syntax:
; help unexpected
Calc is shipped with a standard collection of calc resource files.
For a list of calc standard resource files see:
; help resource
We suggest that you might want to read the README.FIRST file and look at
the calc help subsystem. See also the README.md file.
=-=
In general, if you run into problems, read the BUGS file and follow the instructions.
On calc Makefiles:
# IMPORTANT: parallel make not supported
How to tell the origin of of a Makefile:
We do not support making calc using a parallel make as most parallel
make systems fail to understand the depedency relationships between
a numner of important make rules and thus fail to properly compile calc.
The "# SRC: ... - ..." comment line near the top
of the file indicates the origin of this file.
In each segment below, we indicate what the SRC
comment like will read.
SHELL= ...
On some systems, /bin/sh is a rather reduced shell with
deprecated behavior.
If your system has a up to date, bash shell, then
you may wish to edit the Makefile to use:
SHELL= /bin/bash
On some systems such as macOS, the bash shell is very
far behind to the point where is cannot be depended on.
On such systems, the zsh may be a much better alternative
shell for this Makefile to use:
SHELL= /bin/zsh
Makefile
# SRC: Makefile - Our calc build environment
This is our internal Makefile that drives how we build calc.
For critical rules in Makefile.ship, there is a corresponding
rule in Makefile that calls ${MAKE} -f Makefile.ship with,
additional commands, args and Makefile variables. The ${XVAR}
Makefile variable, for example, is passed on each call to
${MAKE} -f Makefile.ship so that the environment and parameters of
Makefile.ship may be managed for our build environment.
This Makefile is used to make the calc rpm. In addition to these
comments, this Makefile differs from the non-rpm bzip2-ed tarball
source Makefile in at least the the following ways:
CCWERR= -Werror
USE_READLINE= -DUSE_READLINE
READLINE_LIB= -lreadline -lhistory -lncurses
If the Makefile is not suitable for you, then
you may wish to replace it with Makefile.ship:
mv -f -v Makefile.ship Makefile
This Makefile assumes you have a modern make command such as
the GNU make. See Makefile.simple comment below if you do not
have such a modern make command.
In packages such as RPMs, and the tar.bz2 source tarball,
Makefile contains the contents of Makefile.ship. If Makefile.ship
is missing it has likely moved to replace Makefile.
In the calc GitHub repo, Makefile is the calc build environment
and Makefile.ship is the top level Makefile:
https://github.com/lcn2/calc
Makefile.ship
# SRC: Makefile.ship - top level Makefile
This is the main top level Makefile.
In calc packages such as RPMs, and the tar.bz2 source tarball,
Makefile.ship has been moved into Makefile.
In the calc GitHub repo, Makefile is the calc build environment
and Makefile.ship is the top level Makefile:
https://github.com/lcn2/calc
The Makefile.simple rule of Makefile.ship, when forming the
Makefile.simple file, removes lines from Makefile.ship between
pairs of '#if 0' AND '#endif':
#if 0
lines removed when forming Makefile.simple
...
lines removed when forming Makefile.simple
#endif
The '#if 0' AND '#endif' MUST be at the start of the line.
Any text after the '#if 0' OR '#endif' is ignored.
While they may look like a CPP directives, they are not. The
inline awk script of the Makefile.simple rule does NOT allow
them to nest:
#if 0 /* DO NOT DO THIS */
lines removed when forming Makefile.simple
...
#if 0 /* DO NOT DO THIS */
...
#endif /* DO NOT DO THIS */
...
#endif /* DO NOT DO THIS */
The custom/Makefile rule of Makefile.ship is used to form
the custom/Makefile. In particular the Makefile.ship lines:
# start of host target cut
... these go in between custom/Makefile.head and custom/Makefile.tail
# end of host target cut
Makefile.simple
# SRC: non-GNU Makefile via make -f Makefile.ship Makefile.simple
This is a non-GNU or simple Makefile designed for environments
that do not have a modern make command.
If you have a Makefile.simple file, use these commands to
form a Makefile:
if [ -f Makefile ]; then mv -f Makefile Makefile.orig; fi
cp Makefile.simple Makefile
The Makefile.simple rule from Makefile.ship is used to construct
this file from the contents of Makefile.ship.
In calc packages such as RPMs, and the tar.bz2 source the
Makefile.simple exists. In the calc GitHub repo:
https://github.com/lcn2/calc
this file does NOT exist and must be made via the Makefile.simple
make rule. Therefore, non-GNU and simple make commands are NOT
supported by the calc GitHub repo master branch. Instead, you
need to extract Makefile.simple from one of the calc tar.bz2
source tarball source from a calc source mirror:
http://www.isthe.com/chongo/tech/comp/calc/calc-mirror.html
custom/Makefile.head
# SRC: custom/Makefile.head
This file forms the top part of the custom/Makefile.
custom/Makefile.tail
# SRC: custom/Makefile.tail
This file forms the bottom part of the custom/Makefile.
custom/Makefile
# SRC: Makefile via make -f Makefile custom/Makefile
This is the custom directory Makefile.
The custom/Makefile rule of Makefile.ship is used to form
the custom/Makefile. In particular the Makefile.ship lines:
# start of host target cut
... these go in between custom/Makefile.head and custom/Makefile.tail
# end of host target cut
NOTE: The clobber rule does not remove this file. - XXX
custom/Makefile.simple
# SRC: non-GNU Makefile via make -f Makefile custom/Makefile.simple
This is a non-GNU or simple Makefile for the custom directory
that is designed for environments that do not have a modern make
command.
In calc packages such as RPMs, and the tar.bz2 source the
Makefile.simple exists. In the calc GitHub repo:
https://github.com/lcn2/calc
this file does NOT exist and must be made via the
custom/Makefile.simple make rule. Therefore, non-GNU and simple
make commands are NOT supported by the calc GitHub repo master
branch. Instead, you need to extract custom/Makefile.simple
from one of the calc tar.bz2 source tarball source from a calc
source mirror:
http://www.isthe.com/chongo/tech/comp/calc/calc-mirror.html
cal/Makefile
# SRC: cal/Makefile
The Makefile for the cal sub-directory.
cscript/Makefile
# SRC: cscript/Makefile
The Makefile for the cscript sub-directory.
help/Makefile
# SRC: help/Makefile
The Makefile for the help sub-directory.
## Copyright (C) 1999-2007,2021 Landon Curt Noll
## Copyright (C) 1999-2007,2021,2023 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
@@ -435,7 +392,7 @@ help/Makefile
##
## 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
## 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
@@ -443,8 +400,8 @@ help/Makefile
## 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: 1999/09/27 20:48:44
## File existed as early as: 1999
## Under source code control: 1999/09/27 20:48:44
## File existed as early as: 1999
##
## chongo <was here> /\oo/\ http://www.isthe.com/chongo/
## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
## chongo <was here> /\oo/\ http://www.isthe.com/chongo/
## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/

505
LIBRARY
View File

@@ -1,4 +1,4 @@
USING THE ARBITRARY PRECISION ROUTINES IN A C PROGRAM
USING THE ARBITRARY PRECISION ROUTINES IN A C PROGRAM
Part of the calc release consists of an arbitrary precision math link library.
This link library is used by the calc program to perform its own calculations.
@@ -19,9 +19,9 @@ FIRST THINGS FIRST
------------------
...............................................................................
. .
. .
. You MUST call libcalc_call_me_first() prior to using libcalc lib functions! .
. .
. .
...............................................................................
The function libcalc_call_me_first() takes no args and returns void. You
@@ -34,16 +34,16 @@ INCLUDE FILES
To use any of these routines in your own programs, you need to include the
appropriate include file. These include files are:
zmath.h (for integer arithmetic)
qmath.h (for rational arithmetic)
cmath.h (for complex number arithmetic)
zmath.h (for integer arithmetic)
qmath.h (for rational arithmetic)
cmath.h (for complex number arithmetic)
You never need to include more than one of the above files, even if you wish
to use more than one type of arithmetic, since qmath.h automatically includes
zmath.h, and cmath.h automatically includes qmath.h.
The prototypes for the available routines are listed in the above include
files. Some of these routines are meant for internal use, and so aren't
files. Some of these routines are meant for internal use, and so aren't
convenient for outside use. So you should read the source for a routine
to see if it really does what you think it does. I won't guarantee that
obscure internal routines won't change or disappear in future releases!
@@ -61,20 +61,20 @@ to define CALC_SRC.
You need to include the following file to get the symbols and variables
related to error handling:
lib_calc.h
lib_calc.h
External programs may want to compile with:
-I${INCDIR} -L${LIBDIR} -lcalc
-I${INCDIR} -L${LIBDIR} -lcalc
If custom functions are also used, they may want to compile with:
-I${INCDIR} -L${LIBDIR} -lcalc -lcustcalc
-I${INCDIR} -L${LIBDIR} -lcalc -lcustcalc
The CALC_SRC symbol should NOT be defined by default. However if you are
feeling pedantic you may want to force CALC_SRC to be undefined:
-UCALC_SRC
-UCALC_SRC
as well.
@@ -87,64 +87,64 @@ condition, such as malloc failures, division by zero, or some form of
an internal computation error. The routine is called in the manner of
printf, with a format string and optional arguments:
void math_error(char *fmt, ...);
void math_error(char *fmt, ...);
Your program must handle math errors in one of three ways:
1) Print the error message and then exit
There is a math_error() function supplied with the calc library.
By default, this routine simply prints a message to stderr and
then exits. By simply linking in this link library, any calc
errors will result in a error message on stderr followed by
an exit.
There is a math_error() function supplied with the calc library.
By default, this routine simply prints a message to stderr and
then exits. By simply linking in this link library, any calc
errors will result in a error message on stderr followed by
an exit.
2) Use setjmp and longjmp in your program
Use setjmp at some appropriate level in your program, and let
the longjmp in math_error() return to that level and to allow you
to recover from the error. This is what the calc program does.
Use setjmp at some appropriate level in your program, and let
the longjmp in math_error() return to that level and to allow you
to recover from the error. This is what the calc program does.
If one sets up calc_matherr_jmpbuf, and then sets
calc_use_matherr_jmpbuf to non-zero then math_error() will
longjmp back with the return value of calc_use_matherr_jmpbuf.
In addition, the last calc error message will be found in
calc_err_msg; this error is not printed to stderr. The calc
error message will not have a trailing newline.
If one sets up calc_matherr_jmpbuf, and then sets
calc_use_matherr_jmpbuf to non-zero then math_error() will
longjmp back with the return value of calc_use_matherr_jmpbuf.
In addition, the last calc error message will be found in
calc_err_msg; this error is not printed to stderr. The calc
error message will not have a trailing newline.
For example:
For example:
#include <setjmp.h>
#include "lib_calc.h"
#include <setjmp.h>
#include "lib_calc.h"
int error;
int error;
...
...
if ((error = setjmp(calc_matherr_jmpbuf)) != 0) {
if ((error = setjmp(calc_matherr_jmpbuf)) != 0) {
/* report the error */
printf("Ouch: %s\n", calc_err_msg);
/* report the error */
printf("Ouch: %s\n", calc_err_msg);
/* reinitialize calc after the longjmp */
reinitialize();
}
calc_use_matherr_jmpbuf = 1;
/* reinitialize calc after the longjmp */
reinitialize();
}
calc_use_matherr_jmpbuf = 1;
If calc_use_matherr_jmpbuf is non-zero, then the jmp_buf value
calc_matherr_jmpbuf must be initialized by the setjmp() function
or your program will crash.
If calc_use_matherr_jmpbuf is non-zero, then the jmp_buf value
calc_matherr_jmpbuf must be initialized by the setjmp() function
or your program will crash.
3) Supply your own math_error function:
void math_error(char *fmt, ...);
void math_error(char *fmt, ...);
Your math_error() function may exit or transfer control to outside
of the calc library, but it must never return or calc will crash.
Your math_error() function may exit or transfer control to outside
of the calc library, but it must never return or calc will crash.
External programs can obtain the appropriate calc symbols by compiling with:
-I${INCDIR} -L${LIBDIR} -lcalc
-I${INCDIR} -L${LIBDIR} -lcalc
-------------------------
PARSE/SCAN ERROR HANDLING
@@ -159,15 +159,15 @@ any parse/scan errors. By default, this variable it set to 1 and so
parse/scan errors are printed to stderr. By setting this value to zero,
parse/scan errors are not printed:
#include "lib_calc.h"
#include "lib_calc.h"
/* do not print parse/scan errors to stderr */
calc_print_scanerr_msg = 0;
/* do not print parse/scan errors to stderr */
calc_print_scanerr_msg = 0;
The last calc math error or calc parse/scan error message is kept
in the NUL terminated buffer:
char calc_err_msg[MAXERROR+1];
char calc_err_msg[MAXERROR+1];
The value of calc_print_scanerr_msg does not change the use
of the calc_err_msg[] buffer. Messages are stored in that
@@ -182,54 +182,54 @@ Your program must handle parse/scan errors in one of two ways:
1) exit on error
If you do not setup the calc_scanerr_jmpbuf, then when calc
encounters a parse/scan error, a message will be printed to
stderr and calc will exit.
If you do not setup the calc_scanerr_jmpbuf, then when calc
encounters a parse/scan error, a message will be printed to
stderr and calc will exit.
2) Use setjmp and longjmp in your program
Use setjmp at some appropriate level in your program, and let
the longjmp in scanerror() return to that level and to allow you
to recover from the error. This is what the calc program does.
Use setjmp at some appropriate level in your program, and let
the longjmp in scanerror() return to that level and to allow you
to recover from the error. This is what the calc program does.
If one sets up calc_scanerr_jmpbuf, and then sets
calc_use_scanerr_jmpbuf to non-zero then scanerror() will longjmp
back with the return with a non-zero code. In addition, the last
calc error message will be found in calc_err_msg[]; this error is
not printed to stderr. The calc error message will not have a
trailing newline.
If one sets up calc_scanerr_jmpbuf, and then sets
calc_use_scanerr_jmpbuf to non-zero then scanerror() will longjmp
back with the return with a non-zero code. In addition, the last
calc error message will be found in calc_err_msg[]; this error is
not printed to stderr. The calc error message will not have a
trailing newline.
For example:
For example:
#include <setjmp.h>
#include "lib_calc.h"
#include <setjmp.h>
#include "lib_calc.h"
int scan_error;
int scan_error;
...
...
/* delay the printing of the parse/scan error */
calc_use_scanerr_jmpbuf = 0; /* this is optional */
/* delay the printing of the parse/scan error */
calc_use_scanerr_jmpbuf = 0; /* this is optional */
if ((scan_error = setjmp(calc_scanerr_jmpbuf)) != 0) {
if ((scan_error = setjmp(calc_scanerr_jmpbuf)) != 0) {
/* report the parse/scan */
if (calc_use_scanerr_jmpbuf == 0) {
printf("parse error: %s\n", calc_err_msg);
}
/* report the parse/scan */
if (calc_use_scanerr_jmpbuf == 0) {
printf("parse error: %s\n", calc_err_msg);
}
/* initialize calc after the longjmp */
initialize();
}
calc_use_scanerr_jmpbuf = 1;
/* initialize calc after the longjmp */
initialize();
}
calc_use_scanerr_jmpbuf = 1;
If calc_use_scanerr_jmpbuf is non-zero, then the jmp_buf value
calc_scanerr_jmpbuf must be initialized by the setjmp() function
or your program will crash.
If calc_use_scanerr_jmpbuf is non-zero, then the jmp_buf value
calc_scanerr_jmpbuf must be initialized by the setjmp() function
or your program will crash.
External programs can obtain the appropriate calc symbols by compiling with:
-I${INCDIR} -L${LIBDIR} -lcalc
-I${INCDIR} -L${LIBDIR} -lcalc
---------------------------
PARSE/SCAN WARNING HANDLING
@@ -239,22 +239,22 @@ Calc parse/scan warning message are printed to stderr by the warning()
function. The routine is called in the manner of printf, with a format
string and optional arguments:
void warning(char *fmt, ...);
void warning(char *fmt, ...);
The variable, calc_print_scanwarn_msg, controls if calc prints to stderr,
any parse/scan warnings. By default, this variable it set to 1 and so
parse/scan warnings are printed to stderr. By setting this value to zero,
parse/scan warnings are not printed:
#include "lib_calc.h"
#include "lib_calc.h"
/* do not print parse/scan warnings to stderr */
calc_print_scanwarn_msg = 0;
/* do not print parse/scan warnings to stderr */
calc_print_scanwarn_msg = 0;
The last calc calc parse/scan warning message is kept in the NUL
terminated buffer:
char calc_warn_msg[MAXERROR+1];
char calc_warn_msg[MAXERROR+1];
The value of calc_print_scanwarn_msg does not change the use
of the calc_warn_msg[] buffer. Messages are stored in that
@@ -264,19 +264,19 @@ Your program must handle parse/scan warnings in one of two ways:
1) print the warning to stderr and continue
The warning() from libcalc prints warning messages to
stderr and returns. The flow of execution is not changed.
This is what calc does by default.
The warning() from libcalc prints warning messages to
stderr and returns. The flow of execution is not changed.
This is what calc does by default.
2) Supply your own warning function:
void warning(char *fmt, ...);
void warning(char *fmt, ...);
Your warning function should simply return when it is finished.
Your warning function should simply return when it is finished.
External programs can obtain the appropriate calc symbols by compiling with:
-I${INCDIR} -L${LIBDIR} -lcalc
-I${INCDIR} -L${LIBDIR} -lcalc
---------------
@@ -308,7 +308,7 @@ output strings with space filling, output formatted strings like printf, and
flush the output. Output from these routines is diverted as described above.
You can change the default output mode by calling math_setmode, and you can
change the default number of digits printed by calling math_setdigits. These
change the default number of digits printed by calling math_setdigits. These
routines return the previous values. The possible modes are described in
zmath.h.
@@ -320,20 +320,20 @@ The arbitrary precision integer routines define a structure called a ZVALUE.
This is defined in zmath.h. A ZVALUE contains a pointer to an array of
integers, the length of the array, and a sign flag. The array is allocated
using malloc, so you need to free this array when you are done with a
ZVALUE. To do this, you should call zfree with the ZVALUE as an argument
(or call freeh with the pointer as an argument) and never try to free the
array yourself using free. The reason for this is that sometimes the pointer
points to one of two statically allocated arrays which should NOT be freed.
ZVALUE. To do this, you should call zfree() with the ZVALUE as an argument
and never try to free the array yourself using free(). The reason for this
is that sometimes the pointer points to a statically allocated arrays which
should NOT be freed.
The ZVALUE structures are passed to routines by value, and are returned
through pointers. For example, to multiply two small integers together,
you could do the following:
ZVALUE z1, z2, z3;
ZVALUE z1, z2, z3;
itoz(3L, &z1);
itoz(4L, &z2);
zmul(z1, z2, &z3);
itoz(3L, &z1);
itoz(4L, &z2);
zmul(z1, z2, &z3);
Use zcopy to copy one ZVALUE to another. There is no sharing of arrays
between different ZVALUEs even if they have the same value, so you MUST
@@ -344,7 +344,7 @@ values of 0 and 1 are so common that special checks are made for them.
For initial values besides 0 or 1, you need to call itoz to convert a long
value into a ZVALUE, as shown in the above example. Or alternatively,
for larger numbers you can use the atoz routine to convert a string which
for larger numbers you can use the str2z routine to convert a string which
represents a number into a ZVALUE. The string can be in decimal, octal,
hex, or binary according to the leading digits.
@@ -354,72 +354,84 @@ address to a routine as a destination value, otherwise memory will be
lost. The following shows an example of the correct way to free memory
over a long sequence of operations.
ZVALUE z1, z2, z3;
ZVALUE z1, z2, z3;
z1 = _one_;
atoz("12345678987654321", &z2);
zadd(z1, z2, &z3);
zfree(z1);
zfree(z2);
zsquare(z3, &z1);
zfree(z3);
itoz(17L, &z2);
zsub(z1, z2, &z3);
zfree(z1);
zfree(z2);
zfree(z3);
z1 = _one_;
str2z("12345678987654321", &z2);
zadd(z1, z2, &z3);
zfree(z1);
zfree(z2);
zsquare(z3, &z1);
zfree(z3);
itoz(17L, &z2);
zsub(z1, z2, &z3);
zfree(z1);
zfree(z2);
zfree(z3);
There are some quick checks you can make on integers. For example, whether
or not they are zero, negative, even, and so on. These are all macros
defined in zmath.h, and should be used instead of checking the parts of the
ZVALUE yourself. Examples of such checks are:
ziseven(z) (number is even)
zisodd(z) (number is odd)
ziszero(z) (number is zero)
zisneg(z) (number is negative)
zispos(z) (number is positive)
zisunit(z) (number is 1 or -1)
zisone(z) (number is 1)
zisnegone(z) (number is -1)
zistwo(z) (number is 2)
zisabstwo(z) (number is 2 or -2)
zisabsleone(z) (number is -1, 0 or 1)
zislezero(z) (number is <= 0)
zisleone(z) (number is <= 1)
zge16b(z) (number is >= 2^16)
zge24b(z) (number is >= 2^24)
zge31b(z) (number is >= 2^31)
zge32b(z) (number is >= 2^32)
zge64b(z) (number is >= 2^64)
ziseven(z) (number is even)
zisodd(z) (number is odd)
ziszero(z) (number is zero)
zisneg(z) (number is negative)
zispos(z) (number is positive)
zisunit(z) (number is 1 or -1)
zisone(z) (number is 1)
zisnegone(z) (number is -1)
zistwo(z) (number is 2)
zisabstwo(z) (number is 2 or -2)
zisabsleone(z) (number is -1, 0 or 1)
zislezero(z) (number is <= 0)
zisleone(z) (number is <= 1)
zge16b(z) (number is >= 2^16)
zge24b(z) (number is >= 2^24)
zge31b(z) (number is >= 2^31)
zge32b(z) (number is >= 2^32)
zge64b(z) (number is >= 2^64)
Typically the largest unsigned long is typedefed to FULL. The following
macros are useful in dealing with this data type:
MAXFULL (largest positive FULL value)
MAXUFULL (largest unsigned FULL value)
zgtmaxfull(z) (number is > MAXFULL)
zgtmaxufull(z) (number is > MAXUFULL)
zgtmaxlong(z) (number is > MAXLONG, largest long value)
zgtmaxulong(z) (number is > MAXULONG, largest unsigned long value)
MAXFULL (largest positive FULL value)
MAXUFULL (largest unsigned FULL value)
zgtmaxfull(z) (number is > MAXFULL)
zgtmaxufull(z) (number is > MAXUFULL)
zgtmaxlong(z) (number is > MAXLONG, largest long value)
zgtmaxulong(z) (number is > MAXULONG, largest unsigned long value)
If zgtmaxufull(z) is false, then one may quickly convert the absolute
value of number into a full with the macro:
ztofull(z) (convert abs(number) to FULL)
ztoulong(z) (convert abs(number) to an unsigned long)
ztolong(z) (convert abs(number) to a long)
ztofull(z) (convert abs(number) to FULL)
ztoulong(z) (convert abs(number) to an unsigned long)
ztolong(z) (convert abs(number) to a long)
If the value is too large for ztofull(), ztoulong() or ztolong(), only
the low order bits converted.
There are two types of comparisons you can make on ZVALUEs. This is whether
or not they are equal, or the ordering on size of the numbers. The zcmp
function tests whether two ZVALUEs are equal, returning TRUE if they differ.
or not they are equal, or the ordering on size of the numbers. The zcmp
function tests whether two ZVALUEs are equal, returning true if they differ.
The zrel function tests the relative sizes of two ZVALUEs, returning -1 if
the first one is smaller, 0 if they are the same, and 1 if the first one
is larger.
To determine if z is an integer power of 2, use zispowerof2:
ZVALUE z; /* value to check if it is a power of */
FULL log2; /* set to log base 2 of z when is_power_of_2 is true */
bool is_power_of_2;
is_power_of_2 = zispowerof2(z, &log2)
Returns true if z an integer power of 2: set log2 to log base 2 of z.
Returns false if z is NOT integer power of 2 and leave log2 untouched.
The log2 arg must be a non-NULL pointer to a ZVALUE.
---------------
USING FRACTIONS
---------------
@@ -433,34 +445,35 @@ is always positive. If the NUMBER is an integer, the denominator has the
value 1.
Unlike ZVALUEs, NUMBERs are passed using pointers, and pointers to them are
returned by functions. So the basic type for using fractions is not really
returned by functions. So the basic type for using fractions is not really
(NUMBER), but is (NUMBER *). NUMBERs are allocated using the qalloc routine.
This returns a pointer to a number which has the value 1. Because of the
special property of a ZVALUE of 1, the numerator and denominator of this
returned value can simply be overwritten with new ZVALUEs without needing
to free them first. The following illustrates this:
NUMBER *q;
NUMBER *q;
q = qalloc();
itoz(55L, &q->num);
q = qalloc();
itoz(55L, &q->num);
A better way to create NUMBERs with particular values is to use the itoq,
iitoq, or atoq functions. Using itoq makes a long value into a NUMBER,
iitoq, or str2q functions. Using itoq makes a long value into a NUMBER,
using iitoq makes a pair of longs into the numerator and denominator of a
NUMBER (reducing them first if needed), and atoq converts a string representing
a number into the corresponding NUMBER. The atoq function accepts input in
NUMBER (reducing them first if needed), and str2q converts a string representing
a number into the corresponding NUMBER. The str2q function accepts input in
integral, fractional, real, or exponential formats. Examples of allocating
numbers are:
NUMBER *q1, *q2, *q3;
NUMBER *q1, *q2, *q3, *q4;
q1 = itoq(66L);
q2 = iitoq(2L, 3L);
q3 = atoq("456.78");
q1 = itoq(66L);
q2 = iitoq(2L, 3L);
q3 = str2q("456.78");
q4 = utoq((FULL) 1234567890L);
Also unlike ZVALUEs, NUMBERs are quickly copied. This is because they contain
a link count, which is the number of pointers there are to the NUMBER. The
a link count, which is the number of pointers there are to the NUMBER. The
qlink macro is used to copy a pointer to a NUMBER, and simply increments
the link count and returns the same pointer. Since it is a macro, the
argument should not be a function call, but a real pointer variable. The
@@ -473,14 +486,16 @@ the ZVALUEs contained within the NUMBER, and then puts the NUMBER structure
onto a free list for quick reuse. The following is an example of allocating
NUMBERs, copying them, adding them, and finally deleting them again.
NUMBER *q1, *q2, *q3;
NUMBER *q1, *q2, *q3, *q4;
q1 = itoq(111L);
q2 = qlink(q1);
q3 = qqadd(q1, q2);
qfree(q1);
qfree(q2);
qfree(q3);
q1 = itoq(111L);
q2 = qlink(q1);
q3 = qqadd(q1, q2);
q4 = qnum(q2, q3);
qfree(q1);
qfree(q2);
qfree(q3);
Because of the passing of pointers and the ability to copy numbers easily,
you might wish to use the rational number routines even for integral
@@ -498,52 +513,66 @@ There are some transcendental functions in the link library, such as sin
and cos. These cannot be evaluated exactly as fractions. Therefore,
they accept another argument which tells how accurate you want the result.
This is an "epsilon" value, and the returned value will be within that
quantity of the correct value. This is usually an absolute difference,
quantity of the correct value. This is usually an absolute difference,
but for some functions (such as exp), this is a relative difference.
For example, to calculate sin(0.5) to 100 decimal places, you could do:
NUMBER *q, *ans, *epsilon;
NUMBER *q, *ans, *epsilon;
q = atoq("0.5");
epsilon = atoq("1e-100");
ans = qsin(q, epsilon);
q = str2q("0.5");
epsilon = str2q("1e-100");
ans = qsin(q, epsilon);
There are many convenience macros similar to the ones for ZVALUEs which can
give quick information about NUMBERs. In addition, there are some new ones
applicable to fractions. These are all defined in qmath.h. Some of these
macros are:
qiszero(q) (number is zero)
qisneg(q) (number is negative)
qispos(q) (number is positive)
qisint(q) (number is an integer)
qisfrac(q) (number is fractional)
qisunit(q) (number is 1 or -1)
qisone(q) (number is 1)
qisnegone(q) (number is -1)
qistwo(q) (number is 2)
qiseven(q) (number is an even integer)
qisodd(q) (number is an odd integer)
qistwopower(q) (number is a power of 2 >= 1)
qiszero(q) (number is zero)
qisneg(q) (number is negative)
qispos(q) (number is positive)
qisint(q) (number is an integer)
qisfrac(q) (number is fractional)
qisunit(q) (number is 1 or -1)
qisone(q) (number is 1)
qisnegone(q) (number is -1)
qistwo(q) (number is 2)
qiseven(q) (number is an even integer)
qisodd(q) (number is an odd integer)
qisreciprocal(q) (number is 1 / an integer and q != 0)
The comparisons for NUMBERs are similar to the ones for ZVALUEs. You use the
qcmp and qrel functions.
There are four predefined values for fractions. You should qlink them when
There are four predefined values for fractions. You should qlink them when
you want to use them. These are _qzero_, _qone_, _qnegone_, and _qonehalf_.
These have the values 0, 1, -1, and 1/2. An example of using them is:
NUMBER *q1, *q2;
NUMBER *q1, *q2;
q1 = qlink(&_qonehalf_);
q2 = qlink(&_qone_);
q1 = qlink(&_qonehalf_);
q2 = qlink(&_qone_);
To determine if q is an integer power of 2, use qispowerof2:
NUMBER *q; /* value to check if it is a power of */
NUMBER *qlog2; /* set to log base 2 of q when is_power_of_2 is true */
bool is_power_of_2;
q = utoq((FULL) 1234567890L);
qlog2 = qalloc();
is_power_of_2 = qispowerof2(q, &qlog2);
Returns true if q an integer power of 2: set *qlog2 to log base 2 of q.
Returns false if q is NOT integer power of 2 and leave *qlog2 untouched.
Use qalloc() to setup the qlog2 arg before calling.
---------------------
USING COMPLEX NUMBERS
---------------------
The arbitrary precision complex arithmetic routines define a structure
called COMPLEX. This is defined in cmath.h. This contains two NUMBERs
called COMPLEX. This is defined in cmath.h. This contains two NUMBERs
for the real and imaginary parts of a complex number, and a count of the
number of links there are to this COMPLEX number.
@@ -554,19 +583,19 @@ fractional parts using qqtoc. You can copy COMPLEX values using clink
which increments the link count. And you free a COMPLEX value using cfree.
The following example illustrates this:
NUMBER *q1, *q2;
COMPLEX *c1, *c2, *c3;
NUMBER *q1, *q2;
COMPLEX *c1, *c2, *c3;
q1 = itoq(3L);
q2 = itoq(4L);
c1 = qqtoc(q1, q2);
qfree(q1);
qfree(q2);
c2 = clink(c1);
c3 = cmul(c1, c2);
cfree(c1);
cfree(c2);
cfree(c3);
q1 = itoq(3L);
q2 = itoq(4L);
c1 = qqtoc(q1, q2);
qfree(q1);
qfree(q2);
c2 = clink(c1);
c3 = cmul(c1, c2);
cfree(c1);
cfree(c2);
cfree(c3);
As a shortcut, when you want to manipulate a COMPLEX value by a real value,
you can use the caddq, csubq, cmulq, and cdivq routines. These accept one
@@ -576,53 +605,77 @@ There is no direct routine to convert a string value into a COMPLEX value.
But you can do this yourself by converting two strings into two NUMBERS,
and then using the qqtoc routine.
COMPLEX values are always returned from these routines. To split out the
COMPLEX values are always returned from these routines. To split out the
real and imaginary parts into normal NUMBERs, you can simply qlink the
two components, as shown in the following example:
COMPLEX *c;
NUMBER *rp, *ip;
COMPLEX *c;
NUMBER *rp, *ip;
c = calloc();
rp = qlink(c->real);
ip = qlink(c->imag);
c = calloc();
rp = qlink(c->real);
ip = qlink(c->imag);
There are many macros for checking quick things about complex numbers,
similar to the ZVALUE and NUMBER macros. In addition, there are some
only used for complex numbers. Examples of macros are:
only used for complex numbers. Examples of macros are:
cisreal(c) (number is real)
cisimag(c) (number is pure imaginary)
ciszero(c) (number is zero)
cisnegone(c) (number is -1)
cisone(c) (number is 1)
cisrunit(c) (number is 1 or -1)
cisiunit(c) (number is i or -i)
cisunit(c) (number is 1, -1, i, or -i)
cistwo(c) (number is 2)
cisint(c) (number is has integer real and imaginary parts)
ciseven(c) (number is has even real and imaginary parts)
cisodd(c) (number is has odd real and imaginary parts)
cisreal(c) (number is real)
cisimag(c) (number is pure imaginary)
ciszero(c) (number is zero)
cisnegone(c) (number is -1)
cisone(c) (number is 1)
cisrunit(c) (number is 1 or -1)
cisiunit(c) (number is i or -i)
cisunit(c) (number is 1, -1, i, or -i)
cistwo(c) (number is 2)
cisint(c) (number is has integer real and imaginary parts)
ciseven(c) (number is has even real and imaginary parts)
cisodd(c) (number is has odd real and imaginary parts)
There is only one comparison you can make for COMPLEX values, and that is
for equality. The ccmp function returns TRUE if two complex numbers differ.
for equality. The ccmp function returns true if two complex numbers differ.
There are three predefined values for complex numbers. You should clink
them when you want to use them. They are _czero_, _cone_, and _conei_.
Sometimes to results of a COMPLEX based calculation is a real number.
That is, the imaginary part of the COMPLEX is 0. You may convert the
COMPLEX into a new allocated NUMBER that is real part of the COMPLEX value.
For example:
COMPLEX *c;
NUMBER *q;
bool ok_to_free; /* true ==> free COMPLEX value, false ==> do not */
if (cisreal(c)) {
q = c_to_q(c, ok_to_free);
}
The 2nd argument to c_to_q() determines if the complex argument should be freed
or not. Pass a false value as the 2nd arg if you wish to continue to use the
COMPLEX value.
To convert a NUMBER into a COMPLEX value, use:
COMPLEX *c;
NUMBER *q;
c = q_to_c(q);
There are three predefined values for complex numbers. You should clink
them when you want to use them. They are _czero_, _cone_, and _conei_.
These have the values 0, 1, and i.
----------------
LAST THINGS LAST
----------------
If you wish, when you are all doen you can call libcalc_call_me_last()
If you wish, when you are all done you can call libcalc_call_me_last()
to free a small amount of storage associated with the libcalc_call_me_first()
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,2023 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
@@ -630,7 +683,7 @@ need call libcalc_call_me_last() only once.
##
## 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
## 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
@@ -638,8 +691,8 @@ need call libcalc_call_me_last() only once.
## 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: 1993/07/30 19:44:49
## File existed as early as: 1993
## Under source code control: 1993/07/30 19:44:49
## File existed as early as: 1993
##
## chongo <was here> /\oo/\ http://www.isthe.com/chongo/
## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
## chongo <was here> /\oo/\ http://www.isthe.com/chongo/
## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/

6411
Makefile

File diff suppressed because it is too large Load Diff

1383
Makefile.config Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1 +1,100 @@
# Add below to override Makefile values (using :=) as in: HAVE_STRING_H:= YES
#!/usr/bin/env make
#
# Makefile.local - modify, replace or append calc Makefile variables
#
# Copyright (C) 2023 Landon Curt Noll
#
# Suggestion: Read the HOWTO.INSTALL file.
#
# Calc is open software; you can redistribute it and/or modify it under
# the terms of version 2.1 of the GNU Lesser General Public License
# 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.
# 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#
# This calculator first developed by David I. Bell with help/mods from others.
#
# chongo <was here> /\oo/\ http://www.isthe.com/chongo/
# Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
####
# This file is included all calc Makefiles after the last Makefile variable
# is set and before the first make rule. This makes this file suitable to
# modify, replace or append Makefile variables.
#
# To replace a Makefile variable, use := symbols. For example:
#
# CCWERR:= -Werror
# DEBUG:= -O0 -g
#
# You can append to an existing Makefile variable using '+=' symbols.
# For example:
#
# CCOPT+= -Ofast
# COMMON_CFLAGS+= -std=gnu2x
####
###################################################################
# NOTE: For this and other commended out examples in this file, #
# you need to remove the leading '#<whitespaces>' to take effect. #
# #
# Comments start with a #-character. #
###################################################################
####
# Force calc to install under /usr/local
#
# PREFIX:= /usr/local
# BINDIR:= ${PREFIX}/bin
# LIBDIR:= ${PREFIX}/lib
# CALC_SHAREDIR:= ${PREFIX}/share/calc
# CALC_INCDIR:= ${PREFIX}/include/calc
####
####
# macOS Address Sanitizer (ASAN)
#
# This comment block was tested under:
#
# macOS 14.0 with Apple clang version 15.0.0 (clang-1500.0.40.1) for arm64
#
# See the FSANITIZE comment block in Makefile.config for common FSANITIZE values and more info.
#
# To use the Address Sanitizer, uncomment this set set of lines and recompile (make clobber all):
#
# FSANITIZE+= -fsanitize=nullability-arg
# FSANITIZE+= -fsanitize=nullability-assign
# FSANITIZE+= -fsanitize=nullability-return
# CFLAGS+= ${FSANITIZE}
# LDFLAGS+= ${FSANITIZE}
# DEBUG:= -O0 -g3
####
####
# RHEL (Linux) Address Sanitizer (ASAN)
#
# This comment block was tested under:
#
# RHEL9.2 with clang version 15.0.7 (Red Hat 15.0.7-2.el9) for x86_64
#
# with these RPMs installed:
#
# libasan-11.3.1-4.3.el9.x86_64 libubsan-11.3.1-4.3.el9.x86_64
#
# See the FSANITIZE comment block in Makefile.config for common FSANITIZE values and more info.
#
# To use the Address Sanitizer, uncomment this set set of lines and recompile (make clobber all):
#
# FSANITIZE+= -fsanitize=bounds
# CFLAGS+= ${FSANITIZE}
# LDFLAGS+= ${FSANITIZE}
# DEBUG:= -O0 -g3
###

File diff suppressed because it is too large Load Diff

432
Makefile.target Normal file
View File

@@ -0,0 +1,432 @@
#!/usr/bin/env make
#
# Makefile.target - platform target section
#
# Copyright (C) 2023 Landon Curt Noll
#
# Suggestion: Read the HOWTO.INSTALL file.
#
# Calc is open software; you can redistribute it and/or modify it under
# the terms of version 2.1 of the GNU Lesser General Public License
# 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.
# 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#
# This calculator first developed by David I. Bell with help/mods from others.
#
# chongo <was here> /\oo/\ http://www.isthe.com/chongo/
# Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
# SUGGESTION: Instead of modifying this file, consider adding
# statements to modify, replace or append Makefile
# variables in the Makefile.local file.
#######################################################################
# NOTE: These lines are included by both Makefile and custom/Makefile #
#######################################################################
##################################################################################
#-=-=-=-=-=- platform target section - targets that override defaults -=-=-=-=-=-#
##################################################################################
# Common values set in targets
#
# BLD_TYPE determines if calc is built with static and/or dynamic libs.
# Set this value to one of:
#
# BLD_TYPE= calc-dynamic-only
# BLD_TYPE= calc-static-only
#
# CC_SHARE are flags given to ${CC} to build .o files suitable for shared libs
# DEFAULT_LIB_INSTALL_PATH is where calc programs look for calc shared libs
# LD_SHARE are common flags given to ${CC} to link with shared libraries
# LIBCALC_SHLIB are flags given to ${CC} to build libcalc shared libraries
# LIBCUSTCALC_SHLIB are flags given to ${CC} to build libcustcalc shared lib
#
# NOTE: The above 5 values are unused if BLD_TYPE= calc-static-only
#
# CC_STATIC are flags given to ${CC} to build .o files suitable for static libs
# LD_STATIC are common flags given to ${CC} to link with static libraries
# LIBCALC_STATIC are flags given to ${CC} to build libcalc static libraries
# LIBCUSTCALC_STATIC are flags given to ${CC} to build libcustcalc static lib
#
# NOTE: The above 4 values are unused if BLD_TYPE= calc-dynamic-only
#
# CCOPT are flags given to ${CC} for optimization
# CCWARN are flags given to ${CC} for warning message control
#
# The following are given to ${CC}:
#
# WNO_IMPLICT
# WNO_ERROR_LONG_LONG
# WNO_LONG_LONG
#
# when compiling special .o files that may need special compile options:
#
# NOTE: These flags simply turn off certain compiler warnings,
# which is useful only when CCWERR is set to -Werror.
#
# NOTE: If your compiler does not have these -Wno files, just
# set these variables to nothing as in:
#
# WNO_IMPLICT=
# WNO_ERROR_LONG_LONG=
# WNO_LONG_LONG=
#
# CCWERR are flags given to ${CC} to make warnings fatal errors
# NOTE: CCWERR is only set in development Makefiles and must only be
# used with ${CC}, not ${LCC}. If you do not want the compiler
# to abort on warnings, then leave CCWERR blank.
# CCMISC are misc flags given to ${CC}
#
# CCBAN is given to ${CC} in order to control if banned.h is in effect.
# NOTE: See where CCBAN is defined above for details.
#
# LCC is how the C compiler is invoked on locally executed intermediate programs
# CC is how the C compiler is invoked (with an optional Purify)
#
# Specific target overrides or modifications to default values
################
# Linux target #
################
ifeq ($(target),Linux)
# default build type for this target
#
BLD_TYPE= calc-dynamic-only
# target specific library parameters
#
CC_SHARE= -fPIC
DEFAULT_LIB_INSTALL_PATH= ${PWD}:/lib:/usr/lib:${LIBDIR}:${PREFIX}/lib
LD_SHARE= "-Wl,-rpath,${DEFAULT_LIB_INSTALL_PATH}" \
"-Wl,-rpath-link,${DEFAULT_LIB_INSTALL_PATH}"
LIBCALC_SHLIB= -shared "-Wl,-soname,libcalc${LIB_EXT_VERSION}"
LIBCUSTCALC_SHLIB= -shared "-Wl,-soname,libcustcalc${LIB_EXT_VERSION}"
# static library option
#
CC_STATIC=
LD_STATIC=
LIBCALC_STATIC=
LIBCUSTCALC_STATIC=
# common values set for this target
#
#CCWARN= -Wall
CCWARN= -Wall -Wextra -pedantic
WNO_IMPLICT= -Wno-implicit
WNO_ERROR_LONG_LONG= -Wno-error=long-long
WNO_LONG_LONG= -Wno-long-long
CCWERR=
CCOPT= ${DEBUG}
CCMISC=
LCC= gcc
CC= ${PURIFY} ${LCC} ${CCWERR}
endif # ($(target),Linux)
###############################
# Apple macOS / Darwin target #
###############################
ifeq ($(target),Darwin)
# default build type for this target
#
BLD_TYPE= calc-dynamic-only
# For old Apple Power PC systems, we need to add:
#
# -std=gnu99 -arch ppc
#
ifeq ($(arch),powerpc)
COMMON_ADD+= -std=gnu99
ARCH_CFLAGS+= -arch ppc
endif # ($(arch),powerpc)
# target specific library parameters
#
CC_SHARE= -fPIC
DEFAULT_LIB_INSTALL_PATH= ${PWD}:${LIBDIR}:${PREFIX}/lib
LD_SHARE= ${ARCH_CFLAGS}
LIBCALC_SHLIB= -dynamiclib -undefined dynamic_lookup \
-install_name ${LIBDIR}/libcalc${LIB_EXT_VERSION} \
-current_version ${VER} \
${ARCH_CFLAGS}
LIBCUSTCALC_SHLIB= -dynamiclib -undefined dynamic_lookup \
-install_name ${LIBDIR}/libcustcalc${LIB_EXT_VERSION} \
-current_version ${VER} \
${ARCH_CFLAGS}
# To reduce dependency chains under macOS, we remove functions and
# data that are unreachable by the entry point or exported symbols.
#
COMMON_LDFLAGS+= -Wl,-dead_strip
COMMON_LDFLAGS+= -Wl,-dead_strip_dylibs
# static library option
#
CC_STATIC=
LD_STATIC= ${ARCH_CFLAGS}
LIBCALC_STATIC=
LIBCUSTCALC_STATIC=
# common values set for this target
#
#CCWARN= -Wall
CCWARN= -Wall -Wextra -pedantic
WNO_IMPLICT= -Wno-implicit
WNO_ERROR_LONG_LONG= -Wno-error=long-long
WNO_LONG_LONG= -Wno-long-long
CCWERR=
CCOPT= ${DEBUG}
CCMISC= ${ARCH_CFLAGS}
LCC= cc
CC= ${PURIFY} ${LCC} ${CCWERR}
# Darwin dynamic shared lib filenames
#
LIB_EXT:= .dylib
LIB_EXT_VERSION:= .${VERSION}${LIB_EXT}
# LDCONFIG not required on this platform, so we redefine it to an empty string
#
LDCONFIG:=
endif # ($(target),Darwin)
##################
# FreeBSD target #
##################
ifeq ($(target),FreeBSD)
# default build type for this target
#
BLD_TYPE= calc-dynamic-only
# target specific library parameters
#
CC_SHARE= -fPIC
DEFAULT_LIB_INSTALL_PATH= ${PWD}:/lib:/usr/lib:${LIBDIR}:${PREFIX}/lib
LD_SHARE= "-Wl,-rpath,${DEFAULT_LIB_INSTALL_PATH}" \
"-Wl,-rpath-link,${DEFAULT_LIB_INSTALL_PATH}"
LIBCALC_SHLIB= -shared "-Wl,-soname,libcalc${LIB_EXT_VERSION}"
LIBCUSTCALC_SHLIB= -shared "-Wl,-soname,libcustcalc${LIB_EXT_VERSION}"
CC_STATIC=
LD_STATIC=
LIBCALC_STATIC=
LIBCUSTCALC_STATIC=
# common values set for this target
#
#CCWARN= -Wall
CCWARN= -Wall -Wextra -pedantic
WNO_IMPLICT= -Wno-implicit
WNO_ERROR_LONG_LONG= -Wno-error=long-long
WNO_LONG_LONG= -Wno-long-long
CCWERR=
CCOPT= ${DEBUG}
CCMISC=
LCC= gcc
CC= ${PURIFY} ${LCC} ${CCWERR}
# We must use gmake as the FreeBSD target because under some older
# releases of FreeBSD, make not support conditional syntax.
#
MAKE= gmake
endif # ($(target),FreeBSD)
##################
# OpenBSD target #
##################
ifeq ($(target),OpenBSD)
# default build type for this target
#
BLD_TYPE= calc-dynamic-only
# default build type for this target
#
CC_SHARE= -fPIC
DEFAULT_LIB_INSTALL_PATH= ${PWD}:/lib:/usr/lib:${LIBDIR}:${PREFIX}/lib
LD_SHARE= "-Wl,-rpath,${DEFAULT_LIB_INSTALL_PATH}" \
"-Wl,-rpath-link,${DEFAULT_LIB_INSTALL_PATH}"
LIBCALC_SHLIB= -shared "-Wl,-soname,libcalc${LIB_EXT_VERSION}"
LIBCUSTCALC_SHLIB= -shared "-Wl,-soname,libcustcalc${LIB_EXT_VERSION}"
# static library option
#
CC_STATIC=
LD_STATIC=
LIBCALC_STATIC=
LIBCUSTCALC_STATIC=
# common values set for this target
#
#CCWARN= -Wall
CCWARN= -Wall -Wextra -pedantic
WNO_IMPLICT= -Wno-implicit
WNO_ERROR_LONG_LONG= -Wno-error=long-long
WNO_LONG_LONG= -Wno-long-long
CCWERR=
CCOPT= ${DEBUG}
CCMISC=
#
LCC= gcc
CC= ${PURIFY} ${LCC} ${CCWERR}
#
MAKE= gmake
#
endif # ($(target),OpenBSD)
#################
# Cygwin target #
#################
ifeq ($(target),Cygwin)
BLD_TYPE= calc-static-only
# target specific library parameters
#
CC_SHARE= -fPIC
DEFAULT_LIB_INSTALL_PATH= ${PWD}:/lib:/usr/lib:${LIBDIR}:${PREFIX}/lib
LD_SHARE= "-Wl,-rpath,${DEFAULT_LIB_INSTALL_PATH}" \
"-Wl,-rpath-link,${DEFAULT_LIB_INSTALL_PATH}"
LIBCALC_SHLIB= -shared "-Wl,-soname,libcalc${LIB_EXT_VERSION}"
LIBCUSTCALC_SHLIB= -shared "-Wl,-soname,libcustcalc${LIB_EXT_VERSION}"
# static library option
#
CC_STATIC=
LIBCALC_STATIC=
LIBCUSTCALC_STATIC=
LD_STATIC=
# common values set for this target
#
#CCWARN= -Wall
CCWARN= -Wall -Wextra -pedantic
WNO_IMPLICT= -Wno-implicit
WNO_ERROR_LONG_LONG= -Wno-error=long-long
WNO_LONG_LONG= -Wno-long-long
CCWERR=
CCOPT= ${DEBUG}
CCMISC=
LCC= cc
CC= ${PURIFY} ${LCC} ${CCWERR}
endif # ($(target),Cygwin)
###########################################
# default target - (when target is empty) #
###########################################
# NOTE: This is the default generic host target. Used when no other
# host target matches.
ifeq ($(target),)
# default build type for this target
#
BLD_TYPE= calc-static-only
# target specific library parameters
#
CC_SHARE= -fPIC
DEFAULT_LIB_INSTALL_PATH= ${PWD}:/lib:/usr/lib:${LIBDIR}:${PREFIX}/lib
LD_SHARE= "-Wl,-rpath,${DEFAULT_LIB_INSTALL_PATH}" \
"-Wl,-rpath-link,${DEFAULT_LIB_INSTALL_PATH}"
LIBCALC_SHLIB= -shared "-Wl,-soname,libcalc${LIB_EXT_VERSION}"
LIBCUSTCALC_SHLIB= -shared "-Wl,-soname,libcustcalc${LIB_EXT_VERSION}"
# static library option
#
CC_STATIC=
LIBCALC_STATIC=
LIBCUSTCALC_STATIC=
LD_STATIC=
# common values set for this target
#
#CCWARN= -Wall
CCWARN= -Wall -Wextra -pedantic
WNO_IMPLICT= -Wno-implicit
WNO_ERROR_LONG_LONG= -Wno-error=long-long
WNO_LONG_LONG= -Wno-long-long
CCWERR=
CCOPT= ${DEBUG}
CCMISC=
LCC= gcc
CC= ${PURIFY} ${LCC} ${CCWERR}
endif # ($(target),)
###########################################
# Set the default compile flags for ${CC} #
###########################################
# If you want to add flags to all compiler and linker
# run (via ${COMMON_CFLAGS} and ${COMMON_LDFLAGS}),
# set ${COMMON_ADD}.
#
# For example to use gcc's -Werror to force warnings
# to become errors, call make with:
#
# make .. COMMON_ADD='-Werror'
#
# This facility requires a Gnu Makefile, or a make command
# that understands the += make operand.
#
COMMON_CFLAGS+= ${COMMON_ADD}
COMMON_LDFLAGS+= ${COMMON_ADD}
# Required flags to compile C files for calc
#
# ICFLAGS are given to ${CC} for intermediate programs used to help compile calc
# CFLAGS are given to ${CC} for calc programs other than intermediate programs
#
# NOTE: This does not work for: make-XYZ-only and BLD_TYPE != make-XYZ-only
#
ifeq ($(BLD_TYPE),calc-static-only)
ICFLAGS= ${COMMON_CFLAGS} ${CCBAN} ${CC_STATIC}
else # ($(BLD_TYPE),calc-static-only)
ICFLAGS= ${COMMON_CFLAGS} ${CCBAN} ${CC_SHARE}
endif # ($(BLD_TYPE),calc-static-only)
CFLAGS= ${ICFLAGS} ${CCOPT}
# Required flags to link files for calc
#
# ILDFLAGS for ${CC} in linking intermediate programs used to help compile calc
# LDFLAGS for ${CC} in linking calc programs other than intermediate programs
#
ILDFLAGS= ${COMMON_LDFLAGS}
LDFLAGS= ${LD_DEBUG} ${ILDFLAGS}
#######################################################################
#-=-=-=-=-=- end of target section - only make rules below -=-=-=-=-=-#
#######################################################################

View File

@@ -1,37 +1,28 @@
If you have a simple general question about calc, send Email to:
If you have a general question about calc, consider opening
a new Github discussion under:
calc-quest-mail at asthe dot com
https://github.com/lcn2/calc/discussions
NOTE: Remove spaces and replace 'at' with @, and 'dot' with .
Look over the existing discussions to see of your question fits
under one of those exiting discussions.
PLEASE put following the SPECIAL PHRASE somewhere in your Email Subject line:
You may wish to add your question as a comment to an existing discussion.
Otherwise click on:
calc question
((New discussion))
You may add additional words to your subject line.
IMPORTANT: If your Email doesn't contain the above phrase,
then we WILL NOT SEE your Email.
PLEASE BE SURE you have that SPECIAL PHRASE somewhere in the subject line!
Suggestion:
From time to time, the Email address and Subject SPECIAL PHRASE
may change so verify you have the current info by visiting:
http://www.isthe.com/chongo/tech/comp/calc/calc-question.html
and ask your question in that new discussion.
Please limit your questions to general questions about calc. We
cannot go into great detail in our answers, nor can we do your
homework, nor can we do much more than answer short general questions
homework, nor can we do much more than answer general questions
about calc.
Please be patient as we cannot always respond to Email messages quickly.
Please be patient as we cannot always respond to discussion messages quickly.
=-=
## Copyright (C) 2021 Landon Curt Noll
## Copyright (C) 2021,2023 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
@@ -39,7 +30,7 @@ Please be patient as we cannot always respond to Email messages quickly.
##
## 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
## 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
@@ -47,8 +38,8 @@ Please be patient as we cannot always respond to Email messages quickly.
## 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/02/10 00:15:05
## File existed as early as: 2021
## Under source code control: 2021/02/10 00:15:05
## File existed as early as: 2021
##
## chongo <was here> /\oo/\ http://www.isthe.com/chongo/
## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
## chongo <was here> /\oo/\ http://www.isthe.com/chongo/
## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/

View File

@@ -4,7 +4,7 @@ See the HOWTO.INSTALL file for information on how to build and install calc.
To be sure that your version of calc is up to date, check out:
http://www.isthe.com/chongo/tech/comp/calc/calc-download.html
http://www.isthe.com/chongo/tech/comp/calc/calc-download.html
We are interested in any/all feedback on recent versions of calc.
In particular we would like to hear about:
@@ -27,7 +27,7 @@ If you run into problems, see the BUGS file.
Calc is distributed with an extensive collection of help files that
are accessible from the command line. The following assume that you
are running calc from the distribution directory or that you have
installed calc. In these examples, the ">" is the calc prompt, not
installed calc. In these examples, the "; " is the calc prompt, not
something that you type in.
For list of help topics:
@@ -48,7 +48,7 @@ For list of builtin functions:
; help builtin
C programmers should note some unexpected differences in the calc syntax:
C programmers should note some unexpected differences with the calc syntax:
; help unexpected
@@ -105,7 +105,7 @@ for information about how to ask a question.
##
## 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
## 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
@@ -113,8 +113,8 @@ for information about how to ask a question.
## 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: 1995/10/25 05:27:59
## File existed as early as: 1995
## Under source code control: 1995/10/25 05:27:59
## File existed as early as: 1995
##
## chongo <was here> /\oo/\ http://www.isthe.com/chongo/
## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
## chongo <was here> /\oo/\ http://www.isthe.com/chongo/
## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/

158
README.RELEASE Normal file
View File

@@ -0,0 +1,158 @@
On calc versions and releases
Calc version numbers have 4 levels. For example:
++=== top 2 levels: calc builtin functions compatibility
||
vvvv
2.14.0.8
\\\\\\
^ \\\\----> top 3 levels: calc important code base change
|
+--- top version level: internal representation compatibility
The top version level (e.g., 2) refers to the internal representation
of values. Any library or hardware linked/built for calc 2 will be able
to use values from other 2.x.y.z versions.
The top 2 levels (e.g., 2.14) refers to a specific compatible set of
builtin functions. Calc interpreted code (such as calc resource files)
written for, say calc 2.14, will be able to use the same set of builtin
functions for any other 2.14.y.z version. Any new builtin functions or
significant changes to existing builtin functions would be introduced in
a later release such as version 2.15.y.z. While calc scripts written for
2.14.y.z will highly likely be able to run under version 2.15.y.z, any
new builtin functions added in calc 2.15 may collide with an identically
named used defined function.
The top 3 levels (e.g., 2.14.0) change to reflect an important change to
the code base such as a bug fix or performance improvement. There was
neither a change to the internal representation format (a top level
version change), nor were there new calc builtins introduced in such
a top 3 level release.
The file, "version.h" defines the 4 version levels:
MAJOR_VER /* level 1: major library version */
MINOR_VER /* level 2: minor library version */
MAJOR_PATCH /* level 3: major software version level */
MINOR_PATCH /* level 4: minor software version level */
The program "ver_calc" will print information about the compiled
calc version as defined "version.h" when "ver_calc" was compiled:
usage: ./ver_calc [-h] [-V]
-h print this message and exit non-zero
-V print 3-level version (def: print 4-level version)
Also "calc -v" will print the calc version as defined "version.h" when
"calc" was compiled.
The master branch:
The public repository of calc source code is:
http://github.com/lcn2/calc
On that GitHub site you may find released version of calc,
"production", "tested" and "alpha". All commits on the master
branch that are not associated with a release are "alpha".
Any "alpha" commit is likely future code for a future
"tested" or "production" version of calc.
alpha ==> untagged GitHub commit
Any untagged commit to the GitHub master branch should be
considered as alpha code that may make calc unstable.
While we try to avoid breaking the calc code with commits,
there is a risk that picking up such a change could
negatively impact the code.
NOTE: The calc version found in "version.h", and printed
by both "ver_calc [-V]" and "calc -v" for an untagged
commit is the previous "tested" or "production" version
of calc. Any "alpha" changes that remain are code
for some future version of calc.
At the last stage of the release process, "version.h"
will be updated as well as the top level version range
listed in "CHANGES".
tested ==> tagged GitHub pre-release commit
A new version of calc has been released and has recently passed
regression testing on at least to different platforms and chip
architectures.
The "tested" class was historically called "untested",
however this term was misleading as such releases ARE tested.
Since 2.14.0.13 we have used the term "tested".
All tested releases are tagged with a new version number.
Such releases have GitHub assets such as a source tarball,
zip file, source rpm, development rpm and binary rpm. See the
orange "Pre-release" GitHub releases under:
https://github.com/lcn2/calc/releases
At the bottom of a given release is a "> Assets" that may
be opened to reveal down-loadable files.
production ==> tagged GitHub release commit
A new version of calc has been released and has undergone
extensive testing over time over a number of platforms.
Sometimes a "tested" release that is found work well over
a period of time will be re-released with a new version
number as a "production" release.
The latest production GitHub release is marked with green
"Latest" label under:
https://github.com/lcn2/calc/releases
A release that has neither an orange "Pre-release" nor
a green "Latest" label is a prior production class release.
At the bottom of a given release is a "> Assets" that may
be opened to reveal down-loadable files.
Production class code where stability is critical should use a
"production" release.
A historical note and apology:
In the past, some version number changes were made that did not
fully reflect the above version number or change class. Moreover
older terms such as "stable" and "unstable" were misleading and
did not properly reflect the nature of the change. Sorry! The
purpose of this document is to try and bring a better level of
conformity to source code updates, tagged releases and version numbers.
## Copyright (C) 2021,2023 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/12/12 19:36:26
## File existed as early as: 2021
##
## chongo <was here> /\oo/\ http://www.isthe.com/chongo/
## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/

View File

@@ -1,19 +1,150 @@
Dear calc user on a Windoz based system,
Dear calc user on a Windows based system,
See the HOWTO.INSTALL file for information on how to build and install calc.
See also the README file.
NOTE: The main developers do not have access to a Windoz based platform.
While we will make an effort to not break calc Windoz based system,
our lack of a Windoz test environment will mean we will make mistakes
from time to time. Hopefully Windowz users can overcome these mistakes.
Please also add notes to the 'Compiling calc under Windows 11'
and 'Compiling with Cygwin' section in README.WINDOWS file.
NOTE: The main developers do not have access to a Windows based platform.
While we will make an effort to not break calc Windows based system,
our lack of a Windows test environment will mean we will make mistakes
from time to time. Hopefully Windows users can overcome these mistakes.
Of course you are welcome to send us any patches that fix your
Windoz build environment.
Windows build environment.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-= compiling with Windows Subsystem for Linux (WSL) =-Cygwin =-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-= Compiling calc under Windows 11 =-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
BTW: While we are unable to use Windows 11, we welcome Windows 11
developers to try compiling calc natively (instead of via a Linux
virtual machine). If you are able to compile Windows 11 natively,
we would welcome GitHub pull requests showing any needed modifications:
https://github.com/lcn2/calc/pulls
We were given this advice from a Windows 11 developer:
Windows 11 users could use Cygwin:
https://cygwin.com/install.html
IMPORTANT: While installing Cygwin, and during Cygwin Setup, be sure to
select all the MinGW64 packages relating to gcc.
See the "Compiling with Cygwin" section below.
NOTE: Compiling calc under Windows 11 is work in progress. If you run into
problems, consider the "Compiling with Cygwin" section below.
=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-= Compiling with Msys =-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=
The MSYS2 Software Distribution and Building Platform for Windows:
https://www.msys2.org
is a fork of Cygwin. In `Makefile.config`, when the OSNAME is "Msys",
the Cygwin target it set. MSYS2 Software Distribution users should be
sure that the following command prints "Msys".
uname -o
Or call make with OSNAME set as in:
make ... OSNAME=Msys
Follow the "Compiling with Cygwin" instructions below.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-= Compiling with Cygwin =-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
An effort is being made to allow windows users to compile calc using the
Cygwin project (http://sources.redhat.com/cygwin/) with the GCC compiler
and Unix tools for Windows.
The major porting work for Cygwin was performed by Thomas Jones-Low
(tjoneslo at softstart dot com).
In December 2022, GitHub user @Leoongithub successfully compiled
calc-2.14.1.2 under cygwin 2.924 (64 bit). The following are the
compilation steps that GitHub user @Leoongithub recommends:
0. Install the latest version of cygwin (https://cygwin.com/install.html).
NOTE: In addition to the default packages, you also need to check these
three packages: gcc-core, make, and libreadline-devel. The version
of these packages does not matter. Just choose the latest version.
NOTE: The addition of "target=Cygwin" to make commands below
is done just in case the target is not set properly by make.
1. Change (cd) into the top of the source code directory of calc.
NOTE: The make command assume you are at the top of the calc source directory.
2. make clobber target=Cygwin
NOTE: This helps ensure that you are starting from a so-called "clean slate",
and that you have nothing hanging around from previous attempts to compile.
3. make all target=Cygwin
NOTE: If successful, you should have a calc executable. However that executable
may not be working properly. Advance to step (4) to test.
4. make chk target=Cygwin
NOTE: If you want this command be be verbose, try:
make check target=Cygwin
NOTE: This will run calc with the regress.cal regression suite. This step could take
for a while to run, depending on the speed/performance of your machine.
If all is well (all regression tests pass), you will see at the end:
chk OK
Otherwise you may see calc exit non-zero after it prints some lines with '****'
error messages followed by a line including a final error count of the form:
**** 2 error(s) found \/++\/
If you see some errors that may relate to files and I/O, all may not be lost.
It could simply mean that your Windows environment is not conforming to standard
I/O and file operations. The calc mathematical engine may be just fine. On the
other hand if you see mathematical related regression test failures, this is
bad sign that your calc executable under Windows is not usable.
5. make install target=Cygwin
NOTE: This step is optional. While calc is usable at the top of the source code directory
of calc, installing calc may be of benefit so you can use calc elsewhere on your system.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-= Compiling calc via virtual machine under Windows 11 =-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
We would prefer a Windows 11 solution that does not require a Windows 11
developer to install a Linux virtual machine. Nevertheless, a Windows 11
user might want to use the Microsoft Windows Subsystem (WSL) for Linux:
https://docs.microsoft.com/en-us/windows/wsl/
We have been told that you will need to turn on virtualization
to use this WSL subsystem.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-= Compiling calc under Windows 10 via Windows Subsystem for Linux (WSL) =-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
It has been reported that calc version 2.12.6.4 has been successfully
compiled, installed and running on Windows 10 on 2018 Jan 21.
@@ -25,123 +156,11 @@ We were told:
https://docs.microsoft.com/cs-cz/windows/wsl/about
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-= compiling with Cygwin =-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
An effort is being made to allow windows users to compile calc using the
Cygwin project (http://sources.redhat.com/cygwin/) with the GCC compiler
and Un*x tools for Windows.
The major porting work for Cygwin was performed by Thomas Jones-Low
(tjoneslo at softstart dot com).
In March 2009, Michael Penk (mpenk at wuska dot com) reported success in
installs under Cygwin:
On my fairly complete Cygwin installs, everything compiles,
checks, and installs correctly. My Cygwin is configured
in a very standard way (out of the box, using all of Cygwin's
defaults). The install worked on 5 different machines with
Cygwin on them: one XP home, one XP professional, and three
Vista professionals.
Using the calc Makefile, he did the following:
make all target=Cygwin
make check
make install
He also reports:
Of course, one should be logged in as an Administrator when
one builds and installs calc.
He was compiling calc 2.12.4.0 with Cygwin version 1.5.25-15.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-= If all else fails, for Cygwin =-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Much earlier (2001?) Thomas Jones-Low (tjoneslo at softstart dot com)
recommended that you generate by hand all of the header files that
by the Makefile. This has been done for you via the makefile rule:
make win32_hsrc
which uses the Makefile variables in win32.mkdef to form these header
files under win32 directory.
You will find generated versions of these files located in the win32
sub-directory. These files may be appropriate for your Cygwin building
needs.
In particular:
Just copy the win32/*.[ch] files up into the top level calc
source directory, edit them (if needed) and build using the
Cygwin GCC compiler and Cygwin build environment.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-= compiling under DJGPP =-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
You might want to try using the DJGPP system to compile calc. See:
http://www.delorie.com/djgpp/
for DJGPP details and availability.
To compile with DJGPP, one needs to select a number of Makefile
variable changes. Eli Zaretskii <eliz at is dot elta dot co dot il>
recommends the following settings:
TERMCONTROL= -DUSE_TERMIOS
BYTE_ORDER= -DLITTLE_ENDIAN
LONG_BITS= 32
HAVE_FPOS_POS= -DHAVE_NO_FPOS_POS
FPOS_BITS= 32
OFF_T_BITS= 32
DEV_BITS= 32
INODE_BITS= 32
HAVE_USTAT= -DHAVE_NO_USTAT
HAVE_GETSID= -DHAVE_NO_GETSID
HAVE_GETPGID= -DHAVE_NO_GETPGID
HAVE_GETTIME= -DHAVE_NO_GETTIME
HAVE_GETPRID= -DHAVE_NO_GETPRID
HAVE_URANDOM_H= NO
ALIGN32= -UMUST_ALIGN32
HAVE_MALLOC_H= YES
HAVE_STDLIB_H= YES
HAVE_STRING_H= YES
HAVE_TIMES_H= NO
HAVE_SYS_TIMES_H= YES
HAVE_TIME_H= YES
HAVE_SYS_TIME_H= YES
HAVE_UNISTD_H= YES
BINDIR= /dev/env/DJDIR/bin
INCDIR= /dev/env/DJDIR/include
LIBDIR= /dev/env/DJDIR/lib
MANDIR= /dev/env/DJDIR/man/man1
CATDIR= /dev/env/DJDIR/man/cat1
NROFF= groff
CALCPATH= .;./cal;~/.cal;${CALC_SHAREDIR};${CUSTOMCALDIR}
CALCRC= ./.calcinit;~/.calcrc;${CALC_SHAREDIR}/startup
CALCPAGER= less.exe -ci
DEBUG= -O2 -gstabs+ -DWINDOZ
The 'Linux set' or 'gcc set' (see the Select your compiler type section)
should work for DJGPP systems if you set the above Makefile variables.
Look for Makefile comments of the form:
# Select ...something... for DJGPP.
Follow those recommendations. In cases where they conflict with
the above Makefile list, follow the recommendation in the Makefile.
NOTE: The use of calc under Windows 10 has been deprecated in favor of one
of the Windows 11 methods above.
## Copyright (C) 2002-2009 Landon Curt Noll and Thomas Jones-Low
## Copyright (C) 2002-2009,2021-2023 Landon Curt Noll and Thomas Jones-Low
##
## 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
@@ -149,7 +168,7 @@ the above Makefile list, follow the recommendation in the Makefile.
##
## 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
## 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
@@ -157,8 +176,8 @@ the above Makefile list, follow the recommendation in the Makefile.
## 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: 2001/02/25 14:00:05
## File existed as early as: 2001
## Under source code control: 2001/02/25 14:00:05
## File existed as early as: 2001
##
## chongo <was here> /\oo/\ http://www.isthe.com/chongo/
## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
## chongo <was here> /\oo/\ http://www.isthe.com/chongo/
## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/

View File

@@ -1,8 +1,30 @@
# TL;DR Try calc
## TL;DR Install calc
```
misc linux: sudo yum install calc
on Debian: sudo apt install calc
on RHEL: sudo dnf install calc
on Ubuntu: sudo apt install calc
via Termux: apt install calc
via src: sudo make clobber all chk instsll
```
## TL;DR Run calc
```
misc shell: calc
via bash: calc
via misc app: launch calc via Termux
via zsh: calc
```
# What is calc?
Calc is an interactive calculator which provides for easy large
numeric calculations, but which also can be easily programmed
for difficult or long calculations. It can accept a command line
for difficult or long calculations. It can accept a command line
argument, in which case it executes that single command and exits.
Otherwise, it enters interactive mode. In this mode, it accepts
commands one at a time, processes them, and displays the answers.
@@ -167,12 +189,12 @@ followed by a function declaration very similar to C.
```sh
define f2(n)
{
local ans;
local ans;
ans = 1;
while (n > 1)
ans *= (n -= 2);
return ans;
ans = 1;
while (n > 1)
ans *= (n -= 2);
return ans;
}
```

19
SECURITY.md Normal file
View File

@@ -0,0 +1,19 @@
# Security Policy
## Supported Versions
The most recent version of calc is supported with security updates.
If the most recent stable of calc is also supported with security updates.
FYI: please review the BUGS file, or enter the calc command:
; help BUGS
## Reporting a Vulnerability
Please create a calc GitHub repo issue:
https://github.com/lcn2/calc/issues
Click on ((New issue)) and follow the issue template.

929
addop.c

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,16 +17,21 @@
* 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: 1995/11/23 05:18:06
* File existed as early as: 1995
* Under source code control: 1995/11/23 05:18:06
* File existed as early as: 1995
*
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
#include <stdio.h>
#include <signal.h>
#include "have_stdlib.h"
#if defined(HAVE_STDLIB_H)
#include <stdlib.h>
#endif
#include "longbits.h"
#include "have_unistd.h"
@@ -34,43 +39,45 @@
#include <unistd.h>
#endif
#include "banned.h" /* include after system header <> includes */
#include "have_unused.h"
static void buserr(void); /* catch alignment errors */
#include "banned.h" /* include after system header <> includes */
static void buserr(int arg); /* catch alignment errors */
int
main(void)
{
char byte[2*sizeof(USB32)]; /* mis-alignment buffer */
USB32 *p; /* mis-alignment pointer */
int i;
char byte[2*sizeof(USB32)]; /* mis-alignment buffer */
USB32 *p; /* mis-alignment pointer */
unsigned long i;
#if defined(MUST_ALIGN32)
/* force alignment */
printf("#define MUST_ALIGN32\t%c* forced to align 32 bit values *%c\n",
'/', '/');
/* force alignment */
printf("#define MUST_ALIGN32\t%c* forced to align 32 bit values *%c\n",
'/', '/');
#else
/* setup to catch alignment bus errors */
signal(SIGBUS, buserr);
signal(SIGSEGV, buserr); /* some systems will generate SEGV instead! */
/* setup to catch alignment bus errors */
signal(SIGBUS, buserr);
signal(SIGSEGV, buserr); /* some systems will generate SEGV instead! */
/* mis-align our long fetches */
for (i=0; i < sizeof(USB32); ++i) {
p = (USB32 *)(byte+i);
*p = i;
*p += 1;
}
/* mis-align our long fetches */
for (i=0; i < sizeof(USB32); ++i) {
p = (USB32 *)(byte+i);
*p = i;
*p += 1;
}
/* if we got here, then we can mis-align longs */
printf("#undef MUST_ALIGN32\t%c* can mis-align 32 bit values *%c\n",
'/', '/');
/* if we got here, then we can mis-align longs */
printf("#undef MUST_ALIGN32\t%c* can mis-align 32 bit values *%c\n",
'/', '/');
#endif
/* exit(0); */
return 0;
/* exit(0); */
return 0;
}
@@ -78,14 +85,14 @@ main(void)
* buserr - catch an alignment error
*
* given:
* arg to keep ANSI C happy
* arg to keep ANSI C happy
*/
/*ARGSUSED*/
static void
buserr(int arg)
buserr(int UNUSED(arg))
{
/* alignment is required */
printf("#define MUST_ALIGN32\t%c* must align 32 bit values *%c\n",
'/', '/');
exit(0);
/* alignment is required */
printf("#define MUST_ALIGN32\t%c* must align 32 bit values *%c\n",
'/', '/');
exit(0);
}

12
alloc.h
View File

@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,10 +17,10 @@
* 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: 1990/02/15 01:48:29
* File existed as early as: before 1990
* Under source code control: 1990/02/15 01:48:29
* File existed as early as: before 1990
*
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
@@ -28,7 +28,7 @@
#define INCLUDE_ALLOC_H
#if defined(CALC_SRC) /* if we are building from the calc source tree */
#if defined(CALC_SRC) /* if we are building from the calc source tree */
# include "have_newstr.h"
# include "have_string.h"
# include "have_memmv.h"
@@ -42,9 +42,7 @@
# include <string.h>
#else
#if defined(_WIN32) && defined(NOTCYGWIN)
#include <stdio.h>
#endif
# if defined(HAVE_NEWSTR)
E_FUNC void *memcpy();

View File

@@ -1,7 +1,7 @@
/*
* assocfunc - association table routines
*
* Copyright (C) 1999-2007,2021 David I. Bell
* Copyright (C) 1999-2007,2021-2023 David I. Bell
*
* Calc is open software; you can redistribute it and/or modify it under
* the terms of the version 2.1 of the GNU Lesser General Public License
@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,10 +17,10 @@
* 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: 1993/07/20 23:04:27
* File existed as early as: 1993
* Under source code control: 1993/07/20 23:04:27
* File existed as early as: 1993
*
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
/*
@@ -36,97 +36,98 @@
#include "value.h"
#include "banned.h" /* include after system header <> includes */
#include "errtbl.h"
#include "banned.h" /* include after system header <> includes */
#define MINHASHSIZE 31 /* minimum size of hash tables */
#define GROWHASHSIZE 50 /* approximate growth for hash tables */
#define CHAINLENGTH 10 /* desired number of elements on a hash chain */
#define ELEMSIZE(n) (sizeof(ASSOCELEM) + (sizeof(VALUE) * ((n) - 1)))
#define MINHASHSIZE 31 /* minimum size of hash tables */
#define GROWHASHSIZE 50 /* approximate growth for hash tables */
#define CHAINLENGTH 10 /* desired number of elements on a hash chain */
#define ELEMSIZE(n) (sizeof(ASSOCELEM) + (sizeof(VALUE) * ((n) - 1)))
S_FUNC ASSOCELEM *elemindex(ASSOC *ap, long index);
S_FUNC BOOL compareindices(VALUE *v1, VALUE *v2, long dim);
S_FUNC bool compareindices(VALUE *v1, VALUE *v2, long dim);
S_FUNC void resize(ASSOC *ap, long newsize);
S_FUNC void assoc_elemfree(ASSOCELEM *ep);
/*
* Return the address of the value specified by normal indexing of
* an association. The create flag is TRUE if a value is going to be
* assigned into the specified indexing location. If create is FALSE and
* an association. The create flag is true if a value is going to be
* assigned into the specified indexing location. If create is false and
* the index value doesn't exist, a pointer to a NULL value is returned.
*
* given:
* ap association to index into
* create whether to create the index value
* dim dimension of the indexing
* indices table of values being indexed by
* ap association to index into
* create whether to create the index value
* dim dimension of the indexing
* indices table of values being indexed by
*/
VALUE *
associndex(ASSOC *ap, BOOL create, long dim, VALUE *indices)
associndex(ASSOC *ap, bool create, long dim, VALUE *indices)
{
ASSOCELEM **listhead;
ASSOCELEM *ep;
STATIC VALUE val;
QCKHASH hash;
int i;
ASSOCELEM **listhead;
ASSOCELEM *ep;
STATIC VALUE val;
QCKHASH hash;
int i;
if (dim < 0) {
math_error("Negative dimension for indexing association");
/*NOTREACHED*/
}
if (dim < 0) {
math_error("Negative dimension for indexing association");
not_reached();
}
/*
* Calculate the hash value to use for this set of indices
* so that we can first select the correct hash chain, and
* also so we can quickly compare each element for a match.
*/
hash = QUICKHASH_BASIS;
for (i = 0; i < dim; i++)
hash = hashvalue(&indices[i], hash);
/*
* Calculate the hash value to use for this set of indices
* so that we can first select the correct hash chain, and
* also so we can quickly compare each element for a match.
*/
hash = QUICKHASH_BASIS;
for (i = 0; i < dim; i++)
hash = hashvalue(&indices[i], hash);
/*
* Search the correct hash chain for the specified set of indices.
* If found, return the address of the found element's value.
*/
listhead = &ap->a_table[hash % ap->a_size];
for (ep = *listhead; ep; ep = ep->e_next) {
if ((ep->e_hash != hash) || (ep->e_dim != dim))
continue;
if (compareindices(ep->e_indices, indices, dim))
return &ep->e_value;
}
/*
* Search the correct hash chain for the specified set of indices.
* If found, return the address of the found element's value.
*/
listhead = &ap->a_table[hash % ap->a_size];
for (ep = *listhead; ep; ep = ep->e_next) {
if ((ep->e_hash != hash) || (ep->e_dim != dim))
continue;
if (compareindices(ep->e_indices, indices, dim))
return &ep->e_value;
}
/*
* The set of indices was not found.
* Either return a pointer to a NULL value for a read reference,
* or allocate a new element in the list for a write reference.
*/
if (!create) {
val.v_type = V_NULL;
val.v_subtype = V_NOSUBTYPE;
return &val;
}
/*
* The set of indices was not found.
* Either return a pointer to a NULL value for a read reference,
* or allocate a new element in the list for a write reference.
*/
if (!create) {
val.v_type = V_NULL;
val.v_subtype = V_NOSUBTYPE;
return &val;
}
ep = (ASSOCELEM *) malloc(ELEMSIZE(dim));
if (ep == NULL) {
math_error("Cannot allocate association element");
/*NOTREACHED*/
}
ep->e_dim = dim;
ep->e_hash = hash;
ep->e_value.v_type = V_NULL;
ep->e_value.v_subtype = V_NOSUBTYPE;
for (i = 0; i < dim; i++)
copyvalue(&indices[i], &ep->e_indices[i]);
ep->e_next = *listhead;
*listhead = ep;
ap->a_count++;
ep = (ASSOCELEM *) malloc(ELEMSIZE(dim));
if (ep == NULL) {
math_error("Cannot allocate association element");
not_reached();
}
ep->e_dim = dim;
ep->e_hash = hash;
ep->e_value.v_type = V_NULL;
ep->e_value.v_subtype = V_NOSUBTYPE;
for (i = 0; i < dim; i++)
copyvalue(&indices[i], &ep->e_indices[i]);
ep->e_next = *listhead;
*listhead = ep;
ap->a_count++;
resize(ap, ap->a_count / CHAINLENGTH);
resize(ap, ap->a_count / CHAINLENGTH);
return &ep->e_value;
return &ep->e_value;
}
@@ -138,25 +139,25 @@ associndex(ASSOC *ap, BOOL create, long dim, VALUE *indices)
int
assocsearch(ASSOC *ap, VALUE *vp, long i, long j, ZVALUE *index)
{
ASSOCELEM *ep;
ASSOCELEM *ep;
if (i < 0 || j > ap->a_count) {
math_error("This should not happen in assocsearch");
/*NOTREACHED*/
}
while (i < j) {
ep = elemindex(ap, i);
if (ep == NULL) {
math_error("This should not happen in assocsearch");
/*NOTREACHED*/
}
if (acceptvalue(&ep->e_value, vp)) {
utoz(i, index);
return 0;
}
i++;
}
return 1;
if (i < 0 || j > ap->a_count) {
math_error("This should not happen in assocsearch");
not_reached();
}
while (i < j) {
ep = elemindex(ap, i);
if (ep == NULL) {
math_error("This should not happen in assocsearch");
not_reached();
}
if (acceptvalue(&ep->e_value, vp)) {
utoz(i, index);
return 0;
}
i++;
}
return 1;
}
@@ -168,26 +169,26 @@ assocsearch(ASSOC *ap, VALUE *vp, long i, long j, ZVALUE *index)
int
assocrsearch(ASSOC *ap, VALUE *vp, long i, long j, ZVALUE *index)
{
ASSOCELEM *ep;
ASSOCELEM *ep;
if (i < 0 || j > ap->a_count) {
math_error("This should not happen in assocsearch");
/*NOTREACHED*/
}
j--;
while (j >= i) {
ep = elemindex(ap, j);
if (ep == NULL) {
math_error("This should not happen in assocsearch");
/*NOTREACHED*/
}
if (acceptvalue(&ep->e_value, vp)) {
utoz(j, index);
return 0;
}
j--;
}
return 1;
if (i < 0 || j > ap->a_count) {
math_error("This should not happen in assocsearch");
not_reached();
}
j--;
while (j >= i) {
ep = elemindex(ap, j);
if (ep == NULL) {
math_error("This should not happen in assocsearch");
not_reached();
}
if (acceptvalue(&ep->e_value, vp)) {
utoz(j, index);
return 0;
}
j--;
}
return 1;
}
@@ -196,29 +197,29 @@ assocrsearch(ASSOC *ap, VALUE *vp, long i, long j, ZVALUE *index)
* double-bracket operation.
*
* given:
* ap association to index into
* index index of desired element
* ap association to index into
* index index of desired element
*/
S_FUNC ASSOCELEM *
elemindex(ASSOC *ap, long index)
{
ASSOCELEM *ep;
int i;
ASSOCELEM *ep;
int i;
if ((index < 0) || (index > ap->a_count))
return NULL;
if ((index < 0) || (index > ap->a_count))
return NULL;
/*
* This loop should be made more efficient by remembering
* previously requested locations within the association.
*/
for (i = 0; i < ap->a_size; i++) {
for (ep = ap->a_table[i]; ep; ep = ep->e_next) {
if (index-- == 0)
return ep;
}
}
return NULL;
/*
* This loop should be made more efficient by remembering
* previously requested locations within the association.
*/
for (i = 0; i < ap->a_size; i++) {
for (ep = ap->a_table[i]; ep; ep = ep->e_next) {
if (index-- == 0)
return ep;
}
}
return NULL;
}
@@ -227,18 +228,18 @@ elemindex(ASSOC *ap, long index)
* of an association. Returns NULL if there is no such element.
*
* given:
* ap association to index into
* index index of desired element
* ap association to index into
* index index of desired element
*/
VALUE *
assocfindex(ASSOC *ap, long index)
{
ASSOCELEM *ep;
ASSOCELEM *ep;
ep = elemindex(ap, index);
if (ep == NULL)
return NULL;
return &ep->e_value;
ep = elemindex(ap, index);
if (ep == NULL)
return NULL;
return &ep->e_value;
}
@@ -249,64 +250,64 @@ assocfindex(ASSOC *ap, long index)
LIST *
associndices(ASSOC *ap, long index)
{
ASSOCELEM *ep;
LIST *lp;
int i;
ASSOCELEM *ep;
LIST *lp;
int i;
ep = elemindex(ap, index);
if (ep == NULL)
return NULL;
lp = listalloc();
for (i = 0; i < ep->e_dim; i++)
insertlistlast(lp, &ep->e_indices[i]);
return lp;
ep = elemindex(ap, index);
if (ep == NULL)
return NULL;
lp = listalloc();
for (i = 0; i < ep->e_dim; i++)
insertlistlast(lp, &ep->e_indices[i]);
return lp;
}
/*
* Compare two associations to see if they are identical.
* Returns TRUE if they are different.
* Returns true if they are different.
*/
BOOL
bool
assoccmp(ASSOC *ap1, ASSOC *ap2)
{
ASSOCELEM **table1;
ASSOCELEM *ep1;
ASSOCELEM *ep2;
long size1;
long size2;
QCKHASH hash;
long dim;
ASSOCELEM **table1;
ASSOCELEM *ep1;
ASSOCELEM *ep2;
long size1;
long size2;
QCKHASH hash;
long dim;
if (ap1 == ap2)
return FALSE;
if (ap1->a_count != ap2->a_count)
return TRUE;
if (ap1 == ap2)
return false;
if (ap1->a_count != ap2->a_count)
return true;
table1 = ap1->a_table;
size1 = ap1->a_size;
size2 = ap2->a_size;
while (size1-- > 0) {
for (ep1 = *table1++; ep1; ep1 = ep1->e_next) {
hash = ep1->e_hash;
dim = ep1->e_dim;
for (ep2 = ap2->a_table[hash % size2]; ;
ep2 = ep2->e_next) {
if (ep2 == NULL)
return TRUE;
if (ep2->e_hash != hash)
continue;
if (ep2->e_dim != dim)
continue;
if (compareindices(ep1->e_indices,
ep2->e_indices, dim))
break;
}
if (comparevalue(&ep1->e_value, &ep2->e_value))
return TRUE;
}
}
return FALSE;
table1 = ap1->a_table;
size1 = ap1->a_size;
size2 = ap2->a_size;
while (size1-- > 0) {
for (ep1 = *table1++; ep1; ep1 = ep1->e_next) {
hash = ep1->e_hash;
dim = ep1->e_dim;
for (ep2 = ap2->a_table[hash % size2]; ;
ep2 = ep2->e_next) {
if (ep2 == NULL)
return true;
if (ep2->e_hash != hash)
continue;
if (ep2->e_dim != dim)
continue;
if (compareindices(ep1->e_indices,
ep2->e_indices, dim))
break;
}
if (comparevalue(&ep1->e_value, &ep2->e_value))
return true;
}
}
return false;
}
@@ -316,39 +317,39 @@ assoccmp(ASSOC *ap1, ASSOC *ap2)
ASSOC *
assoccopy(ASSOC *oldap)
{
ASSOC *ap;
ASSOCELEM *oldep;
ASSOCELEM *ep;
ASSOCELEM **listhead;
int oldhi;
int i;
ASSOC *ap;
ASSOCELEM *oldep;
ASSOCELEM *ep;
ASSOCELEM **listhead;
int oldhi;
int i;
ap = assocalloc(oldap->a_count / CHAINLENGTH);
ap->a_count = oldap->a_count;
ap = assocalloc(oldap->a_count / CHAINLENGTH);
ap->a_count = oldap->a_count;
for (oldhi = 0; oldhi < oldap->a_size; oldhi++) {
for (oldep = oldap->a_table[oldhi]; oldep;
oldep = oldep->e_next) {
ep = (ASSOCELEM *) malloc(ELEMSIZE(oldep->e_dim));
if (ep == NULL) {
math_error("Cannot allocate "
"association element");
/*NOTREACHED*/
}
ep->e_dim = oldep->e_dim;
ep->e_hash = oldep->e_hash;
ep->e_value.v_type = V_NULL;
ep->e_value.v_subtype = V_NOSUBTYPE;
for (i = 0; i < ep->e_dim; i++)
copyvalue(&oldep->e_indices[i],
&ep->e_indices[i]);
copyvalue(&oldep->e_value, &ep->e_value);
listhead = &ap->a_table[ep->e_hash % ap->a_size];
ep->e_next = *listhead;
*listhead = ep;
}
}
return ap;
for (oldhi = 0; oldhi < oldap->a_size; oldhi++) {
for (oldep = oldap->a_table[oldhi]; oldep;
oldep = oldep->e_next) {
ep = (ASSOCELEM *) malloc(ELEMSIZE(oldep->e_dim));
if (ep == NULL) {
math_error("Cannot allocate "
"association element");
not_reached();
}
ep->e_dim = oldep->e_dim;
ep->e_hash = oldep->e_hash;
ep->e_value.v_type = V_NULL;
ep->e_value.v_subtype = V_NOSUBTYPE;
for (i = 0; i < ep->e_dim; i++)
copyvalue(&oldep->e_indices[i],
&ep->e_indices[i]);
copyvalue(&oldep->e_value, &ep->e_value);
listhead = &ap->a_table[ep->e_hash % ap->a_size];
ep->e_next = *listhead;
*listhead = ep;
}
}
return ap;
}
@@ -360,41 +361,41 @@ assoccopy(ASSOC *oldap)
S_FUNC void
resize(ASSOC *ap, long newsize)
{
ASSOCELEM **oldtable;
ASSOCELEM **newtable;
ASSOCELEM **oldlist;
ASSOCELEM **newlist;
ASSOCELEM *ep;
int i;
ASSOCELEM **oldtable;
ASSOCELEM **newtable;
ASSOCELEM **oldlist;
ASSOCELEM **newlist;
ASSOCELEM *ep;
int i;
if (newsize < ap->a_size + GROWHASHSIZE)
return;
if (newsize < ap->a_size + GROWHASHSIZE)
return;
newsize = (long) next_prime((FULL)newsize);
newtable = (ASSOCELEM **) malloc(sizeof(ASSOCELEM *) * newsize);
if (newtable == NULL) {
math_error("No memory to grow association");
/*NOTREACHED*/
}
for (i = 0; i < newsize; i++)
newtable[i] = NULL;
newsize = (long) next_prime((FULL)newsize);
newtable = (ASSOCELEM **) malloc(sizeof(ASSOCELEM *) * newsize);
if (newtable == NULL) {
math_error("No memory to grow association");
not_reached();
}
for (i = 0; i < newsize; i++)
newtable[i] = NULL;
oldtable = ap->a_table;
oldlist = oldtable;
for (i = 0; i < ap->a_size; i++) {
while (*oldlist) {
ep = *oldlist;
*oldlist = ep->e_next;
newlist = &newtable[ep->e_hash % newsize];
ep->e_next = *newlist;
*newlist = ep;
}
oldlist++;
}
oldtable = ap->a_table;
oldlist = oldtable;
for (i = 0; i < ap->a_size; i++) {
while (*oldlist) {
ep = *oldlist;
*oldlist = ep->e_next;
newlist = &newtable[ep->e_hash % newsize];
ep->e_next = *newlist;
*newlist = ep;
}
oldlist++;
}
ap->a_table = newtable;
ap->a_size = newsize;
free((char *) oldtable);
ap->a_table = newtable;
ap->a_size = newsize;
free((char *) oldtable);
}
@@ -404,14 +405,14 @@ resize(ASSOC *ap, long newsize)
S_FUNC void
assoc_elemfree(ASSOCELEM *ep)
{
int i;
int i;
for (i = 0; i < ep->e_dim; i++)
freevalue(&ep->e_indices[i]);
freevalue(&ep->e_value);
ep->e_dim = 0;
ep->e_next = NULL;
free((char *) ep);
for (i = 0; i < ep->e_dim; i++)
freevalue(&ep->e_indices[i]);
freevalue(&ep->e_value);
ep->e_dim = 0;
ep->e_next = NULL;
free((char *) ep);
}
@@ -422,27 +423,27 @@ assoc_elemfree(ASSOCELEM *ep)
ASSOC *
assocalloc(long initsize)
{
register ASSOC *ap;
int i;
register ASSOC *ap;
int i;
if (initsize < MINHASHSIZE)
initsize = MINHASHSIZE;
ap = (ASSOC *) malloc(sizeof(ASSOC));
if (ap == NULL) {
math_error("No memory for association");
/*NOTREACHED*/
}
ap->a_count = 0;
ap->a_size = initsize;
ap->a_table = (ASSOCELEM **) malloc(sizeof(ASSOCELEM *) * initsize);
if (ap->a_table == NULL) {
free((char *) ap);
math_error("No memory for association");
/*NOTREACHED*/
}
for (i = 0; i < initsize; i++)
ap->a_table[i] = NULL;
return ap;
if (initsize < MINHASHSIZE)
initsize = MINHASHSIZE;
ap = (ASSOC *) malloc(sizeof(ASSOC));
if (ap == NULL) {
math_error("No memory for association");
not_reached();
}
ap->a_count = 0;
ap->a_size = initsize;
ap->a_table = (ASSOCELEM **) malloc(sizeof(ASSOCELEM *) * initsize);
if (ap->a_table == NULL) {
free((char *) ap);
math_error("No memory for association");
not_reached();
}
for (i = 0; i < initsize; i++)
ap->a_table[i] = NULL;
return ap;
}
@@ -452,25 +453,25 @@ assocalloc(long initsize)
void
assocfree(ASSOC *ap)
{
ASSOCELEM **listhead;
ASSOCELEM *ep;
ASSOCELEM *nextep;
int i;
ASSOCELEM **listhead;
ASSOCELEM *ep;
ASSOCELEM *nextep;
int i;
listhead = ap->a_table;
for (i = 0; i < ap->a_size; i++) {
nextep = *listhead;
*listhead = NULL;
while (nextep) {
ep = nextep;
nextep = ep->e_next;
assoc_elemfree(ep);
}
listhead++;
}
free((char *) ap->a_table);
ap->a_table = NULL;
free((char *) ap);
listhead = ap->a_table;
for (i = 0; i < ap->a_size; i++) {
nextep = *listhead;
*listhead = NULL;
while (nextep) {
ep = nextep;
nextep = ep->e_next;
assoc_elemfree(ep);
}
listhead++;
}
free((char *) ap->a_table);
ap->a_table = NULL;
free((char *) ap);
}
@@ -481,58 +482,58 @@ assocfree(ASSOC *ap)
void
assocprint(ASSOC *ap, long max_print)
{
ASSOCELEM *ep;
long index;
long i;
int savemode;
ASSOCELEM *ep;
long index;
long i;
int savemode;
if (max_print <= 0) {
math_fmt("assoc (%ld element%s)", ap->a_count,
((ap->a_count == 1) ? "" : "s"));
return;
}
math_fmt("\n assoc (%ld element%s):\n", ap->a_count,
((ap->a_count == 1) ? "" : "s"));
if (max_print <= 0) {
math_fmt("assoc (%ld element%s)", ap->a_count,
((ap->a_count == 1) ? "" : "s"));
return;
}
math_fmt("\n assoc (%ld element%s):\n", ap->a_count,
((ap->a_count == 1) ? "" : "s"));
for (index = 0; ((index < max_print) && (index < ap->a_count));
index++) {
ep = elemindex(ap, index);
if (ep == NULL)
continue;
math_str(" [");
for (i = 0; i < ep->e_dim; i++) {
if (i)
math_chr(',');
savemode = math_setmode(MODE_FRAC);
printvalue(&ep->e_indices[i],
(PRINT_SHORT | PRINT_UNAMBIG));
math_setmode(savemode);
}
math_str("] = ");
printvalue(&ep->e_value, PRINT_SHORT | PRINT_UNAMBIG);
math_chr('\n');
}
if (max_print < ap->a_count)
math_str(" ...\n");
for (index = 0; ((index < max_print) && (index < ap->a_count));
index++) {
ep = elemindex(ap, index);
if (ep == NULL)
continue;
math_str(" [");
for (i = 0; i < ep->e_dim; i++) {
if (i)
math_chr(',');
savemode = math_setmode(MODE_FRAC);
printvalue(&ep->e_indices[i],
(PRINT_SHORT | PRINT_UNAMBIG));
math_setmode(savemode);
}
math_str("] = ");
printvalue(&ep->e_value, PRINT_SHORT | PRINT_UNAMBIG);
math_chr('\n');
}
if (max_print < ap->a_count)
math_str(" ...\n");
}
/*
* Compare two lists of index values to see if they are identical.
* Returns TRUE if they are the same.
* Returns true if they are the same.
*/
S_FUNC BOOL
S_FUNC bool
compareindices(VALUE *v1, VALUE *v2, long dim)
{
int i;
int i;
for (i = 0; i < dim; i++)
if (v1[i].v_type != v2[i].v_type)
return FALSE;
for (i = 0; i < dim; i++)
if (v1[i].v_type != v2[i].v_type)
return false;
while (dim-- > 0)
if (comparevalue(v1++, v2++))
return FALSE;
while (dim-- > 0)
if (comparevalue(v1++, v2++))
return false;
return TRUE;
return true;
}

69
attribute.h Normal file
View File

@@ -0,0 +1,69 @@
/*
* attribute - control use of attributes in a backward compatible way
*
* Copyright (C) 2022 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: 2022/01/21 22:51:25
* File existed as early as: 2022
*
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
#if !defined(INCLUDE_ATTRIBUTE_H)
#define INCLUDE_ATTRIBUTE_H
/*
* backward compatibility
*
* Not all compilers support __attribute__ nor do they suuport __has_builtin.
* For example, MSVC, TenDRAm and Little C Compiler doesn't support __attribute__.
* Early gcc does not support __attribute__.
*
* Not all compiles have __has_builtin
*/
#if !defined(__attribute__) && \
(defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8)
# define __attribute__(A)
#endif
#if !defined __has_builtin
# define __has_builtin(x) 0
#endif
/*
* not_reached
*
* In the old days of lint, one could give lint and friends a hint by
* placing the token NOTREACHED immediately between opening and closing
* comments. Modern compilers do not honor such commented tokens
* and instead rely on features such as __builtin_unreachable
* and __attribute__((noreturn)).
*
* The not_reached will either yield a __builtin_unreachable() feature call,
* or it will call abort from stdlib.
*/
#if __has_builtin(__builtin_unreachable)
# define not_reached() __builtin_unreachable()
#else
# define not_reached() abort()
#endif /* __has_builtin(__builtin_unreachable) */
#endif /* !INCLUDE_ATTRIBUTE_H */

View File

@@ -1,14 +1,14 @@
/*
* banned - optionally ban dqngerious functions
* banned - optionally ban dangerous functions
*
* Unless UNBAN is defined, this file will turn the use
* of certain dangerous functions into syntax errors.
*
* In the case of calc, we are motivated in part by the desire for
* calc to correctly calculate: even durings extremely long calculations.
* calc to correctly calculate: even during extremely long calculations.
*
* If UNBAN is NOT defined, then calling certain functions
* will result in a syntaxc error.
* will result in a syntax error.
*
* If we define UNBAN, then the effect of this file is disabled.
*
@@ -17,7 +17,7 @@
* if calculations.
*
* In the case of calc, we are motivated in part by the desire for calc
* to correctly calculate: even durings extremely long calculations.
* to correctly calculate: even during extremely long calculations.
*
* If UNBAN is NOT defined, then calling certain functions
* will result in a call to a non-existent function (link error).
@@ -27,18 +27,18 @@
* function may lead to a fatal compiler complication.
* If that happens, consider compiling as:
*
* make clobber all chk CCBAN=-DUNBAN
* make clobber all chk CCBAN=-DUNBAN
*
* as see if this is a work-a-round.
*
* If YOU discover a need for the -DUNBAN work-a-round, PLEASE tell us!
* Please send us a bug report. See the file:
*
* BUGS
* BUGS
*
* or the URL:
*
* http://www.isthe.com/chongo/tech/comp/calc/calc-bugrept.html
* http://www.isthe.com/chongo/tech/comp/calc/calc-bugrept.html
*
* for how to send us such a bug report.
*
@@ -50,7 +50,7 @@
*
* 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
* 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
@@ -58,11 +58,11 @@
* 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/03/06 21:07:31
* File existed as early as: 2021
* Under source code control: 2021/03/06 21:07:31
* File existed as early as: 2021
*
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
@@ -82,17 +82,17 @@
/*
* In the spirit of:
*
* https://github.com/git/git/blob/master/banned.h
* https://github.com/git/git/blob/master/banned.h
*
* we will ban the use of certain unsafe functions by turning
* then into function calls that do not exist.
*
* In the case of calc, we are motivated in part by the desire
* for calc to correctly calculate: even durings extremely long
* for calc to correctly calculate: even during extremely long
* calculations.
*
* If UNBAN is NOT defined, then calling certain functions
* will result in a syntaxc error.
* will result in a syntax error.
*
* Unlike the above URL, we suggest an alternative function.
* In many cases, additional logic is required to use the
@@ -157,22 +157,22 @@
/*
* XXX - As of 2021, functions such as:
*
* gmtime_s
* localtime_s
* ctime_s
* asctime_s
* gmtime_s
* localtime_s
* ctime_s
* asctime_s
*
* are not universal. We cannot yet ban the following
* functions because we do not have a portable AND
* widely available alternative. Therefore we just
* have to be extra careful when using:
*
* gmtime
* localtime
* ctime
* ctime_r
* asctime
* asctime_r
* gmtime
* localtime
* ctime
* ctime_r
* asctime
* asctime_r
*/
#endif /* !UNBAN */

1679
blkcpy.c

File diff suppressed because it is too large Load Diff

View File

@@ -11,7 +11,7 @@
*
* 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
* 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
@@ -19,10 +19,10 @@
* 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: 1997/04/18 20:41:25
* File existed as early as: 1997
* Under source code control: 1997/04/18 20:41:25
* File existed as early as: 1997
*
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
@@ -37,21 +37,21 @@ E_FUNC int copystod(VALUE *, long, long, VALUE *, long);
/*
* specific copy functions
*/
E_FUNC int copyblk2blk(BLOCK *, long, long, BLOCK *, long, BOOL);
E_FUNC int copyblk2blk(BLOCK *, long, long, BLOCK *, long, bool);
E_FUNC int copyblk2file(BLOCK *, long, long, FILEID, long);
E_FUNC int copyblk2mat(BLOCK *, long, long, MATRIX *, long);
E_FUNC int copyblk2num(BLOCK *, long, long, NUMBER *, long, NUMBER **);
E_FUNC int copyblk2str(BLOCK *, long, long, STRING *, long);
E_FUNC int copyfile2blk(FILEID, long, long, BLOCK *, long, BOOL);
E_FUNC int copyfile2blk(FILEID, long, long, BLOCK *, long, bool);
E_FUNC int copylist2list(LIST *, long, long, LIST *, long);
E_FUNC int copylist2mat(LIST *, long, long, MATRIX *, long);
E_FUNC int copymat2blk(MATRIX *, long, long, BLOCK *, long, BOOL);
E_FUNC int copymat2blk(MATRIX *, long, long, BLOCK *, long, bool);
E_FUNC int copymat2list(MATRIX *, long, long, LIST *, long);
E_FUNC int copymat2mat(MATRIX *, long, long, MATRIX *, long);
E_FUNC int copynum2blk(NUMBER *, long, long, BLOCK *, long, BOOL);
E_FUNC int copyostr2blk(char *, long, long, BLOCK *, long, BOOL);
E_FUNC int copynum2blk(NUMBER *, long, long, BLOCK *, long, bool);
E_FUNC int copyostr2blk(char *, long, long, BLOCK *, long, bool);
E_FUNC int copyostr2str(char *, long, long, STRING *, long);
E_FUNC int copystr2blk(STRING *, long, long, BLOCK *, long, BOOL);
E_FUNC int copystr2blk(STRING *, long, long, BLOCK *, long, bool);
E_FUNC int copystr2file(STRING *, long, long, FILEID, long);
E_FUNC int copystr2str(STRING *, long, long, STRING *, long);

882
block.c

File diff suppressed because it is too large Load Diff

196
block.h
View File

@@ -1,7 +1,7 @@
/*
* block - fixed, dynamic, fifo and circular memory blocks
*
* Copyright (C) 1999-2007,2014,2021 Landon Curt Noll and Ernest Bowen
* Copyright (C) 1999-2007,2014,2021,2023 Landon Curt Noll and Ernest Bowen
*
* Primary author: Landon Curt Noll
*
@@ -11,7 +11,7 @@
*
* 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
* 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
@@ -19,11 +19,11 @@
* 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: 1997/02/21 05:03:39
* File existed as early as: 1997
* Under source code control: 1997/02/21 05:03:39
* File existed as early as: 1997
*
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
@@ -41,114 +41,114 @@
*
* Block functions and operations:
*
* x[i]
* (i-1)th octet
* x[i]
* (i-1)th octet
*
* blk(len [, blkchunk])
* unnamed block
* len > 0
* blkchunk defaults to BLK_CHUNKSIZE
* blk(len [, blkchunk])
* unnamed block
* len > 0
* blkchunk defaults to BLK_CHUNKSIZE
*
* blk(name, [len [, blkchunk]])
* named block
* len > 0
* blkchunk defaults to BLK_CHUNKSIZE
* blk(name, [len [, blkchunk]])
* named block
* len > 0
* blkchunk defaults to BLK_CHUNKSIZE
*
* blkfree(x)
* Reduce storage down to 0 octets.
* blkfree(x)
* Reduce storage down to 0 octets.
*
* size(x)
* The length of data stored in the block.
* size(x)
* The length of data stored in the block.
*
* sizeof(x) == blk->maxsize
* Allocation size in memory
* sizeof(x) == blk->maxsize
* Allocation size in memory
*
* isblk(x)
* returns 0 is x is not a BLOCK, 1 if x is an
* unnamed block, 2 if x is a named BLOCK
* isblk(x)
* returns 0 is x is not a BLOCK, 1 if x is an
* unnamed block, 2 if x is a named BLOCK
*
* blkread(x, size, count, fd [, offset])
* blkwrite(x, size, count, fd [, offset])
* returns number of items written
* offset is restricted in value by block type
* blkread(x, size, count, fd [, offset])
* blkwrite(x, size, count, fd [, offset])
* returns number of items written
* offset is restricted in value by block type
*
* blkset(x, val, length [, offset])
* only the lower octet of val is used
* offset is restricted in value by block type
* blkset(x, val, length [, offset])
* only the lower octet of val is used
* offset is restricted in value by block type
*
* blkchr(x, val, length [, offset])
* only the lower octet of val is used
* offset is restricted in value by block type
* blkchr(x, val, length [, offset])
* only the lower octet of val is used
* offset is restricted in value by block type
*
* blkcpy(dest, src, length [, dest_offset [, src_offset]])
* 0 <= length <= blksize(x)
* offset's are restricted in value by block type
* dest may not == src
* blkcpy(dest, src, length [, dest_offset [, src_offset]])
* 0 <= length <= blksize(x)
* offset's are restricted in value by block type
* dest may not == src
*
* blkmove(dest, src, length [, dest_offset [, src_offset]])
* 0 <= length <= blksize(x)
* offset's are restricted in value by block type
* overlapping moves are handled correctly
* blkmove(dest, src, length [, dest_offset [, src_offset]])
* 0 <= length <= blksize(x)
* offset's are restricted in value by block type
* overlapping moves are handled correctly
*
* blkccpy(dest, src, stopval, length [, dest_offset [, src_offset]])
* 0 <= length <= blksize(x)
* offset's are restricted in value by block type
* blkccpy(dest, src, stopval, length [, dest_offset [, src_offset]])
* 0 <= length <= blksize(x)
* offset's are restricted in value by block type
*
* blkcmp(dest, src, length [, dest_offset [, src_offset]])
* 0 <= length <= blksize(x)
* offset's are restricted in value by block type
* blkcmp(dest, src, length [, dest_offset [, src_offset]])
* 0 <= length <= blksize(x)
* offset's are restricted in value by block type
*
* blkswap(x, a, b)
* swaps groups of 'a' octets within each 'b' octets
* b == a is a noop
* b = a*k for some integer k >= 1
* blkswap(x, a, b)
* swaps groups of 'a' octets within each 'b' octets
* b == a is a noop
* b = a*k for some integer k >= 1
*
* scatter(src, dest1, dest2 [, dest3 ] ...)
* copy successive octets from src into dest1, dest2, ...
* restarting with dest1 after end of list
* stops at end of src
* scatter(src, dest1, dest2 [, dest3 ] ...)
* copy successive octets from src into dest1, dest2, ...
* restarting with dest1 after end of list
* stops at end of src
*
* gather(dest, src1, src2 [, src3 ] ...)
* copy first octet from src1, src2, ...
* copy next octet from src1, src2, ...
* ...
* copy last octet from src1, src2, ...
* copy 0 when there is no more data from a given source
* gather(dest, src1, src2 [, src3 ] ...)
* copy first octet from src1, src2, ...
* copy next octet from src1, src2, ...
* ...
* copy last octet from src1, src2, ...
* copy 0 when there is no more data from a given source
*
* blkseek(x, offset, {"in","out"})
* some seeks may not be allowed by block type
* blkseek(x, offset, {"in","out"})
* some seeks may not be allowed by block type
*
* config("blkmaxprint", count)
* number of octets of a block to print, 0 means all
* config("blkmaxprint", count)
* number of octets of a block to print, 0 means all
*
* config("blkverbose", boolean)
* TRUE => print all lines, FALSE => skip dup lines
* config("blkverbose", boolean)
* true => print all lines, false => skip dup lines
*
* config("blkbase", "base")
* output block base = { "hex", "octal", "char", "binary", "raw" }
* binary is base 2, raw is just octet values
* config("blkbase", "base")
* output block base = { "hex", "octal", "char", "binary", "raw" }
* binary is base 2, raw is just octet values
*
* config("blkfmt", "style")
* style of output = {
* "line", lines in blkbase with no spaces between octets
* "string", as one long line with no spaces between octets
* "od_style", position, spaces between octets
* "hd_style"} position, spaces between octets, chars on end
* config("blkfmt", "style")
* style of output = {
* "line", lines in blkbase with no spaces between octets
* "string", as one long line with no spaces between octets
* "od_style", position, spaces between octets
* "hd_style"} position, spaces between octets, chars on end
*/
struct block {
LEN blkchunk; /* allocation chunk size */
LEN maxsize; /* octets actually malloced for this block */
LEN datalen; /* octets of data held this block */
USB8 *data; /* pointer to the 1st octet of the allocated data */
LEN blkchunk; /* allocation chunk size */
LEN maxsize; /* octets actually malloced for this block */
LEN datalen; /* octets of data held this block */
USB8 *data; /* pointer to the 1st octet of the allocated data */
};
typedef struct block BLOCK;
struct nblock {
char *name;
int subtype;
int id;
BLOCK *blk;
char *name;
int subtype;
int id;
BLOCK *blk;
};
typedef struct nblock NBLOCK;
@@ -156,26 +156,26 @@ typedef struct nblock NBLOCK;
/*
* block debug
*/
EXTERN int blk_debug; /* 0 => debug off */
EXTERN int blk_debug; /* 0 => debug off */
/*
* block defaults
*/
#define BLK_CHUNKSIZE 256 /* default allocation chunk size for blocks */
#define BLK_CHUNKSIZE 256 /* default allocation chunk size for blocks */
#define BLK_DEF_MAXPRINT 256 /* default octets to print */
#define BLK_DEF_MAXPRINT 256 /* default octets to print */
#define BLK_BASE_HEX 0 /* output octets in a block in hex */
#define BLK_BASE_OCT 1 /* output octets in a block in octal */
#define BLK_BASE_CHAR 2 /* output octets in a block in characters */
#define BLK_BASE_BINARY 3 /* output octets in a block in base 2 chars */
#define BLK_BASE_RAW 4 /* output octets in a block in raw binary */
#define BLK_BASE_HEX 0 /* output octets in a block in hex */
#define BLK_BASE_OCT 1 /* output octets in a block in octal */
#define BLK_BASE_CHAR 2 /* output octets in a block in characters */
#define BLK_BASE_BINARY 3 /* output octets in a block in base 2 chars */
#define BLK_BASE_RAW 4 /* output octets in a block in raw binary */
#define BLK_FMT_HD_STYLE 0 /* output in base with chars on end of line */
#define BLK_FMT_LINE 1 /* output is lines of up to 79 chars */
#define BLK_FMT_STRING 2 /* output is one long string */
#define BLK_FMT_OD_STYLE 3 /* output in base with chars */
#define BLK_FMT_HD_STYLE 0 /* output in base with chars on end of line */
#define BLK_FMT_LINE 1 /* output is lines of up to 79 chars */
#define BLK_FMT_STRING 2 /* output is one long string */
#define BLK_FMT_OD_STYLE 3 /* output in base with chars */
/*

65
bool.h Normal file
View File

@@ -0,0 +1,65 @@
/*
* bool - calc standard truth :-)
*
* Copyright (C) 2023 David I. Bell and Landon Curt Noll
*
* Primary author: David I. Bell
*
* Calc is open software; you can redistribute it and/or modify it under
* the terms of the version 2.1 of the GNU Lesser General Public License
* 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: 2023/07/19 17:58:42
* File existed as early as: 2023
*
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
#if !defined(INCLUDE_BOOL_H)
#define INCLUDE_BOOL_H
#include "have_stdbool.h"
#if defined(HAVE_STDBOOL_H)
#include <stdbool.h>
#endif /* HAVE_STDBOOL_H */
/*
* standard truth :-)
*/
#if !defined(HAVE_STDBOOL_H)
/* fake a <stdbool.h> header file */
typedef unsigned char bool; /* fake boolean typedef */
#undef true
#define true ((bool)(1))
#undef false
#define false ((bool)(0))
#endif /* !HAVE_STDBOOL_H */
/*
* calc historic booleans
*/
#undef TRUE
#define TRUE (true)
#undef FALSE
#define FALSE (false)
#undef BOOL
#define BOOL bool
#endif /* !INCLUDE_BOOL_H*/

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
/*
* byteswap - byte swapping macros
*
* Copyright (C) 1999,2014 Landon Curt Noll
* Copyright (C) 1999,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
@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,11 +17,11 @@
* 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: 1995/10/11 04:44:01
* File existed as early as: 1995
* Under source code control: 1995/10/11 04:44:01
* File existed as early as: 1995
*
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
@@ -29,7 +29,7 @@
#define INCLUDE_BYTESWAP_H
#if defined(CALC_SRC) /* if we are building from the calc source tree */
#if defined(CALC_SRC) /* if we are building from the calc source tree */
# include "longbits.h"
#else
# include <calc/longbits.h>
@@ -39,42 +39,42 @@
/*
* SWAP_B8_IN_B16 - swap 8 bits in 16 bits
*
* dest - pointer to where the swapped src wil be put
* src - pointer to a 16 bit value to swap
* dest - pointer to where the swapped src will be put
* src - pointer to a 16 bit value to swap
*
* This macro will either switch to the opposite byte sex (Big Endian vs.
* Little Endian) a 16 bit value.
*/
#define SWAP_B8_IN_B16(dest, src) ( \
*((USB16*)(dest)) = \
(((*((USB16*)(src))) << 8) | ((*((USB16*)(src))) >> 8)) \
#define SWAP_B8_IN_B16(dest, src) ( \
*((USB16*)(dest)) = \
(((*((USB16*)(src))) << 8) | ((*((USB16*)(src))) >> 8)) \
)
/*
* SWAP_B16_IN_B32 - swap 16 bits in 32 bits
*
* dest - pointer to where the swapped src wil be put
* src - pointer to a 32 bit value to swap
* dest - pointer to where the swapped src will be put
* src - pointer to a 32 bit value to swap
*/
#define SWAP_B16_IN_B32(dest, src) ( \
*((USB32*)(dest)) = \
(((*((USB32*)(src))) << 16) | ((*((USB32*)(src))) >> 16)) \
#define SWAP_B16_IN_B32(dest, src) ( \
*((USB32*)(dest)) = \
(((*((USB32*)(src))) << 16) | ((*((USB32*)(src))) >> 16)) \
)
/*
* SWAP_B8_IN_B32 - swap 8 & 16 bits in 32 bits
*
* dest - pointer to where the swapped src wil be put
* src - pointer to a 32 bit value to swap
* dest - pointer to where the swapped src will be put
* src - pointer to a 32 bit value to swap
*
* This macro will either switch to the opposite byte sex (Big Endian vs.
* Little Endian) a 32 bit value.
*/
#define SWAP_B8_IN_B32(dest, src) ( \
SWAP_B16_IN_B32(dest, src), \
(*((USB32*)(dest)) = \
((((*((USB32*)(dest))) & (USB32)0xff00ff00) >> 8) | \
(((*((USB32*)(dest))) & (USB32)0x00ff00ff) << 8))) \
#define SWAP_B8_IN_B32(dest, src) ( \
SWAP_B16_IN_B32(dest, src), \
(*((USB32*)(dest)) = \
((((*((USB32*)(dest))) & (USB32)0xff00ff00) >> 8) | \
(((*((USB32*)(dest))) & (USB32)0x00ff00ff) << 8))) \
)
#if defined(HAVE_B64)
@@ -82,41 +82,41 @@
/*
* SWAP_B32_IN_B64 - swap 32 bits in 64 bits
*
* dest - pointer to where the swapped src wil be put
* src - pointer to a 64 bit value to swap
* dest - pointer to where the swapped src will be put
* src - pointer to a 64 bit value to swap
*/
#define SWAP_B32_IN_B64(dest, src) ( \
*((USB64*)(dest)) = \
(((*((USB64*)(src))) << 32) | ((*((USB64*)(src))) >> 32)) \
#define SWAP_B32_IN_B64(dest, src) ( \
*((USB64*)(dest)) = \
(((*((USB64*)(src))) << 32) | ((*((USB64*)(src))) >> 32)) \
)
/*
* SWAP_B16_IN_B64 - swap 16 & 32 bits in 64 bits
*
* dest - pointer to where the swapped src wil be put
* src - pointer to a 64 bit value to swap
* dest - pointer to where the swapped src will be put
* src - pointer to a 64 bit value to swap
*/
#define SWAP_B16_IN_B64(dest, src) ( \
SWAP_B32_IN_B64(dest, src), \
(*((USB64*)(dest)) = \
((((*((USB64*)(dest))) & (USB64)0xffff0000ffff0000) >> 16) | \
(((*((USB64*)(dest))) & (USB64)0x0000ffff0000ffff) << 16))) \
#define SWAP_B16_IN_B64(dest, src) ( \
SWAP_B32_IN_B64(dest, src), \
(*((USB64*)(dest)) = \
((((*((USB64*)(dest))) & (USB64)0xffff0000ffff0000) >> 16) | \
(((*((USB64*)(dest))) & (USB64)0x0000ffff0000ffff) << 16))) \
)
/*
* SWAP_B8_IN_B64 - swap 16 & 32 bits in 64 bits
*
* dest - pointer to where the swapped src wil be put
* src - pointer to a 64 bit value to swap
* dest - pointer to where the swapped src will be put
* src - pointer to a 64 bit value to swap
*
* This macro will either switch to the opposite byte sex (Big Endian vs.
* Little Endian) a 64 bit value.
*/
#define SWAP_B8_IN_B64(dest, src) ( \
SWAP_B16_IN_B64(dest, src), \
(*((USB64*)(dest)) = \
((((*((USB64*)(dest))) & (USB64)0xff00ff00ff00ff00) >> 8) | \
(((*((USB64*)(dest))) & (USB64)0x00ff00ff00ff00ff) << 8))) \
#define SWAP_B8_IN_B64(dest, src) ( \
SWAP_B16_IN_B64(dest, src), \
(*((USB64*)(dest)) = \
((((*((USB64*)(dest))) & (USB64)0xff00ff00ff00ff00) >> 8) | \
(((*((USB64*)(dest))) & (USB64)0x00ff00ff00ff00ff) << 8))) \
)
#else /* HAVE_B64 */
@@ -124,52 +124,52 @@
/*
* SWAP_B32_IN_B64 - swap 32 bits in 64 bits (simulated by 2 32 bit values)
*
* dest - pointer to where the swapped src wil be put
* src - pointer to a 64 bit value to swap
* dest - pointer to where the swapped src will be put
* src - pointer to a 64 bit value to swap
*/
#define SWAP_B32_IN_B64(dest, src) ( \
((USB32*)(dest))[1] = ((USB32*)(dest))[0], \
((USB32*)(dest))[0] = ((USB32*)(dest))[1] \
#define SWAP_B32_IN_B64(dest, src) ( \
((USB32*)(dest))[1] = ((USB32*)(dest))[0], \
((USB32*)(dest))[0] = ((USB32*)(dest))[1] \
)
/*
* SWAP_B16_IN_B64 - swap 16 & 32 bits in 64 bits (simulated by 2 32 bit vals)
*
* dest - pointer to where the swapped src wil be put
* src - pointer to a 64 bit value to swap
* dest - pointer to where the swapped src will be put
* src - pointer to a 64 bit value to swap
*/
#define SWAP_B16_IN_B64(dest, src) ( \
SWAP_B16_IN_B32(((USB32*)dest)+1, ((USB32*)src)), \
SWAP_B16_IN_B32(((USB32*)dest), ((USB32*)src)+1) \
#define SWAP_B16_IN_B64(dest, src) ( \
SWAP_B16_IN_B32(((USB32*)dest)+1, ((USB32*)src)), \
SWAP_B16_IN_B32(((USB32*)dest), ((USB32*)src)+1) \
)
/*
* SWAP_B8_IN_B64 - swap 16 & 32 bits in 64 bits (simulated by 2 32 bit vals)
*
* dest - pointer to where the swapped src wil be put
* src - pointer to a 64 bit value to swap
* dest - pointer to where the swapped src will be put
* src - pointer to a 64 bit value to swap
*
* This macro will either switch to the opposite byte sex (Big Endian vs.
* Little Endian) a 64 bit value.
*/
#define SWAP_B8_IN_B64(dest, src) ( \
SWAP_B8_IN_B32(((USB32*)dest)+1, ((USB32*)src)), \
SWAP_B8_IN_B32(((USB32*)dest), ((USB32*)src)+1) \
#define SWAP_B8_IN_B64(dest, src) ( \
SWAP_B8_IN_B32(((USB32*)dest)+1, ((USB32*)src)), \
SWAP_B8_IN_B32(((USB32*)dest), ((USB32*)src)+1) \
)
#endif /* HAVE_B64 */
#if LONG_BITS == 64
#define SWAP_B32_IN_LONG(dest, src) SWAP_B32_IN_B64(dest, src)
#define SWAP_B16_IN_LONG(dest, src) SWAP_B16_IN_B64(dest, src)
#define SWAP_B8_IN_LONG(dest, src) SWAP_B8_IN_B64(dest, src)
#define SWAP_B32_IN_LONG(dest, src) SWAP_B32_IN_B64(dest, src)
#define SWAP_B16_IN_LONG(dest, src) SWAP_B16_IN_B64(dest, src)
#define SWAP_B8_IN_LONG(dest, src) SWAP_B8_IN_B64(dest, src)
#else /* LONG_BITS == 64 */
#define SWAP_B32_IN_LONG(dest, src) SWAP_B32_IN_B32(dest, src)
#define SWAP_B16_IN_LONG(dest, src) SWAP_B16_IN_B32(dest, src)
#define SWAP_B8_IN_LONG(dest, src) SWAP_B8_IN_B32(dest, src)
#define SWAP_B32_IN_LONG(dest, src) SWAP_B32_IN_B32(dest, src)
#define SWAP_B16_IN_LONG(dest, src) SWAP_B16_IN_B32(dest, src)
#define SWAP_B8_IN_LONG(dest, src) SWAP_B8_IN_B32(dest, src)
#endif /* LONG_BITS == 64 */

View File

@@ -1,16 +1,10 @@
#!/bin/make
#!/usr/bin/env make
#
# cal - makefile for calc standard resource files
#
# Copyright (C) 1999-2006,2017,2021 Landon Curt Noll
# Copyright (C) 1999-2006,2017,2021-2023 Landon Curt Noll
#
# SRC: cal/Makefile
#
# The "# SRC: ... - ..." comment line above indicates
# the origin of this file.
#
# IMPORTANT: Please see the section on Makefiles near the
# bottom of the HOWTO.INSTALL file.
# Suggestion: Read the ../HOWTO.INSTALL file.
#
# 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,188 +23,64 @@
# Under source code control: 1991/07/21 05:00:54
# File existed as early as: 1991
#
# This calculator first developed by David I. Bell with help/mods from others.
#
# chongo <was here> /\oo/\ http://www.isthe.com/chongo/
# Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
#
# calculator by David I. Bell with help/mods from others
# Makefile by Landon Curt Noll
# Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
# The shell used by this Makefile
#
# On some systems, /bin/sh is a rather reduced shell with
# deprecated behavior.
#
# If your system has a up to date, bash shell, then
# you may wish to use:
#
# SHELL= /bin/bash
#
# On some systems such as macOS, the bash shell is very
# far behind to the point where is cannot be depended on.
# On such systems, the zsh may be a much better alternative
# shell for this Makefile to use:
#
# SHELL= /bin/zsh
#
SHELL= /bin/sh
#SHELL= /bin/bash
#SHELL= /bin/zsh
# SUGGESTION: Instead of modifying this file, consider adding
# statements to modify, replace or append Makefile
# variables in the ../Makefile.local file.
####
# Normally, the upper level makefile will set these values. We provide
# a default here just in case you want to build from this directory.
####
# PREFIX - Top level location for calc
#
# The PREFIX is often prepended to paths within calc and calc Makefiles.
#
# Starting with calc v2.13.0.1, nearly all Makefile places that used
# /usr/local now use ${PREFIX}. An exception is the olduninstall rule
# and, of course, this section. :-)
#
# NOTE: The ${PREFIX} is not the same as ${T}. The ${T} specifies
# a top level directory under which calc installs things.
# While usually ${T} is empty, it can be specific path
# as if calc where "chrooted" during an install.
# The ${PREFIX} value, during install, is a path between
# the top level ${T} install directory and the object
# such as an include file.
#
# NOTE: See also, ${T}, below.
#
# There are some paths that do NOT call under ${PREFIX}, such as
# ${CALCPATH}, that include paths not under ${PREFIX}, but those
# too are exceptions to this general rule.
#
# When in doubt, try:
#
# PREFIX= /usr/local
#
PREFIX= /usr/local
#PREFIX= /usr
#PREFIX= /usr/global
###########################################
# Files used or included by this Makefile #
###########################################
# Normally certain files depend on the Makefile. If the Makefile is
# changed, then certain steps should be redone. If MAKE_FILE is
# set to Makefile, then these files will depend on Makefile. If
# MAKE_FILE is empty, then they wont.
# MAKE_FILE is empty, then they won't.
#
# If in doubt, set MAKE_FILE to Makefile
#
MAKE_FILE= Makefile
# Controlling file makefile basename (without the path)
# Calc configuration and compile configuration values
#
# This is the basename same of the makefile that may/does/will drive
# this makefile.
#
# If in doubt, set TOP_MAKE_FILE to Makefile
#
TOP_MAKE_FILE= Makefile
CONFIG_MKF= ../Makefile.config
# Where the system include (.h) files are kept
#
# For DJGPP, select:
#
# INCDIR= /dev/env/DJDIR/include
#
# If in doubt, set:
#
# INCDIR= /usr/include
# Host target information.
#
TARGET_MKF= ../Makefile.target
#INCDIR= ${PREFIX}/include
#INCDIR= /dev/env/DJDIR/include
INCDIR= /usr/include
# Local file that is included just prior to the first rule,
# that allows one to override any values set in this Makefile.
#
LOCAL_MKF= ../Makefile.local
# where to install calc related things
# The set of Makefiles
#
# ${BINDIR} where to install calc binary files
# ${LIBDIR} where calc link library (*.a) files are installed
# ${CALC_SHAREDIR} where to install calc help, .cal, startup, config files
#
# NOTE: The install rule prepends installation paths with ${T}, which
# by default is empty. If ${T} is non-empty, then installation
# locations will be relative to the ${T} directory.
#
# For DJGPP, select:
#
# BINDIR= /dev/env/DJDIR/bin
# LIBDIR= /dev/env/DJDIR/lib
# CALC_SHAREDIR= /dev/env/DJDIR/share/calc
#
# If in doubt, set:
#
# BINDIR= /usr/bin
# LIBDIR= /usr/lib
# CALC_SHAREDIR= /usr/share/calc
#
#BINDIR= ${PREFIX}/bin
#BINDIR= /dev/env/DJDIR/bin
BINDIR= /usr/bin
MK_SET= ${MAKE_FILE} ${CONFIG_MKF} ${TARGET_MKF} ${LOCAL_MKF}
#LIBDIR= ${PREFIX}/lib
#LIBDIR= /dev/env/DJDIR/lib
LIBDIR= /usr/lib
#CALC_SHAREDIR= ${PREFIX}/lib/calc
#CALC_SHAREDIR= /dev/env/DJDIR/share/calc
CALC_SHAREDIR= /usr/share/calc
#######################################################
# Calc configuration and compile configuration values #
#######################################################
include ${CONFIG_MKF}
# By default, these values are based CALC_SHAREDIR, INCDIR, BINDIR
# ---------------------------------------------------------------
# ${HELPDIR} where the help directory is installed
# ${CALC_INCDIR} where the calc include files are installed
# ${SCRIPTDIR} where calc shell scripts are installed
#
# NOTE: The install rule prepends installation paths with ${T}, which
# by default is empty. If ${T} is non-empty, then installation
# locations will be relative to the ${T} directory.
#
# If in doubt, set:
#
# HELPDIR= ${CALC_SHAREDIR}/help
# CALC_INCDIR= ${INCDIR}/calc
# SCRIPTDIR= ${BINDIR}/cscript
#
HELPDIR= ${CALC_SHAREDIR}/help
CALC_INCDIR= ${INCDIR}/calc
SCRIPTDIR= ${BINDIR}/cscript
# T - top level directory under which calc will be installed
#
# The calc install is performed under ${T}, the calc build is
# performed under /. The purpose for ${T} is to allow someone
# to install calc somewhere other than into the system area.
#
# For example, if:
#
# BINDIR= /usr/bin
# LIBDIR= /usr/lib
# CALC_SHAREDIR= /usr/share/calc
#
# and if:
#
# T= /var/tmp/testing
#
# Then the installation locations will be:
#
# calc binary files: /var/tmp/testing/usr/bin
# calc link library: /var/tmp/testing/usr/lib
# calc help, .cal ...: /var/tmp/testing/usr/share/calc
# ... etc ... /var/tmp/testing/...
#
# If ${T} is empty, calc is installed under /, which is the same
# top of tree for which it was built. If ${T} is non-empty, then
# calc is installed under ${T}, as if one had to chroot under
# ${T} for calc to operate.
#
# If in doubt, use T=
#
T=
###############################
# host target section include #
###############################
include ${TARGET_MKF}
##########################################################################
#=-=-=-=-=- Be careful if you change something below this line -=-=-=-=-=#
##########################################################################
# Makefile debug
#
@@ -220,10 +90,10 @@ T=
# H=@: do not report hsrc file formation progress
# H=@ do echo hsrc file formation progress
#
# S= >/dev/null 2>&1 slience ${CC} output during hsrc file formation
# S= >/dev/null 2>&1 silence ${CC} output during hsrc file formation
# S= full ${CC} output during hsrc file formation
#
# E= 2>/dev/null slience command stderr during hsrc file formation
# E= 2>/dev/null silence command stderr during hsrc file formation
# E= full command stderr during hsrc file formation
#
# V=@: do not echo debug statements (quiet mode)
@@ -244,52 +114,43 @@ H=@
V=@:
#V=@
# standard tools
#
CHMOD= chmod
CMP= cmp
CO= co
CP= cp
FMT= fmt
MKDIR= mkdir
MV= mv
RM= rm
RMDIR= rmdir
SED= sed
SORT= sort
TOUCH= touch
TRUE= true
# The calc files to install
#
# This list is produced by the detaillist rule when no WARNINGS are detected.
#
# Please use:
#
# make calc_files_list
# make clobber >/dev/null && make calc_files_list
#
# to keep this list in nice sorted order.
#
CALC_FILES= README alg_config.cal beer.cal bernoulli.cal \
bernpoly.cal bigprime.cal bindings brentsolve.cal chi.cal chrem.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
comma.cal constants.cal deg.cal dms.cal dotest.cal ellip.cal \
factorial.cal factorial2.cal fnv_tool.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 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.line smallfactors.cal \
solve.cal specialfunctions.cal splitbits.cal statistics.cal \
strings.cal sumsq.cal sumtimes.cal surd.cal test2300.obj_incdec.cal \
test2600.numfunc.cal test2700.isqrt.cal test3100.matobj.cal \
test3300.det.cal test3400.trig.cal test4000.ptest.cal \
test4100.redc.cal test4600.fileop.cal test5100.newdecl.cal \
test5200.globstat.cal test8000.read.cal test8400.quit.cal \
test8500.divmod.cal test8600.maxargs.cal test8700.dotest.cal \
test8900.special.cal test9300.frem.cal test9500.trigeq.cal \
toomcook.cal unitfrac.cal varargs.cal write2file.cal xx_print.cal \
zeta2.cal
# These calc files are now obsolete and are removed by the install rule.
#
DEAD_CALC_FILES= lucas_tbl.cal
DEAD_CALC_FILES= lucas_tbl.cal set8700.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
# These files are found (but not built) in the distribution
#
@@ -299,8 +160,31 @@ DISTLIST= ${CALC_FILES} ${MAKE_FILE}
#
CALCLIBLIST=
# rules that are not also names of files
#
PHONY= all distlist buildlist distdir calcliblist calc_files_list echo_inst_files \
clean clobber install uninstall
############################################################
# Allow Makefile.local to change any of the above settings #
############################################################
include ${LOCAL_MKF}
###########################################
# all - First and default Makefile target #
###########################################
all: ${CALC_FILES} ${MAKE_FILE} .all
###############################
# additional Makefile targets #
###############################
.PHONY: ${PHONY}
# used by the upper level Makefile to determine of we have done all
#
.all:
@@ -327,6 +211,13 @@ distlist: ${DISTLIST}
fi; \
done
buildlist:
${Q} for i in ${BUILD_ALL} /dev/null; do \
if [ X"$$i" != X"/dev/null" ]; then \
echo cal/$$i; \
fi; \
done | fgrep -v '.bak' | LANG=C ${SORT}
distdir:
${Q} echo cal
@@ -379,14 +270,10 @@ clobber: clean
echo ${RM} -rf .DS_Store; \
${RM} -rf .DS_Store; \
fi
-${Q} for i in ${DEAD_CALC_FILES} /dev/null; do \
-${Q} for i in ${DEAD_CALC_FILES} test082.cal outfile /dev/null; do \
if [ "$$i" = "/dev/null" ]; then \
continue; \
fi; \
if [ -e "${T}${CALC_SHAREDIR}/$$i" ]; then \
echo "${RM} -f ${T}${CALC_SHAREDIR}/$$i"; \
${RM} -f ${T}${CALC_SHAREDIR}/$$i; \
fi; \
if [ -e "./$$i" ]; then \
echo "${RM} -f ./$$i"; \
${RM} -f ./$$i; \
@@ -461,7 +348,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 \

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,11 +17,11 @@
* 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: 1996/11/13 13:21:05
* File existed as early as: 1996
* Under source code control: 1996/11/13 13:21:05
* File existed as early as: 1996
*
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
/*
@@ -30,17 +30,17 @@
for (i=99; i > 0;) {
/* current wall state */
some_bottles = (i != 1) ? "bottles" : "bottle";
print i, some_bottles, "of beer on the wall,",;
print i, some_bottles, "of beer!";
/* current wall state */
some_bottles = (i != 1) ? "bottles" : "bottle";
print i, some_bottles, "of beer on the wall,",;
print i, some_bottles, "of beer!";
/* glug, glug */
--i;
print "Take one down and pass it around,",;
/* glug, glug */
--i;
print "Take one down and pass it around,",;
/* new wall state */
less = (i > 0) ? i : "no";
bottles = (i!=1) ? "bottles" : "bottle";
print less, bottles, "of beer on the wall!\n";
/* new wall state */
less = (i > 0) ? i : "no";
bottles = (i!=1) ? "bottles" : "bottle";
print less, bottles, "of beer on the wall!\n";
}

View File

@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,10 +17,10 @@
* 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: 1991/09/30 11:18:41
* File existed as early as: 1991
* Under source code control: 1991/09/30 11:18:41
* File existed as early as: 1991
*
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
/*
@@ -30,16 +30,16 @@
*
* The non-builtin code used the following symbolic formula to calculate B(n):
*
* (b+1)^(n+1) - b^(n+1) = 0
* (b+1)^(n+1) - b^(n+1) = 0
*
* where b is a dummy value, and each power b^i gets replaced by B(i).
* For example, for n = 3:
*
* (b+1)^4 - b^4 = 0
* b^4 + 4*b^3 + 6*b^2 + 4*b + 1 - b^4 = 0
* 4*b^3 + 6*b^2 + 4*b + 1 = 0
* 4*B(3) + 6*B(2) + 4*B(1) + 1 = 0
* B(3) = -(6*B(2) + 4*B(1) + 1) / 4
* (b+1)^4 - b^4 = 0
* b^4 + 4*b^3 + 6*b^2 + 4*b + 1 - b^4 = 0
* 4*b^3 + 6*b^2 + 4*b + 1 = 0
* 4*B(3) + 6*B(2) + 4*B(1) + 1 = 0
* B(3) = -(6*B(2) + 4*B(1) + 1) / 4
*
* The combinatorial factors in the expansion of the above formula are
* calculated interactively, and we use the fact that B(2i+1) = 0 if i > 0.
@@ -56,38 +56,38 @@ static mat Bn[1001];
define B(n)
{
/*
local nn, np1, i, sum, mulval, divval, combval;
local nn, np1, i, sum, mulval, divval, combval;
if (!isint(n) || (n < 0))
quit "Non-negative integer required for Bernoulli";
if (!isint(n) || (n < 0))
quit "Non-negative integer required for Bernoulli";
if (n == 0)
return 1;
if (n == 1)
return -1/2;
if (isodd(n))
return 0;
if (n > 1000)
quit "Very large Bernoulli";
if (n == 0)
return 1;
if (n == 1)
return -1/2;
if (isodd(n))
return 0;
if (n > 1000)
quit "Very large Bernoulli";
if (n <= Bnmax)
return Bn[n];
if (n <= Bnmax)
return Bn[n];
for (nn = Bnmax + 2; nn <= n; nn+=2) {
np1 = nn + 1;
mulval = np1;
divval = 1;
combval = 1;
sum = 1 - np1 / 2;
for (i = 2; i < np1; i+=2) {
combval = combval * mulval-- / divval++;
combval = combval * mulval-- / divval++;
sum += combval * Bn[i];
}
Bn[nn] = -sum / np1;
}
Bnmax = n;
return Bn[n];
for (nn = Bnmax + 2; nn <= n; nn+=2) {
np1 = nn + 1;
mulval = np1;
divval = 1;
combval = 1;
sum = 1 - np1 / 2;
for (i = 2; i < np1; i+=2) {
combval = combval * mulval-- / divval++;
combval = combval * mulval-- / divval++;
sum += combval * Bn[i];
}
Bn[nn] = -sum / np1;
}
Bnmax = n;
return Bn[n];
*/
return bernoulli(n);
return bernoulli(n);
}

View File

@@ -17,8 +17,8 @@
* 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: 2013/08/11 01:31:28
* File existed as early as: 2013
* Under source code control: 2013/08/11 01:31:28
* File existed as early as: 2013
*/

View File

@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,29 +17,29 @@
* 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: 1991/05/22 21:56:32
* File existed as early as: 1991
* Under source code control: 1991/05/22 21:56:32
* File existed as early as: 1991
*
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
define bigprime(a, m, p)
{
local n1, n;
local n1, n;
n1 = 2^m * p;
for (;;) {
m++;
n1 += n1;
n = n1 + 1;
if (isodd(m))
continue;
print m;
if (pmod(a, n1 / 2, n) != n1)
continue;
if (pmod(a, n1 / p, n) == 1)
continue;
print " " : n;
}
n1 = 2^m * p;
for (;;) {
m++;
n1 += n1;
n = n1 + 1;
if (isodd(m))
continue;
print m;
if (pmod(a, n1 / 2, n) != n1)
continue;
if (pmod(a, n1 / p, n) == 1)
continue;
print " " : n;
}
}

View File

@@ -8,7 +8,7 @@
#
# 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
# 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
@@ -16,56 +16,56 @@
# 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: 1993/05/02 20:09:19
# File existed as early as: 1993
# Under source code control: 1993/05/02 20:09:19
# File existed as early as: 1993
#
# Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
# NOTE: This facility is ignored if calc was compiled with GNU-readline.
# In that case, the standard readline mechanisms (see readline(3))
# are used in place of those found below.
# In that case, the standard readline mechanisms (see readline(3))
# are used in place of those found below.
map base-map
map base-map
default insert-char
^@ set-mark
^A start-of-line
^B backward-char
^D delete-char
^E end-of-line
^F forward-char
^H backward-kill-char
^J new-line
^K kill-line
^L refresh-line
^M new-line
^N forward-history
^O save-line
^P backward-history
^R reverse-search
^T swap-chars
^U flush-input
^V quote-char
^W kill-region
^Y yank
^? backward-kill-char
^[ ignore-char esc-map
^@ set-mark
^A start-of-line
^B backward-char
^D delete-char
^E end-of-line
^F forward-char
^H backward-kill-char
^J new-line
^K kill-line
^L refresh-line
^M new-line
^N forward-history
^O save-line
^P backward-history
^R reverse-search
^T swap-chars
^U flush-input
^V quote-char
^W kill-region
^Y yank
^? backward-kill-char
^[ ignore-char esc-map
map esc-map
default ignore-char base-map
G start-of-line
H backward-history
P forward-history
K backward-char
M forward-char
O end-of-line
S delete-char
g goto-line
s backward-word
t forward-word
d forward-kill-word
u uppercase-word
l lowercase-word
h list-history
^[ flush-input
[ arrow-key
map esc-map
default ignore-char base-map
G start-of-line
H backward-history
P forward-history
K backward-char
M forward-char
O end-of-line
S delete-char
g goto-line
s backward-word
t forward-word
d forward-kill-word
u uppercase-word
l lowercase-word
h list-history
^[ flush-input
[ arrow-key

View File

@@ -17,8 +17,8 @@
* 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: 2013/08/11 01:31:28
* File existed as early as: 2013
* Under source code control: 2013/08/11 01:31:28
* File existed as early as: 2013
*/

View File

@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,11 +17,11 @@
* 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: 2001/03/27 14:10:11
* File existed as early as: 2001
* Under source code control: 2001/03/27 14:10:11
* File existed as early as: 2001
*
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
@@ -29,20 +29,20 @@
* Z(x)
*
* From Handbook of Mathematical Functions
* 10th printing, Dec 1972 with corrections
* National Bureau of Standards
* 10th printing, Dec 1972 with corrections
* National Bureau of Standards
*
* Section 26.2.1, p931.
*/
define Z(x, eps_term)
{
local eps; /* error term */
local eps; /* error term */
/* obtain the error term */
if (isnull(eps_term)) {
eps = epsilon();
eps = epsilon();
} else {
eps = eps_term;
eps = eps_term;
}
/* compute Z(x) value */
@@ -56,46 +56,46 @@ define Z(x, eps_term)
* NOTE: If eps is omitted, the stored epsilon value is used.
*
* From Handbook of Mathematical Functions
* 10th printing, Dec 1972 with corrections
* National Bureau of Standards
* 10th printing, Dec 1972 with corrections
* National Bureau of Standards
*
* 26.2.11, p932:
*
* P(x) = 1/2 + Z(x) * sum(n=0; n < infinity){x^(2*n+1)/(1*3*5*...(2*n+1)};
* P(x) = 1/2 + Z(x) * sum(n=0; n < infinity){x^(2*n+1)/(1*3*5*...(2*n+1)};
*
* We continue the fraction until it is less than epsilon error term.
*
* Also note 26.2.5:
*
* P(x) + Q(x) = 1
* P(x) + Q(x) = 1
*/
define P(x, eps_term)
{
local eps; /* error term */
local s; /* sum */
local x2; /* x^2 */
local x_term; /* x^(2*r+1) */
local odd_prod; /* 1*3*5* ... */
local odd_term; /* next odd value to multiply into odd_prod */
local term; /* the recent term added to the sum */
local eps; /* error term */
local s; /* sum */
local x2; /* x^2 */
local x_term; /* x^(2*r+1) */
local odd_prod; /* 1*3*5* ... */
local odd_term; /* next odd value to multiply into odd_prod */
local term; /* the recent term added to the sum */
/* obtain the error term */
if (isnull(eps_term)) {
eps = epsilon();
eps = epsilon();
} else {
eps = eps_term;
eps = eps_term;
}
/* firewall */
if (x <= 0) {
if (x == 0) {
return 0; /* hack */
} else {
quit "Q(x[,eps]) 1st argument must be >= 0";
}
if (x == 0) {
return 0; /* hack */
} else {
quit "Q(x[,eps]) 1st argument must be >= 0";
}
}
if (eps <= 0) {
quit "Q(x[,eps]) 2nd argument must be > 0";
quit "Q(x[,eps]) 2nd argument must be > 0";
}
/*
@@ -103,17 +103,17 @@ define P(x, eps_term)
*/
x2 = x*x;
x_term = x;
s = x_term; /* 1st term */
s = x_term; /* 1st term */
odd_term = 1;
odd_prod = 1;
do {
/* compute the term */
odd_term += 2;
odd_prod *= odd_term;
x_term *= x2;
term = x_term / odd_prod;
s += term;
/* compute the term */
odd_term += 2;
odd_prod *= odd_term;
x_term *= x2;
term = x_term / odd_prod;
s += term;
} while (term >= eps);
@@ -133,68 +133,68 @@ define P(x, eps_term)
* a sufficiently small error term as the degrees gets large (>100).
*
* NOTE: This function does not work well with odd degrees of freedom.
* Can somebody help / find a bug / provide a better method of
* this odd degrees of freedom case?
* Can somebody help / find a bug / provide a better method of
* this odd degrees of freedom case?
*
* NOTE: This function works well with even degrees of freedom. However
* when the even degrees gets large (say, as you approach 100), you
* need to increase your error term.
* when the even degrees gets large (say, as you approach 100), you
* need to increase your error term.
*
* From Handbook of Mathematical Functions
* 10th printing, Dec 1972 with corrections
* National Bureau of Standards
* 10th printing, Dec 1972 with corrections
* National Bureau of Standards
*
* Section 26.4.4, p941:
*
* For odd v:
*
* Q(chi_sq, v) = 2*Q(chi) + 2*Z(chi) * (
* sum(r=1, r<=(r-1)/2) {(chi_sq^r/chi) / (1*3*5*...(2*r-1)});
* Q(chi_sq, v) = 2*Q(chi) + 2*Z(chi) * (
* sum(r=1, r<=(r-1)/2) {(chi_sq^r/chi) / (1*3*5*...(2*r-1)});
*
* chi = sqrt(chi_sq)
* chi = sqrt(chi_sq)
*
* NOTE: Q(x) = 1-P(x)
* NOTE: Q(x) = 1-P(x)
*
* Section 26.4.5, p941.
*
* For even v:
*
* Q(chi_sq, v) = sqrt(2*pi()) * Z(chi) * ( 1 +
* sum(r=1, r=((v-2)/2)) { chi_sq^r / (2*4*...*(2r)) } );
* Q(chi_sq, v) = sqrt(2*pi()) * Z(chi) * ( 1 +
* sum(r=1, r=((v-2)/2)) { chi_sq^r / (2*4*...*(2r)) } );
*
* chi = sqrt(chi_sq)
* chi = sqrt(chi_sq)
*
* Observe that:
*
* Z(x) = exp(-x*x/2) / sqrt(2*pi()); (Section 26.2.1, p931)
* Z(x) = exp(-x*x/2) / sqrt(2*pi()); (Section 26.2.1, p931)
*
* and thus:
*
* sqrt(2*pi()) * Z(chi) =
* sqrt(2*pi()) * Z(sqrt(chi_sq)) =
* sqrt(2*pi()) * exp(-sqrt(chi_sq)*sqrt(chi_sq)/2) / sqrt(2*pi()) =
* exp(-sqrt(chi_sq)*sqrt(chi_sq)/2) =
* exp(-sqrt(-chi_sq/2)
* sqrt(2*pi()) * Z(chi) =
* sqrt(2*pi()) * Z(sqrt(chi_sq)) =
* sqrt(2*pi()) * exp(-sqrt(chi_sq)*sqrt(chi_sq)/2) / sqrt(2*pi()) =
* exp(-sqrt(chi_sq)*sqrt(chi_sq)/2) =
* exp(-sqrt(-chi_sq/2)
*
* So:
*
* Q(chi_sq, v) = exp(-sqrt(-chi_sq/2) * ( 1 + sum(....){...} );
* Q(chi_sq, v) = exp(-sqrt(-chi_sq/2) * ( 1 + sum(....){...} );
*/
define chi_prob(chi_sq, v, eps_term)
{
local eps; /* error term */
local r; /* index in finite sum */
local r_lim; /* limit value for r */
local s; /* sum */
local d; /* denominator (2*4*6*... or 1*3*5...) */
local chi_term; /* chi_sq^r */
local ret; /* return value */
local eps; /* error term */
local r; /* index in finite sum */
local r_lim; /* limit value for r */
local s; /* sum */
local d; /* denominator (2*4*6*... or 1*3*5...) */
local chi_term; /* chi_sq^r */
local ret; /* return value */
/* obtain the error term */
if (isnull(eps_term)) {
eps = epsilon();
eps = epsilon();
} else {
eps = eps_term;
eps = eps_term;
}
/*
@@ -202,45 +202,45 @@ define chi_prob(chi_sq, v, eps_term)
*/
if (isodd(v)) {
local chi; /* sqrt(chi_sq) */
local chi; /* sqrt(chi_sq) */
/* setup for sum */
s = 1;
d = 1;
chi = sqrt(abs(chi_sq), eps);
chi_term = chi;
r_lim = (v-1)/2;
/* setup for sum */
s = 1;
d = 1;
chi = sqrt(abs(chi_sq), eps);
chi_term = chi;
r_lim = (v-1)/2;
/* compute sum(r=1, r=((v-1)/2)) {(chi_sq^r/chi) / (1*3*5...*(2r-1))} */
for (r=2; r <= r_lim; ++r) {
chi_term *= chi_sq;
d *= (2*r)-1;
s += chi_term/d;
}
/* compute sum(r=1, r=((v-1)/2)) {(chi_sq^r/chi) / (1*3*5...*(2r-1))} */
for (r=2; r <= r_lim; ++r) {
chi_term *= chi_sq;
d *= (2*r)-1;
s += chi_term/d;
}
/* apply term and factor, Q(x) = 1-P(x) */
ret = 2*(1-P(chi)) + 2*Z(chi)*s;
/* apply term and factor, Q(x) = 1-P(x) */
ret = 2*(1-P(chi)) + 2*Z(chi)*s;
/*
* even degrees of freedom
*/
} else {
/* setup for sum */
s =1;
d = 1;
chi_term = 1;
r_lim = (v-2)/2;
/* setup for sum */
s =1;
d = 1;
chi_term = 1;
r_lim = (v-2)/2;
/* compute sum(r=1, r=((v-2)/2)) { chi_sq^r / (2*4*...*(2r)) } */
for (r=1; r <= r_lim; ++r) {
chi_term *= chi_sq;
d *= r*2;
s += chi_term/d;
}
/* compute sum(r=1, r=((v-2)/2)) { chi_sq^r / (2*4*...*(2r)) } */
for (r=1; r <= r_lim; ++r) {
chi_term *= chi_sq;
d *= r*2;
s += chi_term/d;
}
/* apply factor - see observation in the main comment above */
ret = exp(-chi_sq/2, eps) * s;
/* apply factor - see observation in the main comment above */
ret = exp(-chi_sq/2, eps) * s;
}
return ret;

View File

@@ -11,7 +11,7 @@
*
* 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
* 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
@@ -19,33 +19,33 @@
* 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: 1992/09/26 01:00:47
* File existed as early as: 1992
* Under source code control: 1992/09/26 01:00:47
* File existed as early as: 1992
*
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
/*
* When possible, chrem finds solutions for x of a set of congruence
* of the form:
*
* x = r1 (mod m1)
* x = r2 (mod m2)
* ...
* x = r1 (mod m1)
* x = r2 (mod m2)
* ...
*
* where the residues r1, r2, ... and the moduli m1, m2, ... are
* given integers. The Chinese remainder theorem states that if
* m1, m2, ... are relatively prime in pairs, the above congruence
* have a unique solution modulo m1 * m2 * ... If m1, m2, ...
* have a unique solution modulo m1 * m2 * ... If m1, m2, ...
* are not relatively prime in pairs, it is possible that no solution
* exists. If solutions exist, the general solution is expressible as:
*
* x = r (mod m)
* x = r (mod m)
*
* where m = lcm(m1,m2,...), and if m > 0, 0 <= r < m. This
* where m = lcm(m1,m2,...), and if m > 0, 0 <= r < m. This
* solution may be interpreted as:
*
* x = r + k * m [[NOTE 1]]
* x = r + k * m [[NOTE 1]]
*
* where k is an arbitrary integer.
*
@@ -53,19 +53,19 @@
*
* usage:
*
* chrem(r1,m1 [,r2,m2, ...])
* chrem(r1,m1 [,r2,m2, ...])
*
* r1, r2, ... remainder integers or null values
* m1, m2, ... moduli integers
* r1, r2, ... remainder integers or null values
* m1, m2, ... moduli integers
*
* chrem(r_list, [m_list])
* chrem(r_list, [m_list])
*
* r_list list (r1,r2, ...)
* m_list list (m1,m2, ...)
* r_list list (r1,r2, ...)
* m_list list (m1,m2, ...)
*
* If m_list is omitted, then 'defaultmlist' is used.
* This default list is a global value that may be changed
* by the user. Initially it is the first 8 primes.
* If m_list is omitted, then 'defaultmlist' is used.
* This default list is a global value that may be changed
* by the user. Initially it is the first 8 primes.
*
* If a remainder is null(), then the corresponding congruence is
* ignored. This is useful when working with a fixed list of moduli.
@@ -75,17 +75,17 @@
*
* The moduli may be any integers, not necessarily relatively prime in
* pairs (as required for the Chinese remainder theorem). Any moduli
* may be zero; x = r (mod 0) has the meaning of x = r.
* may be zero; x = r (mod 0) has the meaning of x = r.
*
* returns:
*
* If args were integer pairs:
*
* r ('r' is defined above, see [[NOTE 1]])
* r ('r' is defined above, see [[NOTE 1]])
*
* If 1 or 2 list args were given:
*
* (r, m) ('r' and 'm' are defined above, see [[NOTE 1]])
* (r, m) ('r' and 'm' are defined above, see [[NOTE 1]])
*
* NOTE: In all cases, null() is returned if there is no solution.
*
@@ -95,20 +95,20 @@
*
* Sun-Tsu, 1st century A.D.
*
* To find a number for which the reminders after division by 3, 5, 7
* are 2, 3, 2, respectively:
* To find a number for which the reminders after division by 3, 5, 7
* are 2, 3, 2, respectively:
*
* chrem(2,3,3,5,2,7) ---> 23
* chrem(2,3,3,5,2,7) ---> 23
*
* Fibonacci, 13th century A.D.
*
* To find a number divisible by 7 which leaves remainder 1 when
* divided by 2, 3, 4, 5, or 6:
* To find a number divisible by 7 which leaves remainder 1 when
* divided by 2, 3, 4, 5, or 6:
*
*
* chrem(list(0,1,1,1,1,1),list(7,2,3,4,5,6)) ---> (301,420)
* chrem(list(0,1,1,1,1,1),list(7,2,3,4,5,6)) ---> (301,420)
*
* i.e., any value that is 301 mod 420.
* i.e., any value that is 301 mod 420.
*/
@@ -116,10 +116,10 @@ static defaultmlist = list(2,3,5,7,11,13,17,19); /* The first eight primes */
define chrem()
{
local argc; /* number of args given */
local rlist; /* reminder list - ri */
local mlist; /* modulus list - mi */
local list_args; /* true => args given are lists, not r1,m1, ... */
local argc; /* number of args given */
local rlist; /* reminder list - ri */
local mlist; /* modulus list - mi */
local list_args; /* true => args given are lists, not r1,m1, ... */
local m,z,r,y,d,t,x,u,i;
/*
@@ -127,25 +127,25 @@ define chrem()
*/
argc = param(0);
if (argc == 0) {
quit "usage: chrem(r1,m1 [,r2,m2 ...]) or chrem(r_list, m_list)";
quit "usage: chrem(r1,m1 [,r2,m2 ...]) or chrem(r_list, m_list)";
}
list_args = islist(param(1));
if (list_args) {
rlist = param(1);
mlist = (argc == 1) ? defaultmlist : param(2);
if (size(rlist) > size(mlist)) {
quit "too many residues";
}
rlist = param(1);
mlist = (argc == 1) ? defaultmlist : param(2);
if (size(rlist) > size(mlist)) {
quit "too many residues";
}
} else {
if (argc % 2 == 1) {
quit "odd number integers given";
}
rlist = list();
mlist = list();
for (i=1; i <= argc; i+=2) {
push(rlist, param(i));
push(mlist, param(i+1));
}
if (argc % 2 == 1) {
quit "odd number integers given";
}
rlist = list();
mlist = list();
for (i=1; i <= argc; i+=2) {
push(rlist, param(i));
push(mlist, param(i+1));
}
}
/*
@@ -154,46 +154,46 @@ define chrem()
m = 1;
z = 0;
while (size(rlist)) {
r=pop(rlist);
y=abs(pop(mlist));
if (r==null())
continue;
if (m) {
if (y) {
d = t = z - r;
m = lcm(x=m, y);
while (d % y) {
u = x;
x %= y;
swap(x,y);
if (y==0)
return;
z += (t *= -u/y);
}
} else {
if ((r % m) != (z % m))
return;
else {
m = 0;
z = r;
}
}
} else if (((y) && (r % y != z % y)) || (r != z))
return;
r=pop(rlist);
y=abs(pop(mlist));
if (r==null())
continue;
if (m) {
if (y) {
d = t = z - r;
m = lcm(x=m, y);
while (d % y) {
u = x;
x %= y;
swap(x,y);
if (y==0)
return;
z += (t *= -u/y);
}
} else {
if ((r % m) != (z % m))
return;
else {
m = 0;
z = r;
}
}
} else if (((y) && (r % y != z % y)) || (r != z))
return;
}
if (m) {
z %= m;
if (z < 0)
z += m;
z %= m;
if (z < 0)
z += m;
}
/*
* return information as required
*/
if (list_args) {
return list(z,m);
return list(z,m);
} else {
return z;
return z;
}
}

437
cal/comma.cal Normal file
View File

@@ -0,0 +1,437 @@
/*
* comma - convert numbers into strings with 3-digit group and integer-fraction separators
*
* Convert numbers into strings with 3-digit group and integer-fraction separators.
*
* If the value is an integer, the integer-fraction separator is not used.
*
* str_comma(x, [group, [decimal]])
*
* Convert x into a string.
*
* If group is given and is a string, group will be used as
* the 3-digit group separator, otherwise the default 3-digit
* group separator will be used.
*
* If decimal is given and is a string, group will be used as
* the integer-fraction separator, otherwise the default
* integer-fraction separator will be used.
*
* The decimal and group arguments are optional.
*
* set_default_group_separator(group)
*
* Change the default 3-digit group separator if group is a string,
* otherwise the default 3-digit group separator will not be
* changed. Return the old 3-digit group separator.
*
* set_default_decimal_separator(decimal)
*
* Change the default 3-digit group separator if decimal is a
* string, otherwise the default integer-fraction separator
* will not be changed. Return the old integer-fraction separator.
*
* print_comma(x, [group, [decimal]])
*
* Print the value produced by str_comma(x, [group, [decimal]])
* followed by a newline.
*
* If the str_comma() does not return a string, nothing is printed.
*
* The decimal and group arguments are optional.
*
* The value produced by str_comma() is returned.
*
* fprint_comma(fd, x, [group, [decimal]])
*
* Print the value produced by str_comma(x, [group, [decimal]]),
* without a trailing newline, on file fd.
*
* If the str_comma() does not return a string, nothing is printed.
*
* If fd is not an open file, nothing is printed.
*
* The decimal and group arguments are optional.
*
* The value produced by str_comma() is returned.
*
* Copyright (C) 2022 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: 2022/06/20 15:51:49
* File existed as early as: 2022
*
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
static default_group_separator = ","; /* default 3-digit group separator */
static default_decimal_separator = "."; /* default integer-fraction separator */
/*
* str_comma - convert number into base 10 string with 3-digit groups and integer-fraction separator
*
*
* This function converts a real number into a base 10 string, where
* groups of 3 digits are separated by a 3-digit group separator and
* a integer-fraction separator is printed between integer and decimal fraction.
*
* For example:
*
* string = str_comma(x);
* string = str_comma(x), " ", ".");
* string = str_comma(x), ".", ",");
*
* Internally the function calls:
*
* strprintf("%f", x);
*
* and thus the number of decimal fraction digits is subject to
* the display() or config("display") value. See:
*
* man display
*
* for details.
*
* given:
*
* x number to convert
*
* optional args:
*
* group use this 3-digit group separator
* decimal use this integer-fraction separator
*
* returns:
*
* string containing the base 10 digits with group and decimal separators, OR
* null() if x is not a number, OR
* null() if group is neither null() (not given) nor a string, OR
* null() if group is null() (not given) AND default_group_separator is not a string, OR
* null() if decimal is neither null() (not given) nor a string, OR
* null() if decimal is null() (not given) AND default_decimal_separator is not a string.
*/
define str_comma(x, group, decimal)
{
local group_separator; /* 3-digit group separator */
local decimal_separator; /* separator between decimal integer and decimal fraction */
local sign_str; /* leading - if x < 0 or empty if x >= 0 */
local integer; /* integer part of absolute value of x */
local int_str; /* integer as a string */
local int_len; /* number of digits in int_str */
local first_group_len; /* length of 1st group before the 1st 3-digit group separator */
local fraction; /* factional part of absolute value of x */
local frac_str; /* fraction as a string */
local frac_len; /* number of digits in frac_str including leading 0. */
local ret; /* string to return */
local config_leadzero; /* config("leadzero") to restore */
local config_tilde; /* config("tilde") to restore */
local i;
/*
* parse args - return null if args are bogus
*
* Return null() if args or conditions are bogus.
*/
if (!isreal(x)) {
return null();
}
group_separator = isnull(group) ? default_group_separator : group;
decimal_separator = isnull(decimal) ? default_decimal_separator : decimal;
if (!isstr(group_separator)) {
return null();
}
if (!isstr(decimal_separator)) {
return null();
}
/*
* split number
*/
if (x < 0) {
sign_str = "-";
integer = int(-x);
fraction = frac(-x);
} else {
sign_str = "";
integer = int(x);
fraction = frac(x);
}
ret = sign_str;
/*
* convert digits
*
* Avoid printing ~ and leading zeros for factional part.
*/
int_str = strprintf("%d", integer);
config_leadzero = config("leadzero", 0);
config_tilde = config("tilde", 0);
frac_str = strprintf("%d", fraction);
config("leadzero", config_leadzero),;
config("tilde", config_tilde),;
/*
* determine number of digits in the integer part
*/
int_len = strlen(int_str);
frac_len = strlen(frac_str);
/*
* form integer part with group separators as needed
*/
/*
* case: integer is 3 or fewer digits
*/
if (integer < 1000) {
ret += int_str;
/*
* case: integer is 4 or more digits
*/
} else {
/*
* form a decimal string using group separators
*/
/*
* form the initial leading digits before 1st group separator
*/
first_group_len = int_len % 3;
if (first_group_len == 0) {
first_group_len = 3;
}
ret += substr(int_str, 1, first_group_len);
/*
* until end of digits, print group separator followed by 3 more digits
*/
for (i = first_group_len+1; i < int_len; i += 3) {
ret += group_separator + substr(int_str, i, 3);
}
}
/*
* form fractional part using decimal separator as needed
*/
/*
* case: x is an integer
*/
if (fraction == 0) {
/* no fraction, nothing more to do */
/*
* case: x is not an integer
*/
} else {
/*
* add integer-fraction separator
*/
ret += decimal_separator;
/*
* add remaining digits
*
* Skip over the leading 0. in frac_str
*/
ret += substr(frac_str, 2, frac_len-1);
}
/*
* All Done!!! -- Jessica Noll, Age 2
*/
return ret;
}
/*
* set_default_group_separator - change the default 3-digit group separator
*
* If group is not a string, then the default 3-digit group separator
* is not changed. Thus, this will only return the default 3-digit group separator:
*
* set_default_group_separator(null());
*
* given:
*
* group 3-digit group separator
*
* returns:
*
* previous 3-digit group separator value
*/
define set_default_group_separator(group)
{
local old_default_group_separator; /* previous default 3-digit group separator to return */
/*
* save current 3-digit group separator
*/
old_default_group_separator = default_group_separator;
/*
* change 3-digit group separator if group is a string
*/
if (isstr(group)) {
default_group_separator = group;
}
return old_default_group_separator;
}
/*
* set_default_decimal_separator - change the default integer-fraction separator
*
* If decimal is not a string, then the default integer-fraction separator
* is not changed. Thus, this will only return the integer-fraction separator:
*
* set_default_decimal_separator(null());
*
* given:
*
* decimal separator between decimal integer and decimal fraction (def: ".")
*
* returns:
*
* previous integer-fraction separator value
*/
define set_default_decimal_separator(decimal)
{
local old_default_decimal_separator; /* previous default integer-fraction separator */
/*
* save current integer-fraction separator
*/
old_default_decimal_separator = default_decimal_separator;
/*
* change 3-digit decimal integer-fraction if decimal is a string
*/
if (isstr(decimal)) {
default_decimal_separator = decimal;
}
return old_default_decimal_separator;
}
/*
* print_comma - print base 10 string with 3-digit group separators & integer-fraction separator + newline
*
* This function prints the result of str_comma(x, group, decimal) followed by a newline.
* For example:
*
* print_comma(x);
* print_comma(x), " ", ".");
* print_comma(x), ".", ",");
*
* If str_comma() does not return a string, this function prints nothing.
*
* NOTE: To print without a newline, use fprint_comma(fd, x, group, decimal).
*
* given:
* x number to convert
*
* optional args:
*
* group use this 3-digit group separator
* decimal use this integer-fraction separator
*
* returns:
*
* string containing the base 10 digits with group and decimal separators, OR
* null() if x is not a number, OR
* null() if group is neither null() (not given) nor a string, OR
* null() if group is null() (not given) AND default_group_separator is not a string, OR
* null() if decimal is neither null() (not given) nor a string, OR
* null() if decimal is null() (not given) AND default_decimal_separator is not a string.
*/
define print_comma(x, group, decimal)
{
local ret; /* base 10 string with 3-digit group and integer-fraction separators */
/*
* convert to string
*/
ret = str_comma(x, group, decimal);
/*
* print converted string
*/
if (isstr(ret)) {
printf("%s\n", ret);
}
return ret;
}
/*
* fprint_comma - print base 10 string with 3-digit group separators & integer-fraction separator w/o newline
*
* This function prints the result of str_comma(x, group, decimal) on an open file, without a trailing newline.
* For example:
*
* fprint_comma(files(1), x);
* fprint_comma(fd, x), " ", ".");
* fprint_comma(files(2), x), ".", ",");
*
* If str_comma() does not return a string, this function prints nothing.
*
* This function flushes output to the open file before returning.
*
* NOTE: To print with a newline, use print_comma(x, group, decimal).
*
* given:
* fd open file
* x number to convert
*
* optional args:
*
* group use this 3-digit group separator
* decimal use this integer-fraction separator
*
* returns:
*
* string containing the base 10 digits with group and integer-fraction separators, OR
* null() if x is not a number, OR
* null() if group is neither null() (not given) nor a string, OR
* null() if group is null() (not given) AND default_group_separator is not a string, OR
* null() if decimal is neither null() (not given) nor a string, OR
* null() if decimal is null() (not given) AND default_decimal_separator is not a string.
*/
define fprint_comma(fd, x, group, decimal)
{
local ret; /* base 10 string with 3-digit group and integer-fraction separators */
/*
* convert to string
*/
ret = str_comma(x, group, decimal);
/*
* print converted string
*/
if (isstr(ret) && isfile(fd)) {
fprintf(fd, "%s", ret);
fflush(fd);
}
return ret;
}

View File

@@ -17,8 +17,8 @@
* 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: 2013/08/11 01:31:28
* File existed as early as: 2013
* Under source code control: 2013/08/11 01:31:28
* File existed as early as: 2013
*/

View File

@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,10 +17,10 @@
* 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: 1990/02/15 01:50:33
* File existed as early as: before 1990
* Under source code control: 1990/02/15 01:50:33
* File existed as early as: before 1990
*
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
@@ -28,105 +28,105 @@ obj deg {deg, min, sec};
define deg(deg, min, sec)
{
local ans;
local ans;
if (isnull(sec))
sec = 0;
if (isnull(min))
min = 0;
obj deg ans;
ans.deg = deg;
ans.min = min;
ans.sec = sec;
fixdeg(ans);
return ans;
if (isnull(sec))
sec = 0;
if (isnull(min))
min = 0;
obj deg ans;
ans.deg = deg;
ans.min = min;
ans.sec = sec;
fixdeg(ans);
return ans;
}
define deg_add(a, b)
{
local obj deg ans;
local obj deg ans;
ans.deg = 0;
ans.min = 0;
ans.sec = 0;
if (istype(a, ans)) {
ans.deg += a.deg;
ans.min += a.min;
ans.sec += a.sec;
} else
ans.deg += a;
if (istype(b, ans)) {
ans.deg += b.deg;
ans.min += b.min;
ans.sec += b.sec;
} else
ans.deg += b;
fixdeg(ans);
return ans;
ans.deg = 0;
ans.min = 0;
ans.sec = 0;
if (istype(a, ans)) {
ans.deg += a.deg;
ans.min += a.min;
ans.sec += a.sec;
} else
ans.deg += a;
if (istype(b, ans)) {
ans.deg += b.deg;
ans.min += b.min;
ans.sec += b.sec;
} else
ans.deg += b;
fixdeg(ans);
return ans;
}
define deg_neg(a)
{
local obj deg ans;
local obj deg ans;
ans.deg = -a.deg;
ans.min = -a.min;
ans.sec = -a.sec;
return ans;
ans.deg = -a.deg;
ans.min = -a.min;
ans.sec = -a.sec;
return ans;
}
define deg_sub(a, b)
{
return a - b;
return a - b;
}
define deg_mul(a, b)
{
local obj deg ans;
local obj deg ans;
if (istype(a, ans) && istype(b, ans))
quit "Cannot multiply degrees together";
if (istype(a, ans)) {
ans.deg = a.deg * b;
ans.min = a.min * b;
ans.sec = a.sec * b;
} else {
ans.deg = b.deg * a;
ans.min = b.min * a;
ans.sec = b.sec * a;
}
fixdeg(ans);
return ans;
if (istype(a, ans) && istype(b, ans))
quit "Cannot multiply degrees together";
if (istype(a, ans)) {
ans.deg = a.deg * b;
ans.min = a.min * b;
ans.sec = a.sec * b;
} else {
ans.deg = b.deg * a;
ans.min = b.min * a;
ans.sec = b.sec * a;
}
fixdeg(ans);
return ans;
}
define deg_print(a)
{
print a.deg : 'd' : a.min : 'm' : a.sec : 's' :;
print a.deg : 'd' : a.min : 'm' : a.sec : 's' :;
}
define deg_abs(a)
{
return a.deg + a.min / 60 + a.sec / 3600;
return a.deg + a.min / 60 + a.sec / 3600;
}
define fixdeg(a)
{
a.min += frac(a.deg) * 60;
a.deg = int(a.deg);
a.sec += frac(a.min) * 60;
a.min = int(a.min);
a.min += a.sec // 60;
a.sec %= 60;
a.deg += a.min // 60;
a.min %= 60;
a.deg %= 360;
a.min += frac(a.deg) * 60;
a.deg = int(a.deg);
a.sec += frac(a.min) * 60;
a.min = int(a.min);
a.min += a.sec // 60;
a.sec %= 60;
a.deg += a.min // 60;
a.min %= 60;
a.deg %= 360;
}
if (config("resource_debug") & 3) {

View File

@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,10 +17,10 @@
* 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: 1990/02/15 01:50:33
* File existed as early as: before 1990
* Under source code control: 1990/02/15 01:50:33
* File existed as early as: before 1990
*
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
@@ -28,14 +28,14 @@ obj dms {deg, min, sec};
define dms(deg, min, sec)
{
local obj dms ans; /* return value */
local obj dms ans; /* return value */
/* default missing args to 0 */
if (isnull(sec)) {
sec = 0;
sec = 0;
}
if (isnull(min)) {
min = 0;
min = 0;
}
/* load object */
@@ -51,30 +51,30 @@ define dms(deg, min, sec)
define dms_add(a, b)
{
local obj dms ans; /* return value */
local obj dms ans; /* return value */
/* initialize value to 1st arg */
if (istype(a, ans)) {
/* 1st arg is dms object, load it */
ans.deg = a.deg;
ans.min = a.min;
ans.sec = a.sec;
/* 1st arg is dms object, load it */
ans.deg = a.deg;
ans.min = a.min;
ans.sec = a.sec;
} else {
/* 1st arg is not dms, assume scalar degrees */
ans.deg = a;
ans.min = 0;
ans.sec = 0;
/* 1st arg is not dms, assume scalar degrees */
ans.deg = a;
ans.min = 0;
ans.sec = 0;
}
/* add value of 2nd arg */
if (istype(b, ans)) {
/* 2nd arg is dms object, add it */
ans.deg += b.deg;
ans.min += b.min;
ans.sec += b.sec;
/* 2nd arg is dms object, add it */
ans.deg += b.deg;
ans.min += b.min;
ans.sec += b.sec;
} else {
/* 2nd arg is not dms, add scalar degrees */
ans.deg += b;
/* 2nd arg is not dms, add scalar degrees */
ans.deg += b;
}
/* return normalized result */
@@ -85,19 +85,19 @@ define dms_add(a, b)
define dms_neg(a)
{
local obj dms ans; /* return value */
local obj dms ans; /* return value */
/* negate argument */
if (istype(a, ans)) {
/* 1st arg is dms object, load it */
ans.deg = -a.deg;
ans.min = -a.min;
ans.sec = -a.sec;
/* 1st arg is dms object, load it */
ans.deg = -a.deg;
ans.min = -a.min;
ans.sec = -a.sec;
} else {
/* 2nd arg is not dms, negate scalar degrees */
ans.deg = -a;
ans.min = 0;
ans.sec = 0;
/* 2nd arg is not dms, negate scalar degrees */
ans.deg = -a;
ans.min = 0;
ans.sec = 0;
}
/* return normalized result */
@@ -108,30 +108,30 @@ define dms_neg(a)
define dms_sub(a, b)
{
local obj dms ans; /* return value */
local obj dms ans; /* return value */
/* initialize value to 1st arg */
if (istype(a, ans)) {
/* 1st arg is dms object, load it */
ans.deg = a.deg;
ans.min = a.min;
ans.sec = a.sec;
/* 1st arg is dms object, load it */
ans.deg = a.deg;
ans.min = a.min;
ans.sec = a.sec;
} else {
/* 1st arg is not dms, assume scalar degrees */
ans.deg = a;
ans.min = 0;
ans.sec = 0;
/* 1st arg is not dms, assume scalar degrees */
ans.deg = a;
ans.min = 0;
ans.sec = 0;
}
/* subtract value of 2nd arg */
if (istype(b, ans)) {
/* 2nd arg is dms object, subtract it */
ans.deg -= b.deg;
ans.min -= b.min;
ans.sec -= b.sec;
/* 2nd arg is dms object, subtract it */
ans.deg -= b.deg;
ans.min -= b.min;
ans.sec -= b.sec;
} else {
/* 2nd arg is not dms, subtract scalar degrees */
ans.deg -= b;
/* 2nd arg is not dms, subtract scalar degrees */
ans.deg -= b;
}
/* return normalized result */
@@ -142,23 +142,23 @@ define dms_sub(a, b)
define dms_mul(a, b)
{
local obj dms ans; /* return value */
local obj dms ans; /* return value */
/* dms object multiplication */
if (istype(a, ans) && istype(b, ans)) {
ans.deg = dms_abs(a) * dms_abs(b);
ans.min = 0;
ans.sec = 0;
ans.deg = dms_abs(a) * dms_abs(b);
ans.min = 0;
ans.sec = 0;
/* scalar multiplication */
} else if (istype(a, ans)) {
ans.deg = a.deg * b;
ans.min = a.min * b;
ans.sec = a.sec * b;
ans.deg = a.deg * b;
ans.min = a.min * b;
ans.sec = a.sec * b;
} else {
ans.deg = b.deg * a;
ans.min = b.min * a;
ans.sec = b.sec * a;
ans.deg = b.deg * a;
ans.min = b.min * a;
ans.sec = b.sec * a;
}
/* return normalized result */
@@ -169,11 +169,11 @@ define dms_mul(a, b)
define dms_print(a)
{
local obj dms ans; /* temp object for dms type testing */
local obj dms ans; /* temp object for dms type testing */
/* firewall - arg must be a dms object */
if (! istype(a, ans)) {
quit "dms_print called with non dms object";
quit "dms_print called with non dms object";
}
/* print in dms form */
@@ -183,12 +183,12 @@ define dms_print(a)
define dms_abs(a)
{
local obj dms ans; /* temp object for dms type testing */
local deg; /* return scalar value */
local obj dms ans; /* temp object for dms type testing */
local deg; /* return scalar value */
/* firewall - just absolute value non dms objects */
if (! istype(a, ans)) {
return abs(a);
return abs(a);
}
/* compute degrees */
@@ -201,12 +201,12 @@ define dms_abs(a)
define dms_norm(a)
{
local obj dms ans; /* temp object for dms type testing */
local deg; /* degrees */
local obj dms ans; /* temp object for dms type testing */
local deg; /* degrees */
/* firewall - arg must be a dms object */
if (! istype(a, ans)) {
quit "dms_norm called with non dms object";
quit "dms_norm called with non dms object";
}
/* square degrees (norm is the square of absolute value */
@@ -219,18 +219,18 @@ define dms_norm(a)
define dms_test(a)
{
local obj dms ans; /* temp value */
local obj dms ans; /* temp value */
/* firewall - arg must be a dms object */
if (! istype(a, ans)) {
quit "dms_test called with non dms object";
quit "dms_test called with non dms object";
}
/* return false of non-zero */
ans = fixdms(a);
if (ans.deg == 0 && ans.min == 0 && ans.sec == 0) {
/* false */
return 0;
/* false */
return 0;
}
/* true */
return 1;
@@ -239,11 +239,11 @@ define dms_test(a)
define dms_int(a)
{
local obj dms ans; /* return value */
local obj dms ans; /* return value */
/* firewall - arg must be a dms object */
if (! istype(a, ans)) {
quit "dms_int called with non dms object";
quit "dms_int called with non dms object";
}
/* normalize the argument */
@@ -259,11 +259,11 @@ define dms_int(a)
define dms_frac(a)
{
local obj dms ans; /* return value */
local obj dms ans; /* return value */
/* firewall - arg must be a dms object */
if (! istype(a, ans)) {
quit "dms_frac called with non dms object";
quit "dms_frac called with non dms object";
}
/* normalize the argument */
@@ -281,7 +281,7 @@ define dms_frac(a)
define dms_rel(a,b)
{
local abs_a, abs_b; /* scalars of the arguments */
local abs_a, abs_b; /* scalars of the arguments */
/* compute scalars of the arguments */
abs_a = dms_abs(a);
@@ -294,7 +294,7 @@ define dms_rel(a,b)
define dms_cmp(a,b)
{
local abs_a, abs_b; /* scalars of the arguments */
local abs_a, abs_b; /* scalars of the arguments */
/* compute scalars of the arguments */
abs_a = dms_abs(a);
@@ -307,16 +307,16 @@ define dms_cmp(a,b)
define dms_inc(a)
{
local obj dms ans; /* return value */
local obj dms ans; /* return value */
/* increment a dms object */
if (istype(a, ans)) {
ans = a;
++ans.sec;
ans = a;
++ans.sec;
/* return normalized result */
ans = fixdms(ans);
return ans;
/* return normalized result */
ans = fixdms(ans);
return ans;
}
/* increment a scalar */
@@ -326,16 +326,16 @@ define dms_inc(a)
define dms_dec(a)
{
local obj dms ans; /* return value */
local obj dms ans; /* return value */
/* decrement a dms object */
if (istype(a, ans)) {
ans = a;
--ans.sec;
ans = a;
--ans.sec;
/* return normalized result */
ans = fixdms(ans);
return ans;
/* return normalized result */
ans = fixdms(ans);
return ans;
}
/* decrement a scalar */
@@ -345,11 +345,11 @@ define dms_dec(a)
define fixdms(a)
{
local obj dms ans; /* temp value */
local obj dms ans; /* temp value */
/* firewall */
if (! istype(a, ans)) {
quit "attempt to fix a non dms object";
quit "attempt to fix a non dms object";
}
/* use builtin d2dms function */

View File

@@ -4,22 +4,40 @@
* This file was created by Ernest Bowen <ebowen at une dot edu dot au>
* and modified by Landon Curt Noll.
*
* This dotest_code has been placed in the public domain. Please do not
* copyright this dotest_code.
*
* ERNEST BOWEN AND LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MER-
* CHANTABILITY AND FITNESS. IN NO EVENT SHALL LANDON CURT
* NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* This file is not covered under version 2.1 of the GNU LGPL.
* This file is covered under "The unlicense":
*
* Under source dotest_code control: 2006/03/08 05:54:09
* File existed as early as: 2006
* https://unlicense.org
*
* In particular:
*
* This is free and unencumbered software released into the public domain.
*
* Anyone is free to copy, modify, publish, use, compile, sell, or
* distribute this software, either in source code form or as a compiled
* binary, for any purpose, commercial or non-commercial, and by any
* means.
*
* In jurisdictions that recognize copyright laws, the author or authors
* of this software dedicate any and all copyright interest in the
* software to the public domain. We make this dedication for the benefit
* of the public at large and to the detriment of our heirs and
* successors. We intend this dedication to be an overt act of
* relinquishment in perpetuity of all present and future rights to this
* software under copyright law.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* For more information, please refer to <http://unlicense.org/>
*
* Under source dotest_code control: 2006/03/08 05:54:09
* File existed as early as: 2006
*/
@@ -27,29 +45,29 @@
* dotest - perform tests from dotest_testline file
*
* given:
* dotest_file filename containing single test lines
* dotest_code regress.cal test number to use (def: 0)
* dotest_maxcond max error conditions allowed (def: <0 ==> 2^31-1)
* dotest_file filename containing single test lines
* dotest_code regress.cal test number to use (def: 0)
* dotest_maxcond max error conditions allowed (def: <0 ==> 2^31-1)
*
* returns:
* number of line test failures
* number of line test failures
*
* NOTE: All variables used by the dotest() function start with "dotest_".
* The dotest_file and dotest_read should not use any variable
* that starts with "dotest_".
* The dotest_file and dotest_read should not use any variable
* that starts with "dotest_".
*/
define dotest(dotest_file, dotest_code = 0, dotest_maxcond = -1)
{
local dotest_f_file; /* open file containing test lines */
local dotest_testline; /* test line */
local dotest_testeval; /* eval value from dotest_testline test line */
local dotest_tmperrcnt; /* temp error count after line test */
local dotest_errcnt; /* total number of errors */
local dotest_failcnt; /* number of line tests failed */
local dotest_testnum; /* number of test lines evaluated */
local dotest_linenum; /* test line number */
local dotest_old_errmax; /* value of errmax() prior to calling */
local dotest_old_errcount; /* value of errcount() prior to calling */
local dotest_f_file; /* open file containing test lines */
local dotest_testline; /* test line */
local dotest_testeval; /* eval value from dotest_testline test line */
local dotest_tmperrcnt; /* temp error count after line test */
local dotest_errcnt; /* total number of errors */
local dotest_failcnt; /* number of line tests failed */
local dotest_testnum; /* number of test lines evaluated */
local dotest_linenum; /* test line number */
local dotest_old_errmax; /* value of errmax() prior to calling */
local dotest_old_errcount; /* value of errcount() prior to calling */
/*
* preserve calling stats
@@ -69,9 +87,9 @@ define dotest(dotest_file, dotest_code = 0, dotest_maxcond = -1)
* setup error accounting for dotest
*/
if (dotest_maxcond >= 0 && dotest_maxcond < 2147483647) {
errmax(dotest_maxcond + dotest_old_errcount + 1),;
errmax(dotest_maxcond + dotest_old_errcount + 1),;
} else {
errmax(2147483647),;
errmax(2147483647),;
}
/*
@@ -80,9 +98,9 @@ define dotest(dotest_file, dotest_code = 0, dotest_maxcond = -1)
printf("%d-: opening line file: %d", dotest_code, dotest_file);
dotest_f_file = fpathopen(dotest_file, "r");
if (!isfile(dotest_f_file)) {
printf("**** Unable to file or open file \"%s\"\n",
dotest_file);
quit;
printf("**** Unable to file or open file \"%s\"\n",
dotest_file);
quit;
}
printf('%d: testing "%s"\n', dotest_code, dotest_file);
@@ -91,73 +109,73 @@ define dotest(dotest_file, dotest_code = 0, dotest_maxcond = -1)
*/
for (;;) {
/* get the next test line */
dotest_testline = fgets(dotest_f_file);
++dotest_linenum;
if (iserror(dotest_testline)) {
quit "**** Error while reading file";
} else if (isnull(dotest_testline)) {
/* EOF - end of test file */
break;
}
/* get the next test line */
dotest_testline = fgets(dotest_f_file);
++dotest_linenum;
if (iserror(dotest_testline)) {
quit "**** Error while reading file";
} else if (isnull(dotest_testline)) {
/* EOF - end of test file */
break;
}
/* skip empty lines */
if (dotest_testline == "\n") {
continue;
}
/* skip empty lines */
if (dotest_testline == "\n") {
continue;
}
/* evaluate the test line */
dotest_testeval = eval(dotest_testline);
/* evaluate the test line */
dotest_testeval = eval(dotest_testline);
/* ignore white space or comment lines */
if (isnull(dotest_testeval)) {
continue;
}
/* ignore white space or comment lines */
if (isnull(dotest_testeval)) {
continue;
}
/* look for test line parse errors */
if (iserror(dotest_testeval)) {
printf("**** evaluation error: ");
++dotest_failcnt;
/* look for test line parse errors */
if (iserror(dotest_testeval)) {
printf("**** evaluation error: ");
++dotest_failcnt;
/* look for test line dotest_failcnt */
} else if (dotest_testeval != 1) {
printf("**** did not return 1: ");
++dotest_failcnt;
}
/* look for test line dotest_failcnt */
} else if (dotest_testeval != 1) {
printf("**** did not return 1: ");
++dotest_failcnt;
}
/* show the test line we just performed */
printf("%d-%d: %s", dotest_code, dotest_linenum, dotest_testline);
/* show the test line we just performed */
printf("%d-%d: %s", dotest_code, dotest_linenum, dotest_testline);
/* error accounting */
dotest_tmperrcnt = errcount() - dotest_errcnt;
if (dotest_tmperrcnt > 0) {
/* error accounting */
dotest_tmperrcnt = errcount() - dotest_errcnt;
if (dotest_tmperrcnt > 0) {
/* report any other errors */
if (dotest_tmperrcnt > 1) {
printf("%d-%d: NOTE: %d error conditions(s): %s\n",
dotest_code, dotest_linenum, dotest_tmperrcnt);
}
/* report any other errors */
if (dotest_tmperrcnt > 1) {
printf("%d-%d: NOTE: %d error conditions(s): %s\n",
dotest_code, dotest_linenum, dotest_tmperrcnt);
}
/* report the calc error string */
printf("%d-%d: NOTE: last error string: %s\n",
dotest_code, dotest_linenum, strerror());
/* report the calc error string */
printf("%d-%d: NOTE: last error string: %s\n",
dotest_code, dotest_linenum, strerror());
/* new error count level */
dotest_errcnt = errcount();
if (dotest_maxcond >= 0 &&
dotest_old_errcount-dotest_errcnt > dotest_maxcond) {
printf("%d-%d: total error conditions: %d > %d\n",
dotest_code, dotest_linenum,
dotest_maxcond, dotest_old_errcount-dotest_errcnt);
}
}
/* new error count level */
dotest_errcnt = errcount();
if (dotest_maxcond >= 0 &&
dotest_old_errcount-dotest_errcnt > dotest_maxcond) {
printf("%d-%d: total error conditions: %d > %d\n",
dotest_code, dotest_linenum,
dotest_maxcond, dotest_old_errcount-dotest_errcnt);
}
}
}
/*
* 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);
@@ -165,11 +183,11 @@ define dotest(dotest_file, dotest_code = 0, dotest_maxcond = -1)
* test line file accounting
*/
if (dotest_failcnt > 0) {
printf("**** %d-: %d test failure(s) in %d line(s)\n",
dotest_code, dotest_failcnt, dotest_linenum);
printf("**** %d-: %d test failure(s) in %d line(s)\n",
dotest_code, dotest_failcnt, dotest_linenum);
} else {
printf("%d-: no failure(s) in %d line(s)\n",
dotest_code, dotest_linenum);
printf("%d-: no failure(s) in %d line(s)\n",
dotest_code, dotest_linenum);
}
/*

View File

@@ -1,7 +1,7 @@
/*
* ellip - attempt to factor numbers using elliptic functions
*
* Copyright (C) 1999 David I. Bell
* Copyright (C) 1999,2023 David I. Bell
*
* Calc is open software; you can redistribute it and/or modify it under
* the terms of the version 2.1 of the GNU Lesser General Public License
@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,16 +17,16 @@
* 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: 1990/02/15 01:50:33
* File existed as early as: before 1990
* Under source code control: 1990/02/15 01:50:33
* File existed as early as: before 1990
*
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
/*
* Attempt to factor numbers using elliptic functions:
*
* y^2 = x^3 + a*x + b (mod ellip_N).
* y^2 = x^3 + a*x + b (mod ellip_N).
*
* Many points (x,y) (mod ellip_N) are found that solve the above equation,
* starting from a trivial solution and 'multiplying' that point together
@@ -47,13 +47,13 @@
* Theory and Cryptography" by Neal Koblitz for a good explanation.
*
* efactor(iN, ia, B, force)
* iN is the number to be factored.
* ia is the initial value of a in the equation, and each successive
* value of a is an independent attempt at factoring (default 1).
* B is the limit of the primes that make up the high power that the
* point is raised to for each factoring attempt (default 100).
* force is a flag to attempt to factor numbers even if they are
* thought to already be prime (default FALSE).
* iN is the number to be factored.
* ia is the initial value of a in the equation, and each successive
* value of a is an independent attempt at factoring (default 1).
* B is the limit of the primes that make up the high power that the
* point is raised to for each factoring attempt (default 100).
* force is a flag to attempt to factor numbers even if they are
* thought to already be prime (default false).
*
* Making B larger makes the power the point being raised to contain more
* prime factors, thus increasing the chance that the order of the point
@@ -77,114 +77,114 @@
* of the powers so far.
*
* If a factor is found, it is returned and is also saved in the global
* variable f. The number being factored is also saved in the global
* variable f. The number being factored is also saved in the global
* variable ellip_N.
*/
obj point {x, y};
global ellip_N; /* number to factor */
global ellip_a; /* first coefficient */
global ellip_b; /* second coefficient */
global ellip_f; /* found factor */
global ellip_N; /* number to factor */
global ellip_a; /* first coefficient */
global ellip_b; /* second coefficient */
global ellip_f; /* found factor */
define efactor(iN, ia, B, force)
{
local C, x, p;
local C, x, p;
if (!force && ptest(iN, 50))
return 1;
if (isnull(B))
B = 100;
if (isnull(ia))
ia = 1;
obj point x;
ellip_a = ia;
ellip_b = -ia;
ellip_N = iN;
C = isqrt(ellip_N);
C = 2 * C + 2 * isqrt(C) + 1;
ellip_f = 0;
while (ellip_f == 0) {
print "A =", ellip_a;
x.x = 1;
x.y = 1;
print 2, x;
x = x ^ (2 ^ (highbit(C) + 1));
for (p = 3; ((p < B) && (ellip_f == 0)); p += 2) {
if (!ptest(p, 1))
continue;
print p, x;
x = x ^ (p ^ ((highbit(C) // highbit(p)) + 1));
}
ellip_a++;
ellip_b--;
}
return ellip_f;
if (!force && ptest(iN, 50))
return 1;
if (isnull(B))
B = 100;
if (isnull(ia))
ia = 1;
obj point x;
ellip_a = ia;
ellip_b = -ia;
ellip_N = iN;
C = isqrt(ellip_N);
C = 2 * C + 2 * isqrt(C) + 1;
ellip_f = 0;
while (ellip_f == 0) {
print "A =", ellip_a;
x.x = 1;
x.y = 1;
print 2, x;
x = x ^ (2 ^ (highbit(C) + 1));
for (p = 3; ((p < B) && (ellip_f == 0)); p += 2) {
if (!ptest(p, 1))
continue;
print p, x;
x = x ^ (p ^ ((highbit(C) // highbit(p)) + 1));
}
ellip_a++;
ellip_b--;
}
return ellip_f;
}
define point_print(p)
{
print "(" : p.x : "," : p.y : ")" :;
print "(" : p.x : "," : p.y : ")" :;
}
define point_mul(p1, p2)
{
local r, m;
local r, m;
if (p2 == 1)
return p1;
if (p1 == p2)
return point_square(`p1);
obj point r;
m = (minv(p2.x - p1.x, ellip_N) * (p2.y - p1.y)) % ellip_N;
if (m == 0) {
if (ellip_f == 0)
ellip_f = gcd(p2.x - p1.x, ellip_N);
r.x = 1;
r.y = 1;
return r;
}
r.x = (m^2 - p1.x - p2.x) % ellip_N;
r.y = ((m * (p1.x - r.x)) - p1.y) % ellip_N;
return r;
if (p2 == 1)
return p1;
if (p1 == p2)
return point_square(`p1);
obj point r;
m = (minv(p2.x - p1.x, ellip_N) * (p2.y - p1.y)) % ellip_N;
if (m == 0) {
if (ellip_f == 0)
ellip_f = gcd(p2.x - p1.x, ellip_N);
r.x = 1;
r.y = 1;
return r;
}
r.x = (m^2 - p1.x - p2.x) % ellip_N;
r.y = ((m * (p1.x - r.x)) - p1.y) % ellip_N;
return r;
}
define point_square(p)
{
local r, m;
local r, m;
obj point r;
m = ((3 * p.x^2 + ellip_a) * minv(p.y << 1, ellip_N)) % ellip_N;
if (m == 0) {
if (ellip_f == 0)
ellip_f = gcd(p.y << 1, ellip_N);
r.x = 1;
r.y = 1;
return r;
}
r.x = (m^2 - p.x - p.x) % ellip_N;
r.y = ((m * (p.x - r.x)) - p.y) % ellip_N;
return r;
obj point r;
m = ((3 * p.x^2 + ellip_a) * minv(p.y << 1, ellip_N)) % ellip_N;
if (m == 0) {
if (ellip_f == 0)
ellip_f = gcd(p.y << 1, ellip_N);
r.x = 1;
r.y = 1;
return r;
}
r.x = (m^2 - p.x - p.x) % ellip_N;
r.y = ((m * (p.x - r.x)) - p.y) % ellip_N;
return r;
}
define point_pow(p, pow)
{
local bit, r, t;
local bit, r, t;
r = 1;
if (isodd(pow))
r = p;
t = p;
for (bit = 2; ((bit <= pow) && (ellip_f == 0)); bit <<= 1) {
t = point_square(`t);
if (bit & pow)
r = point_mul(`t, `r);
}
return r;
r = 1;
if (isodd(pow))
r = p;
t = p;
for (bit = 2; ((bit <= pow) && (ellip_f == 0)); bit <<= 1) {
t = point_square(`t);
if (bit & pow)
r = point_mul(`t, `r);
}
return r;
}

View File

@@ -17,8 +17,8 @@
* 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: 2013/08/11 01:31:28
* File existed as early as: 2013
* Under source code control: 2013/08/11 01:31:28
* File existed as early as: 2013
*/

View File

@@ -17,8 +17,8 @@
* 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: 2013/08/11 01:31:28
* File existed as early as: 2013
* Under source code control: 2013/08/11 01:31:28
* File existed as early as: 2013
*/
@@ -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;
@@ -168,34 +168,34 @@ define __CZ__add_factored_factorials(matrix_2n,matrix_n){
timings
this comb comb-this rel. k/n
this comb comb-this rel. k/n
; benchmark_binomial(10,13)
n=2^13 k=2^10 0.064004 0.016001 + 0.76923076923076923077
n=2^13 k=2^11 0.064004 0.048003 + 0.84615384615384615385
n=2^13 k=2^12 0.068004 0.124008 - 0.92307692307692307692
n=2^13 k=2^10 0.064004 0.016001 + 0.76923076923076923077
n=2^13 k=2^11 0.064004 0.048003 + 0.84615384615384615385
n=2^13 k=2^12 0.068004 0.124008 - 0.92307692307692307692
; benchmark_binomial(10,15)
n=2^15 k=2^10 0.216014 0.024001 + 0.66666666666666666667
n=2^15 k=2^11 0.220014 0.064004 + 0.73333333333333333333
n=2^15 k=2^12 0.228014 0.212014 + 0.8
n=2^15 k=2^13 0.216013 0.664042 - 0.86666666666666666667
n=2^15 k=2^14 0.240015 1.868117 - 0.93333333333333333333
n=2^15 k=2^10 0.216014 0.024001 + 0.66666666666666666667
n=2^15 k=2^11 0.220014 0.064004 + 0.73333333333333333333
n=2^15 k=2^12 0.228014 0.212014 + 0.8
n=2^15 k=2^13 0.216013 0.664042 - 0.86666666666666666667
n=2^15 k=2^14 0.240015 1.868117 - 0.93333333333333333333
; benchmark_binomial(11,15)
n=2^15 k=2^11 0.216014 0.068004 + 0.73333333333333333333
n=2^15 k=2^12 0.236015 0.212013 + 0.8
n=2^15 k=2^13 0.216013 0.656041 - 0.86666666666666666667
n=2^15 k=2^14 0.244016 1.872117 - 0.93333333333333333333
n=2^15 k=2^11 0.216014 0.068004 + 0.73333333333333333333
n=2^15 k=2^12 0.236015 0.212013 + 0.8
n=2^15 k=2^13 0.216013 0.656041 - 0.86666666666666666667
n=2^15 k=2^14 0.244016 1.872117 - 0.93333333333333333333
; benchmark_binomial(11,18)
n=2^18 k=2^11 1.652103 0.100006 + 0.61111111111111111111
n=2^18 k=2^12 1.608101 0.336021 + 0.66666666666666666667
n=2^18 k=2^13 1.700106 1.140071 + 0.72222222222222222222
n=2^18 k=2^14 1.756109 3.924245 - 0.77777777777777777778
n=2^18 k=2^15 2.036127 13.156822 - 0.83333333333333333333
n=2^18 k=2^16 2.172135 41.974624 - 0.88888888888888888889
n=2^18 k=2^17 2.528158 121.523594 - 0.94444444444444444444
n=2^18 k=2^11 1.652103 0.100006 + 0.61111111111111111111
n=2^18 k=2^12 1.608101 0.336021 + 0.66666666666666666667
n=2^18 k=2^13 1.700106 1.140071 + 0.72222222222222222222
n=2^18 k=2^14 1.756109 3.924245 - 0.77777777777777777778
n=2^18 k=2^15 2.036127 13.156822 - 0.83333333333333333333
n=2^18 k=2^16 2.172135 41.974624 - 0.88888888888888888889
n=2^18 k=2^17 2.528158 121.523594 - 0.94444444444444444444
; benchmark_binomial(15,25)
n=2^25 k=2^15 303.790985 38.266392 + 0.6
n=2^25 k=2^15 303.790985 38.266392 + 0.6
; benchmark_binomial(17,25)
n=2^25 k=2^17 319.127944 529.025062 - 0.68
n=2^25 k=2^17 319.127944 529.025062 - 0.68
*/
define benchmark_binomial(s,limit){
@@ -207,7 +207,7 @@ define benchmark_binomial(s,limit){
T1 = end-start;
start=usertime();B=comb(N,K);end=usertime();
T2 = end-start;
print "n=2^"limit,"k=2^"k," ",T1," ",T2,T1<T2?"-":"+"," "k/limit;
print "n=2^"limit,"k=2^"k," ",T1," ",T2,T1<T2?"-":"+"," "k/limit;
if(A!=B){
print "false";
break;
@@ -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;
@@ -328,7 +328,7 @@ define binomial(n,k){
do {
prime_list[K ,0] = prime;
diff = __CZ__prime_divisors(n,prime)-
( __CZ__prime_divisors(n-k,prime)+__CZ__prime_divisors(k,prime));
( __CZ__prime_divisors(n-k,prime)+__CZ__prime_divisors(k,prime));
if(diff != 0)
prime_list[K++,1] = diff;
prime = nextprime(prime);
@@ -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;
}

473
cal/fnv_tool.cal Normal file
View File

@@ -0,0 +1,473 @@
/*
* fnv_util - utility tools for FNV hash and "FNV-style" hash operations
*
* This file provides the following functions:
*
* find_fnv_prime(bits)
* deprecated_fnv0(bits, fnv_prime, string)
* fnv_offset_basis(bits, fnv_prime)
* fnv1a_style_hash(bits, fnv_prime, prev_hash, string)
*
* See the individual function for details on args and return value.
*
* If no args are given to find_fnv_prime() and stdin is associated
* with a tty (i.e., an interactive terminal), then bits will be
* prompted for and commentary will be printed to stdout as well.
*
* If fnv_prime == null(), then an attempt to compute the FNV prime
* for a hash if size bits is attempted..
*
* If prev_hash == null(), then the FNV offset basis for
* for a hash if size bits is computed.
*
* For more information on the FNV hash see:
*
* https://en.wikipedia.org/wiki/Fowler-Noll-Vo_hash_function
* http://www.isthe.com/chongo/tech/comp/fnv/index.html
*
* IMPORTANT NOTE:
*
* These functions, if given non-standard values, will produce bogus results.
* In some cases, such as specifying the number of bits in the hash,
* using a non-power of 2 bit will produce a result that may work,
* but the hash will be only an "FNV-style" hash and not a true FNV hash.
*
* We say "FNV-style" because the result hash is not a "true FNV-like" hash.
*
* Let integer n > 0 be the number if bits in the FNV hash. Then:
*
* t = floor((5+n)/12)
*
* The FNV prime, for the given n bits is the smallest prime of the form:
*
* p = 256^t + 2^8 + b
*
* such that:
*
* 0 < b < 2^8
* The number of one-bits in b must be 4 or 5
* p mod (2^40 - 2^24 - 1) > (2^24 + 2^8 + 2^7)
*
* If you force n to not be a power of 2, for example:
*
* n = 44
*
* you will find that the FNV prime for 44 bits is:
*
* p44 = 4294967597
* = 0x10000012d
* = 0b100000000000000000000000100101101
* = 2^32 + 301 = 2^32 + 2^8 + 2^5 + 2^3 + 2^2 + 2^0
*
* However a hash size of 44 bits is not a true FNV hash, it is only a "FNV-style" hash.
*
* NOTE: We disallow n <= 31 because there are no FNV primes that small.
*
* NOTE: For n that is a power of 2 and n > 1024, you will find that
* that FNV primes become so rare that that one may not find a suitable
* FNV prime. For n = powers of 2 >= 2048 and <= 1048576,
* there is NO FNV primes.
*
* As for as hashing goes, large values of n, even if an
* FNV hash may be found, are unlikely to be truly useful. :-)
*/
/*
* Copyright (c) 2023 by Landon Curt Noll. All Rights Reserved.
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright, this permission notice and text
* this comment, and the disclaimer below appear in all of the following:
*
* supporting documentation
* source copies
* source works derived from this source
* binaries derived from this source or from derived source
*
* LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
* EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* chongo (Landon Curt Noll, http://www.isthe.com/chongo/index.html) /\oo/\
*
* Share and enjoy! :-)
*/
/*
* find_fnv_prime - try to find a FNV prime given the number of bits
*
* If bits == null(), this function will attempt to prompt stdin
* for a value and provide commends on the value of bits.
*
* given:
* bits number of bits in the hash, null() ==> prompt for value
*
* returns:
* 0 ==> no FNV prime found
* >0 ==> FNV prime
*/
define find_fnv_prime(bits)
{
local b; /* lower octet of the potential FNV prime: [1,255] */
local p; /* value to test as an FNV prime */
local t; /* power of 256 part of the FNV prime */
local one_bits; /* number of 1 bits in b */
local p_minus_b; /* potential FNV prime less b */
local interactive; /* true ==> interactive mode and print commentary */
/*
* case: no arg, prompt for bits and print commentary
*/
interactive = 0; /* assume non-interactive mode */
if (isnull(bits)) {
/*
* must be attached to an interactive terminal
*/
if (!isatty(files(0))) {
print "# FATAL: stdin is not a tty: not attached to an interactive terminal";
return 0;
}
interactive = 1; /* set interactive mode */
/*
* prompt for the number of bits
*/
do {
local strscanf_ret; /* return from strscanf_ret */
local input; /* value read after prompt */
/*
* prompt and obtain the input
*/
input = prompt("Enter hash size in bits: ");
strscanf_ret = strscanf(input, "%i", bits);
print "input =", input;
print "bits =", bits;
if (!isint(bits) || bits <= 0) {
print;
print "# NOTE: must enter a integer > 0, try again";
print;
}
} while (!isint(bits) || bits <= 0);
}
/*
* firewall - bits must be non-negative integer
*/
if (!isint(bits) || bits < 0) {
if (interactive) {
print "# FATAL: bits must be non-negative integer";
}
return 0;
}
/*
* provide commentary on the choice of bits if we are interactive
*/
if (interactive) {
if (popcnt(bits) == 1) {
if (bits > 1024) {
print "# WARNING: FNV primes for bit size powers of 2 > 1024 are extremely rare.";
print "# WARNING: There are no FNV primes for bit size powers of 2 >= 2048 and <= 1048576.";
}
print "n =", bits;
} else {
if (bits < 32) {
print "# WARNING: bits < 32 is not recommended because there isn't enough bits to be worth hashing";
}
print "# WARNING: because bits is not a power of 2, we can only form an \"FNV-style hash\": not a true FNV hash.";
print "# WARNING: A \"FNV-style hash\" may not have the desired hash properties of a true FNV hash.";
print "n =", bits;
}
}
/*
* search setup
*/
t = floor((5+bits)/12);
p_minus_b = 256^t + 2^8;
/*
* search for a b that forms a suitable FNV prime
*/
for (b=1; b < 256; ++b) {
/*
* reject b unless the of one-bits in bottom octet of p is 4 or 5
*/
one_bits = popcnt(b);
if (one_bits != 4 && one_bits != 5) {
continue;
}
/*
* reject p if p mod (2^40 - 2^24 - 1) <= (2^24 + 2^8 + 2^7)
*/
p = p_minus_b + b;
if ((p % (2^40 - 2^24 - 1)) <= (2^24 + 2^8 + 2^7)) {
continue;
}
/*
* accept potential p value that is prime
*/
if (ptest(p) == 1) {
return p;
}
}
/*
* case: did not find an FNV prime
*/
if (b >= 256) {
/*
* examine results if interactive
*/
if (interactive) {
print "# FATAL: There is no a suitable FNV prime for bits =", bits;
quit "find_fnv_prime: FATAL: FNV prime search failed";
}
/*
* return 0 to indicate no FNV prime found
*/
return 0;
}
/*
* provide FNV commentary if interactive
*/
if (interactive) {
print "t =", t;
print "b =", b;
print "# NOTE: p = 256^":t, "+ 2^8 +", b;
print;
print "p =", p;
}
/*
* return FNV prime
*/
return p;
}
/*
* deprecated_fnv0 - FNV-0 hash that should only be used to generate an FNV offset basis
*
* If fnv_prime == null(), this function will try to compute the FNV prime
* for a hash of size bits.
*
* given:
* bits number of bits in FNV hash
* fnv_prime FNV prime, null() ==> generate suitable FNV prime if possible
* string string to hash
*
* returns:
* FNV-0 hash, for size bytes, of string
*
* NOTE: This function does NOT attempt to determine that fnv_prime is prime.
*/
define deprecated_fnv0(bits, fnv_prime, string)
{
local hash; /* FNV hash value */
local len; /* length of string */
local base; /* base of FNV hash: 2^bits */
local i;
/*
* firewall
*/
if (!isint(bits) || bits <= 0) {
quit "deprecated_fnv0: FATAL: bits arg must be an integer > 0";
}
if (!isstr(string)) {
quit "deprecated_fnv0: FATAL: string arg must be a string";
}
/*
* fnv_prime == null() means to try and generate the FNV prime
*/
if (isnull(fnv_prime)) {
/* try to generate an FNV prime */
fnv_prime = find_fnv_prime(bits);
if (fnv_prime == 0) {
quit "deprecated_fnv0: FATAL: no FNV prime exists for the given hash size in bits";
}
}
if (!isint(fnv_prime) || fnv_prime <= 0) {
quit "deprecated_fnv0: FATAL: fnv_prime arg must be an integer > 0 and should be prime";
}
/*
* FNV-0 hash each character
*/
len = strlen(string);
base = 2^bits;
hash = 0;
for (i=0; i < len; ++i) {
hash = xor((hash * fnv_prime) % base, ord(string[i]));
}
return hash;
}
/*
* fnv_offset_basis - generate and FNV offset basis
*
* given:
* bits number of bits in FNV hash
* fnv_prime FNV prime, null() ==> generate suitable FNV prime if possible
*
* returns:
* FNV offset basis for a hash size of bits and an FNV prime of fnv_prime
*
* NOTE: This function does NOT attempt to determine that fnv_prime is prime.
*/
define
fnv_offset_basis(bits, fnv_prime)
{
local fnv0_hash = 0; /* FNV-0 hash value */
/* string to generate a FNV offset basis - do not change this value */
static chongo_was_here = "chongo <Landon Curt Noll> /\\../\\";
/*
* firewall
*/
if (!isint(bits) || bits <= 0) {
quit "fnv_offset_basis: FATAL: bits arg must be an integer > 0";
}
/*
* fnv_prime == null() means to try and generate the FNV prime
*/
if (isnull(fnv_prime)) {
/* try to generate an FNV prime */
fnv_prime = find_fnv_prime(bits);
if (fnv_prime == 0) {
quit "fnv_offset_basis: FATAL: no FNV prime exists for the given hash size in bits";
}
}
if (!isint(fnv_prime) || fnv_prime <= 0) {
quit "fnv_offset_basis: FATAL: fnv_prime arg must be an integer > 0 and should be prime";
}
/*
* return the FNV-0 hash of fnv_offset_basis as the FNV offset basis
*/
fnv0_hash = deprecated_fnv0(bits, fnv_prime, chongo_was_here);
return fnv0_hash;
}
/*
* fnv_style_hash - compute an "FNV-1a-style" hash
*
* These functions, if given non-standard values, will produce bogus results.
* To produce a true FNV-1a hash:
*
* bits must be a power of 2
* 32 <= bits
* fnv_prime == find_fnv_prime(bits) OR fnv_prime == null()
* prev_hash == previous FNV hash OR prev_hash == null()
*
* If fnv_prime == null(), this function will try to compute the FNV prime
* for a hash of size bits.
*
* If prev_hash == null(), this function will try to compute the FNV offset basis
* for a hash of size bits.
*
* One may chain "FNV-style" hashes by replacing the offset_basis with
* the hash state of the previous hash. For the first hash:
*
* fnv_prime = find_fnv_prime(bits)
* hash_val = fnv_style_hash(bits, fnv_prime, null(), string_a);
*
* then:
*
* hash_val = fnv_style_hash(bits, fnv_prime, hash_val, string_b);
*
* This will produce the same as the string_a concatenated with string_b:
*
* hash_val = fnv_style_hash(bits, null(), null(), string_a + string_b);
*
* NOTE: Because string_a and string_b are strings, the expression:
*
* string_a + string_b
*
* is string_a concatenated with string_b.
*
* given:
* bits number of bits in FNV hash
* fnv_prime FNV prime, null() ==> generate suitable FNV prime if possible
* prev_hash previous hash value, null() ==> generate FNV offset basis
* string string to hash
*
* returns:
* "FNV-style" hash of bits
*
* NOTE: This function does NOT attempt to determine that fnv_prime is prime.
*/
define
fnv1a_style_hash(bits, fnv_prime, prev_hash, string)
{
local hash = 0; /* FNV hash value */
local len; /* length of string */
local base; /* base of FNV hash: 2^bits */
local i;
/*
* firewall
*/
if (!isint(bits) || bits <= 0) {
quit "fnv1a_style_hash: FATAL: bits arg must be an integer > 0";
}
if (!isstr(string)) {
quit "fnv1a_style_hash: FATAL: string arg must be a string";
}
/*
* fnv_prime == null() means to try and generate the FNV prime
*/
if (isnull(fnv_prime)) {
/* try to generate an FNV prime */
fnv_prime = find_fnv_prime(bits);
if (fnv_prime == 0) {
quit "fnv1a_style_hash: FATAL: no FNV prime exists for the given hash size in bits";
}
}
if (!isint(fnv_prime) || fnv_prime <= 0) {
quit "fnv1a_style_hash: FATAL: fnv_prime arg must be an integer > 0 and should be prime";
}
/*
* prev_hash == null() means to generate the FNV offset basis
*/
if (isnull(prev_hash)) {
/* generate the FNV offset basis for a hash of size bits */
prev_hash = fnv_offset_basis(bits, fnv_prime);
}
if (!isint(prev_hash) || prev_hash < 0) {
quit "fnv1a_style_hash: FATAL: prev_hash arg must be an integer => 0";
}
/*
* FNV-1a hash each character
*/
len = strlen(string);
base = 2^bits;
hash = prev_hash;
for (i=0; i < len; ++i) {
hash = xor((hash * fnv_prime) % base, ord(string[i]));
}
return hash;
}

View File

@@ -17,37 +17,37 @@
define gvec(function, vector)
{
local xlen,y,foo;
local precx = 1e-50; /* default for now */
local precx = 1e-50; /* default for now */
local argc = param(0)-1;
local old_tilde; /* previous config("tilde") */
local old_tilde; /* previous config("tilde") */
/*
* parse args
*/
local plist = mat[argc];
if (config("resource_debug") & 8) {
print "plist=", plist;
print "argc=", argc;
print "plist=", plist;
print "argc=", argc;
}
for(local i = 0; i< argc; i++) {
local ii = i + 2;
if (config("resource_debug") & 8) {
print "ii=", ii;
print "param(" : ii : "}=", param(ii);
print "size(param(" : ii : ")=", size(param(ii));
}
plist[i] = size(param(ii));
local ii = i + 2;
if (config("resource_debug") & 8) {
print "ii=", ii;
print "param(" : ii : "}=", param(ii);
print "size(param(" : ii : ")=", size(param(ii));
}
plist[i] = size(param(ii));
}
local slist=sort(plist);
if (config("resource_debug") & 8) {
print "plist=", plist;
print "plist=", plist;
}
local argm = argc-1;
if (config("resource_debug") & 8) {
print "argm=", argm;
print "argm=", argm;
}
if (slist[0] != slist[argm]) {
quit "lengths don't match";
quit "lengths don't match";
}
xlen = size(vector);
y = mat[xlen];
@@ -67,32 +67,32 @@ define gvec(function, vector)
*/
if (isdefined(function)) {
/* yep, it's a function, either builtin or user-defined */
for (local j=0; j<xlen; j++) {
/* yep, it's a function, either builtin or user-defined */
for (local j=0; j<xlen; j++) {
/* build the function call */
foo = strcat(function, "(");
for (local jj = 0; jj<argc; jj++) {
foo = strcat(foo , str(param(jj+2)[j]), ",");
}
foo = strcat(foo, str(precx), ")");
if (config("resource_debug") & 8) {
print "foo=", foo;
}
y[j] = eval(foo);
}
/* build the function call */
foo = strcat(function, "(");
for (local jj = 0; jj<argc; jj++) {
foo = strcat(foo , str(param(jj+2)[j]), ",");
}
foo = strcat(foo, str(precx), ")");
if (config("resource_debug") & 8) {
print "foo=", foo;
}
y[j] = eval(foo);
}
/*
* it is an operator -- multi-argument operator makes no sense
*/
} else {
if (argc > 1) {
quit "Error: operator can accept only one argument";
}
for (j=0; j<xlen; j++) {
foo = strcat(str(vector[j]), function);
y[j] = eval(foo);
}
if (argc > 1) {
quit "Error: operator can accept only one argument";
}
for (j=0; j<xlen; j++) {
foo = strcat(str(vector[j]), function);
y[j] = eval(foo);
}
}
/* restore tilde mode if needed */

View File

@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,11 +17,11 @@
* 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: 1996/11/13 13:25:43
* File existed as early as: 1996
* Under source code control: 1996/11/13 13:25:43
* File existed as early as: 1996
*
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
/*

View File

@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,10 +17,10 @@
* 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: 2010/09/01 17:14:55
* File existed as early as: 2010
* Under source code control: 2010/09/01 17:14:55
* File existed as early as: 2010
*
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
@@ -28,14 +28,14 @@ obj hms {hour, min, sec};
define hms(hour, min, sec)
{
local obj hms ans; /* return value */
local obj hms ans; /* return value */
/* default missing args to 0 */
if (isnull(sec)) {
sec = 0;
sec = 0;
}
if (isnull(min)) {
min = 0;
min = 0;
}
/* load object */
@@ -51,30 +51,30 @@ define hms(hour, min, sec)
define hms_add(a, b)
{
local obj hms ans; /* return value */
local obj hms ans; /* return value */
/* initialize value to 1st arg */
if (istype(a, ans)) {
/* 1st arg is hms object, load it */
ans.hour = a.hour;
ans.min = a.min;
ans.sec = a.sec;
/* 1st arg is hms object, load it */
ans.hour = a.hour;
ans.min = a.min;
ans.sec = a.sec;
} else {
/* 1st arg is not hms, assume scalar hours */
ans.hour = a;
ans.min = 0;
ans.sec = 0;
/* 1st arg is not hms, assume scalar hours */
ans.hour = a;
ans.min = 0;
ans.sec = 0;
}
/* add value of 2nd arg */
if (istype(b, ans)) {
/* 2nd arg is hms object, add it */
ans.hour += b.hour;
ans.min += b.min;
ans.sec += b.sec;
/* 2nd arg is hms object, add it */
ans.hour += b.hour;
ans.min += b.min;
ans.sec += b.sec;
} else {
/* 2nd arg is not hms, add scalar hours */
ans.hour += b;
/* 2nd arg is not hms, add scalar hours */
ans.hour += b;
}
/* return normalized result */
@@ -85,19 +85,19 @@ define hms_add(a, b)
define hms_neg(a)
{
local obj hms ans; /* return value */
local obj hms ans; /* return value */
/* negate argument */
if (istype(a, ans)) {
/* 1st arg is hms object, load it */
ans.hour = -a.hour;
ans.min = -a.min;
ans.sec = -a.sec;
/* 1st arg is hms object, load it */
ans.hour = -a.hour;
ans.min = -a.min;
ans.sec = -a.sec;
} else {
/* 2nd arg is not hms, negate scalar hours */
ans.hour = -a;
ans.min = 0;
ans.sec = 0;
/* 2nd arg is not hms, negate scalar hours */
ans.hour = -a;
ans.min = 0;
ans.sec = 0;
}
/* return normalized result */
@@ -108,30 +108,30 @@ define hms_neg(a)
define hms_sub(a, b)
{
local obj hms ans; /* return value */
local obj hms ans; /* return value */
/* initialize value to 1st arg */
if (istype(a, ans)) {
/* 1st arg is hms object, load it */
ans.hour = a.hour;
ans.min = a.min;
ans.sec = a.sec;
/* 1st arg is hms object, load it */
ans.hour = a.hour;
ans.min = a.min;
ans.sec = a.sec;
} else {
/* 1st arg is not hms, assume scalar hours */
ans.hour = a;
ans.min = 0;
ans.sec = 0;
/* 1st arg is not hms, assume scalar hours */
ans.hour = a;
ans.min = 0;
ans.sec = 0;
}
/* subtract value of 2nd arg */
if (istype(b, ans)) {
/* 2nd arg is hms object, subtract it */
ans.hour -= b.hour;
ans.min -= b.min;
ans.sec -= b.sec;
/* 2nd arg is hms object, subtract it */
ans.hour -= b.hour;
ans.min -= b.min;
ans.sec -= b.sec;
} else {
/* 2nd arg is not hms, subtract scalar hours */
ans.hour -= b;
/* 2nd arg is not hms, subtract scalar hours */
ans.hour -= b;
}
/* return normalized result */
@@ -142,23 +142,23 @@ define hms_sub(a, b)
define hms_mul(a, b)
{
local obj hms ans; /* return value */
local obj hms ans; /* return value */
/* hms object multiplication */
if (istype(a, ans) && istype(b, ans)) {
ans.hour = hms_abs(a) * hms_abs(b);
ans.min = 0;
ans.sec = 0;
ans.hour = hms_abs(a) * hms_abs(b);
ans.min = 0;
ans.sec = 0;
/* scalar multiplication */
} else if (istype(a, ans)) {
ans.hour = a.hour * b;
ans.min = a.min * b;
ans.sec = a.sec * b;
ans.hour = a.hour * b;
ans.min = a.min * b;
ans.sec = a.sec * b;
} else {
ans.hour = b.hour * a;
ans.min = b.min * a;
ans.sec = b.sec * a;
ans.hour = b.hour * a;
ans.min = b.min * a;
ans.sec = b.sec * a;
}
/* return normalized result */
@@ -169,11 +169,11 @@ define hms_mul(a, b)
define hms_print(a)
{
local obj hms ans; /* temp object for hms type testing */
local obj hms ans; /* temp object for hms type testing */
/* firewall - arg must be a hms object */
if (! istype(a, ans)) {
quit "hms_print called with non hms object";
quit "hms_print called with non hms object";
}
/* print in hms form */
@@ -183,12 +183,12 @@ define hms_print(a)
define hms_abs(a)
{
local obj hms ans; /* temp object for hms type testing */
local hour; /* return scalar value */
local obj hms ans; /* temp object for hms type testing */
local hour; /* return scalar value */
/* firewall - just absolute value non hms objects */
if (! istype(a, ans)) {
return abs(a);
return abs(a);
}
/* compute hours */
@@ -201,12 +201,12 @@ define hms_abs(a)
define hms_norm(a)
{
local obj hms ans; /* temp object for hms type testing */
local hour; /* hours */
local obj hms ans; /* temp object for hms type testing */
local hour; /* hours */
/* firewall - arg must be a hms object */
if (! istype(a, ans)) {
quit "hms_norm called with non hms object";
quit "hms_norm called with non hms object";
}
/* square hours (norm is the square of absolute value */
@@ -219,18 +219,18 @@ define hms_norm(a)
define hms_test(a)
{
local obj hms ans; /* temp value */
local obj hms ans; /* temp value */
/* firewall - arg must be a hms object */
if (! istype(a, ans)) {
quit "hms_test called with non hms object";
quit "hms_test called with non hms object";
}
/* return false of non-zero */
ans = fixhms(a);
if (ans.hour == 0 && ans.min == 0 && ans.sec == 0) {
/* false */
return 0;
/* false */
return 0;
}
/* true */
return 1;
@@ -239,11 +239,11 @@ define hms_test(a)
define hms_int(a)
{
local obj hms ans; /* return value */
local obj hms ans; /* return value */
/* firewall - arg must be a hms object */
if (! istype(a, ans)) {
quit "hms_int called with non hms object";
quit "hms_int called with non hms object";
}
/* normalize the argument */
@@ -259,11 +259,11 @@ define hms_int(a)
define hms_frac(a)
{
local obj hms ans; /* return value */
local obj hms ans; /* return value */
/* firewall - arg must be a hms object */
if (! istype(a, ans)) {
quit "hms_frac called with non hms object";
quit "hms_frac called with non hms object";
}
/* normalize the argument */
@@ -281,7 +281,7 @@ define hms_frac(a)
define hms_rel(a,b)
{
local abs_a, abs_b; /* scalars of the arguments */
local abs_a, abs_b; /* scalars of the arguments */
/* compute scalars of the arguments */
abs_a = hms_abs(a);
@@ -294,7 +294,7 @@ define hms_rel(a,b)
define hms_cmp(a,b)
{
local abs_a, abs_b; /* scalars of the arguments */
local abs_a, abs_b; /* scalars of the arguments */
/* compute scalars of the arguments */
abs_a = hms_abs(a);
@@ -307,16 +307,16 @@ define hms_cmp(a,b)
define hms_inc(a)
{
local obj hms ans; /* return value */
local obj hms ans; /* return value */
/* increment a hms object */
if (istype(a, ans)) {
ans = a;
++ans.sec;
ans = a;
++ans.sec;
/* return normalized result */
ans = fixhms(ans);
return ans;
/* return normalized result */
ans = fixhms(ans);
return ans;
}
/* increment a scalar */
@@ -326,16 +326,16 @@ define hms_inc(a)
define hms_dec(a)
{
local obj hms ans; /* return value */
local obj hms ans; /* return value */
/* decrement a hms object */
if (istype(a, ans)) {
ans = a;
--ans.sec;
ans = a;
--ans.sec;
/* return normalized result */
ans = fixhms(ans);
return ans;
/* return normalized result */
ans = fixhms(ans);
return ans;
}
/* decrement a scalar */
@@ -345,11 +345,11 @@ define hms_dec(a)
define fixhms(a)
{
local obj hms ans; /* temp value */
local obj hms ans; /* temp value */
/* firewall */
if (! istype(a, ans)) {
quit "attempt to fix a non hms object";
quit "attempt to fix a non hms object";
}
/* use builtin h2hms function */

View File

@@ -26,9 +26,9 @@ resource_debug_level = config("resource_debug", 0);
define isinfinite(x)
{
if (isstr(x)) {
if (strncmp(x, "cinf", 4) == 0
|| strncmp(x, "pinf", 4) == 0 || strncmp(x, "ninf", 4) == 0)
return 1;
if (strncmp(x, "cinf", 4) == 0
|| strncmp(x, "pinf", 4) == 0 || strncmp(x, "ninf", 4) == 0)
return 1;
}
return 0;
}
@@ -36,8 +36,8 @@ define isinfinite(x)
define iscinf(x)
{
if (isstr(x)) {
if (strncmp(x, "cinf", 4) == 0)
return 1;
if (strncmp(x, "cinf", 4) == 0)
return 1;
}
return 0;
}
@@ -45,8 +45,8 @@ define iscinf(x)
define ispinf(x)
{
if (isstr(x)) {
if (strncmp(x, "pinf", 4) == 0)
return 1;
if (strncmp(x, "pinf", 4) == 0)
return 1;
}
return 0;
}
@@ -54,8 +54,8 @@ define ispinf(x)
define isninf(x)
{
if (isstr(x)) {
if (strncmp(x, "ninf", 4) == 0)
return 1;
if (strncmp(x, "ninf", 4) == 0)
return 1;
}
return 0;
}

View File

@@ -27,9 +27,9 @@
/*
* NOTE: Because leading HALF values are trimmed from integer, a file
* that begins with lots of 0 bits (in the case of big Endian)
* or that ends with lots of 0 bits (in the case of little Endian)
* will be changed when the subsequent integer is written back.
* that begins with lots of 0 bits (in the case of big Endian)
* or that ends with lots of 0 bits (in the case of little Endian)
* will be changed when the subsequent integer is written back.
*/
@@ -37,16 +37,16 @@
* file2be - convert a file into an big Endian integer
*
* given:
* filename filename to read
* filename filename to read
*
* returns:
* integer read from its contents on big Endian order
* integer read from its contents on big Endian order
*/
define file2be(filename)
{
local fd; /* open file */
local ret; /* integer to return */
local c; /* character read from the file */
local fd; /* open file */
local ret; /* integer to return */
local c; /* character read from the file */
local i;
/*
@@ -62,8 +62,8 @@ define file2be(filename)
*/
ret = 0;
while (! isnull(c = fgetc(fd))) {
ret <<= 8;
ret += ord(c);
ret <<= 8;
ret += ord(c);
}
/*
@@ -78,17 +78,17 @@ define file2be(filename)
* file2le - convert a file into an little Endian integer
*
* given:
* filename filename to read
* filename filename to read
*
* returns:
* integer read from its contents on little Endian order
* integer read from its contents on little Endian order
*/
define file2le(filename)
{
local fd; /* open file */
local ret; /* integer to return */
local c; /* character read from the file */
local shft; /* bit shift for the c value */
local fd; /* open file */
local ret; /* integer to return */
local c; /* character read from the file */
local shft; /* bit shift for the c value */
local i;
/*
@@ -105,8 +105,8 @@ define file2le(filename)
ret = 0;
shft = 0;
while (! isnull(c = fgetc(fd))) {
ret |= (ord(c) << shft);
shft += 8;
ret |= (ord(c) << shft);
shft += 8;
}
/*
@@ -121,25 +121,25 @@ define file2le(filename)
* be2file - convert a big Endian integer into a file
*
* given:
* v integer to write to the file
* filename filename to write
* v integer to write to the file
* filename filename to write
*
* returns:
* The number of octets written to the file.
* The number of octets written to the file.
*
* NOTE: The absolute value of the integer is written to the file.
*/
define be2file(v, filename)
{
local fd; /* open file */
local octlen; /* length of v in octets */
local fd; /* open file */
local octlen; /* length of v in octets */
local i;
/*
* firewall
*/
if (!isint(v)) {
quit "be2file: 1st arg not an integer";
quit "be2file: 1st arg not an integer";
}
v = abs(v);
@@ -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)));
}
/*
@@ -171,24 +171,24 @@ define be2file(v, filename)
* le2file - convert a little Endian integer into a file
*
* given:
* v integer to write to the file
* filename filename to write
* v integer to write to the file
* filename filename to write
*
* returns:
* The number of octets written to the file.
* The number of octets written to the file.
*
* NOTE: The absolute value of the integer is written to the file.
*/
define le2file(v, filename)
{
local fd; /* open file */
local cnt; /* octets written */
local fd; /* open file */
local cnt; /* octets written */
/*
* firewall
*/
if (!isint(v)) {
quit "be2file: 1st arg not an integer";
quit "be2file: 1st arg not an integer";
}
v = abs(v);
@@ -205,9 +205,9 @@ define le2file(v, filename)
*/
cnt = 0;
while (v > 0) {
fputc(fd, char(v));
v >>= 8;
++cnt;
fputc(fd, char(v));
v >>= 8;
++cnt;
}
/*

View File

@@ -43,7 +43,7 @@ define quadtscomputenodes(order, expo, eps)
local t cht sht chp sum k PI places;
local h t0 x w;
if (__CZ__tanhsinh_order == order && __CZ__tanhsinh_prec == eps)
return 1;
return 1;
__CZ__tanhsinh_order = order;
__CZ__tanhsinh_prec = eps;
__CZ__tanhsinh_x = list();
@@ -68,34 +68,34 @@ define quadtscomputenodes(order, expo, eps)
*/
/* make use of x(-t) = -x(t), w(-t) = w(t) */
for (k = 0; k < 20 * order + 1; k++) {
/*
* x = tanh(pi/2 * sinh(t))
* w = pi/2 * cosh(t) / cosh(pi/2 * sinh(t))^2
*/
t = bround(t0 + k * h, places);
/*
* x = tanh(pi/2 * sinh(t))
* w = pi/2 * cosh(t) / cosh(pi/2 * sinh(t))^2
*/
t = bround(t0 + k * h, places);
cht = bround(cosh(t), places);
sht = bround(sinh(t), places);
chp = bround(cosh(0.5 * PI * sht), places);
x = bround(tanh(0.5 * PI * sht), places);
w = bround((PI * h * cht) / (2 * chp ^ 2), places);
/*
* c = bround(exp(a-b),places);
* d = bround(1/c,places);
* co =bround( (c+d)/2,places);
* si =bround( (c-d)/2,places);
* x = bround(si / co,places);
* w = bround((a+b) / co^2,places);
*/
if (abs(x - 1) <= eps)
break;
cht = bround(cosh(t), places);
sht = bround(sinh(t), places);
chp = bround(cosh(0.5 * PI * sht), places);
x = bround(tanh(0.5 * PI * sht), places);
w = bround((PI * h * cht) / (2 * chp ^ 2), places);
/*
* c = bround(exp(a-b),places);
* d = bround(1/c,places);
* co =bround( (c+d)/2,places);
* si =bround( (c-d)/2,places);
* x = bround(si / co,places);
* w = bround((a+b) / co^2,places);
*/
if (abs(x - 1) <= eps)
break;
append(__CZ__tanhsinh_x, x);
append(__CZ__tanhsinh_w, w);
/*
* a *= udelta;
* b *= urdelta;
*/
append(__CZ__tanhsinh_x, x);
append(__CZ__tanhsinh_w, w);
/*
* a *= udelta;
* b *= urdelta;
*/
}
/* Normalize the weights to make them add up to 2 (two) */
@@ -119,100 +119,100 @@ define quadtscore(a, b, n)
places = highbit(1 + int (1 / epsilon())) +1;
m = int (4 + max(0, ln(places / 30.0) / ln(2))) + 2;
if (!isnull(n)) {
order = n;
m = ilog(order / 3, 2) + 1;
order = n;
m = ilog(order / 3, 2) + 1;
} else
order = 3 * 2 ^ (m - 1);
order = 3 * 2 ^ (m - 1);
quadtscomputenodes(order, m, epsilon());
sizel = size(__CZ__tanhsinh_w);
if (isinfinite(a) || isinfinite(b)) {
/*
* x
* t = ------------
* 2
* sqrt(1 - y )
*/
if (isninf(a) && ispinf(b)) {
for (k = 0; k < sizel; k++) {
x1 = __CZ__tanhsinh_x[k];
x2 = -__CZ__tanhsinh_x[k];
w1 = __CZ__tanhsinh_w[k];
/*
* x
* t = ------------
* 2
* sqrt(1 - y )
*/
if (isninf(a) && ispinf(b)) {
for (k = 0; k < sizel; k++) {
x1 = __CZ__tanhsinh_x[k];
x2 = -__CZ__tanhsinh_x[k];
w1 = __CZ__tanhsinh_w[k];
x = bround(x1 * (1 - x1 ^ 2) ^ (-1 / 2), places);
xm = bround(x2 * (1 - x2 ^ 2) ^ (-1 / 2), places);
w = bround(w1 * (((1 - x1 ^ 2) ^ (-1 / 2)) / (1 - x1 ^ 2)),
places);
w2 = bround(w1 * (((1 - x2 ^ 2) ^ (-1 / 2)) / (1 - x2 ^ 2)),
places);
sum += bround(w * f(x), places);
sum += bround(w2 * f(xm), places);
}
}
/*
* 1
* t = - - + b + 1
* x
*/
else if (isninf(a) && !iscinf(b)) {
for (k = 0; k < sizel; k++) {
x1 = __CZ__tanhsinh_x[k];
x2 = -__CZ__tanhsinh_x[k];
w1 = __CZ__tanhsinh_w[k];
x = bround((b + 1) - (2 / (x1 + 1)), places);
xm = bround((b + 1) - (2 / (x2 + 1)), places);
w = bround(w1 * (1 / 2 * (2 / (x1 + 1)) ^ 2), places);
w2 = bround(w1 * (1 / 2 * (2 / (x2 + 1)) ^ 2), places);
sum += bround(w * f(x), places);
sum += bround(w2 * f(xm), places);
}
}
/*
* 1
* t = - + a - 1
* x
*/
else if (!iscinf(a) && ispinf(b)) {
for (k = 0; k < sizel; k++) {
x1 = __CZ__tanhsinh_x[k];
x2 = -__CZ__tanhsinh_x[k];
w1 = __CZ__tanhsinh_w[k];
x = bround((a - 1) + (2 / (x1 + 1)), places);
xm = bround((a - 1) + (2 / (x2 + 1)), places);
w = bround(w1 * (((1 / 2) * (2 / (x1 + 1)) ^ 2)), places);
w2 = bround(w1 * (((1 / 2) * (2 / (x2 + 1)) ^ 2)), places);
sum += bround(w * f(x), places);
sum += bround(w2 * f(xm), places);
}
} else if (isninf(a) || isninf(b)) {
/*TODO: swap(a,b) and negate(w)? Lookup! */
return newerror("quadtscore: reverse limits?");
} else {
return
newerror("quadtscore: complex infinity not yet implemented");
x = bround(x1 * (1 - x1 ^ 2) ^ (-1 / 2), places);
xm = bround(x2 * (1 - x2 ^ 2) ^ (-1 / 2), places);
w = bround(w1 * (((1 - x1 ^ 2) ^ (-1 / 2)) / (1 - x1 ^ 2)),
places);
w2 = bround(w1 * (((1 - x2 ^ 2) ^ (-1 / 2)) / (1 - x2 ^ 2)),
places);
sum += bround(w * f(x), places);
sum += bround(w2 * f(xm), places);
}
}
ret = sum;
/*
* 1
* t = - - + b + 1
* x
*/
else if (isninf(a) && !iscinf(b)) {
for (k = 0; k < sizel; k++) {
x1 = __CZ__tanhsinh_x[k];
x2 = -__CZ__tanhsinh_x[k];
w1 = __CZ__tanhsinh_w[k];
x = bround((b + 1) - (2 / (x1 + 1)), places);
xm = bround((b + 1) - (2 / (x2 + 1)), places);
w = bround(w1 * (1 / 2 * (2 / (x1 + 1)) ^ 2), places);
w2 = bround(w1 * (1 / 2 * (2 / (x2 + 1)) ^ 2), places);
sum += bround(w * f(x), places);
sum += bround(w2 * f(xm), places);
}
}
/*
* 1
* t = - + a - 1
* x
*/
else if (!iscinf(a) && ispinf(b)) {
for (k = 0; k < sizel; k++) {
x1 = __CZ__tanhsinh_x[k];
x2 = -__CZ__tanhsinh_x[k];
w1 = __CZ__tanhsinh_w[k];
x = bround((a - 1) + (2 / (x1 + 1)), places);
xm = bround((a - 1) + (2 / (x2 + 1)), places);
w = bround(w1 * (((1 / 2) * (2 / (x1 + 1)) ^ 2)), places);
w2 = bround(w1 * (((1 / 2) * (2 / (x2 + 1)) ^ 2)), places);
sum += bround(w * f(x), places);
sum += bround(w2 * f(xm), places);
}
} else if (isninf(a) || isninf(b)) {
/*TODO: swap(a,b) and negate(w)? Lookup! */
return newerror("quadtscore: reverse limits?");
} else {
return
newerror("quadtscore: complex infinity not yet implemented");
}
ret = sum;
} else {
/* Avoid rounding errors */
if (a == -1 && b == 1) {
c = 1;
d = 0;
} else {
c = (b - a) / 2;
d = (b + a) / 2;
}
sum = 0;
for (k = 0; k < sizel; k++) {
sum +=
bround(__CZ__tanhsinh_w[k] * f(c * __CZ__tanhsinh_x[k] + d),
places);
sum +=
bround(__CZ__tanhsinh_w[k] * f(c * -__CZ__tanhsinh_x[k] + d),
places);
}
ret = c * sum;
/* Avoid rounding errors */
if (a == -1 && b == 1) {
c = 1;
d = 0;
} else {
c = (b - a) / 2;
d = (b + a) / 2;
}
sum = 0;
for (k = 0; k < sizel; k++) {
sum +=
bround(__CZ__tanhsinh_w[k] * f(c * __CZ__tanhsinh_x[k] + d),
places);
sum +=
bround(__CZ__tanhsinh_w[k] * f(c * -__CZ__tanhsinh_x[k] + d),
places);
}
ret = c * sum;
}
epsilon(eps);
return ret;
@@ -225,97 +225,97 @@ define quadts(a, b, points)
local k sp results epsbits nsect interval length segment slope C ;
local x1 x2 y1 y2 sum D1 D2 D3 D4;
if (param(0) < 2)
return newerror("quadts: not enough arguments");
return newerror("quadts: not enough arguments");
epsbits = highbit(1 + int (1 / epsilon())) +1;
if (param(0) < 3 || isnull(points)) {
/* return as given */
return quadtscore(a, b);
/* return as given */
return quadtscore(a, b);
} else {
if ((isinfinite(a) || isinfinite(b))
&& (!ismat(points) && !islist(points)))
return
newerror(strcat
("quadts: segments of infinite length ",
"are not yet supported"));
if (ismat(points) || islist(points)) {
sp = size(points);
if (sp == 0)
return
newerror(strcat
("quadts: variable 'points` must be a list or ",
"1d-matrix of a length > 0"));
/* check if all points are numbers */
for (k = 0; k < sp; k++) {
if (!isnum(points[k]))
return
newerror(strcat
("quadts: elements of 'points` must be",
" numbers only"));
}
/* We have n-1 intervals and a and b, hence n-1 + 2 results */
results = mat[sp + 1];
if ((isinfinite(a) || isinfinite(b))
&& (!ismat(points) && !islist(points)))
return
newerror(strcat
("quadts: segments of infinite length ",
"are not yet supported"));
if (ismat(points) || islist(points)) {
sp = size(points);
if (sp == 0)
return
newerror(strcat
("quadts: variable 'points` must be a list or ",
"1d-matrix of a length > 0"));
/* check if all points are numbers */
for (k = 0; k < sp; k++) {
if (!isnum(points[k]))
return
newerror(strcat
("quadts: elements of 'points` must be",
" numbers only"));
}
/* We have n-1 intervals and a and b, hence n-1 + 2 results */
results = mat[sp + 1];
if (a != points[0]) {
results[0] = quadtscore(a, points[0]);
results[0] = quadtscore(a, points[0]);
} else {
results[0] = 0;
}
if (sp == 1) {
if (sp == 1) {
if (b != points[0]) {
results[1] = quadtscore(points[0], b);
results[1] = quadtscore(points[0], b);
} else {
results[1] = 0;
}
} else {
for (k = 1; k < sp; k++) {
results[k] = quadtscore(points[k - 1], points[k]);
}
} else {
for (k = 1; k < sp; k++) {
results[k] = quadtscore(points[k - 1], points[k]);
}
if (b != points[k - 1]) {
results[k] = quadtscore(points[k - 1], b);
results[k] = quadtscore(points[k - 1], b);
} else {
results[k] = 0;
}
}
} else {
if (!isint(points) || points <= 0)
return newerror(strcat("quadts: variable 'points` must be a ",
"list or a positive integer"));
/* Taking "points" as the number of equally spaced intervals */
results = mat[points + 1];
/* It is easy if a,b lie on the real line */
if (isreal(a) && isreal(b)) {
length = abs(a - b);
segment = length / points;
}
} else {
if (!isint(points) || points <= 0)
return newerror(strcat("quadts: variable 'points` must be a ",
"list or a positive integer"));
/* Taking "points" as the number of equally spaced intervals */
results = mat[points + 1];
/* It is easy if a,b lie on the real line */
if (isreal(a) && isreal(b)) {
length = abs(a - b);
segment = length / points;
for (k = 1; k <= points; k++) {
results[k - 1] =
quadtscore(a + (k - 1) * segment, a + k * segment);
}
} else {
/* We have at least one complex limit but treat "points" still
for (k = 1; k <= points; k++) {
results[k - 1] =
quadtscore(a + (k - 1) * segment, a + k * segment);
}
} else {
/* We have at least one complex limit but treat "points" still
* as the number of equally spaced intervals on a straight line
* connecting a and b. Computing the segments here is a bit
* more complicated but not much, it should have been taught in
* high school.
* Other contours by way of a list of points */
slope = (im(b) - im(a)) / (re(b) - re(a));
C = (im(a) + slope) * re(a);
length = abs(re(a) - re(b));
segment = length / points;
* Other contours by way of a list of points */
slope = (im(b) - im(a)) / (re(b) - re(a));
C = (im(a) + slope) * re(a);
length = abs(re(a) - re(b));
segment = length / points;
/* y = mx+C where m is the slope, x is the real part and y the
* imaginary part */
/* y = mx+C where m is the slope, x is the real part and y the
* imaginary part */
if(re(a)>re(b))swap(a,b);
for (k = re(a); k <= (re(b)); k+=segment) {
x1 = slope*(k) + C;
results[k] = quadtscore(k + x1 * 1i);
}
} /* else of isreal */
} /* else of ismat|islist */
} /* else of isnull(points) */
for (k = re(a); k <= (re(b)); k+=segment) {
x1 = slope*(k) + C;
results[k] = quadtscore(k + x1 * 1i);
}
} /* else of isreal */
} /* else of ismat|islist */
} /* else of isnull(points) */
/* With a bit of undeserved luck we have a result by now. */
sp = size(results);
for (k = 0; k < sp; k++) {
sum += results[k];
sum += results[k];
}
return sum;
}
@@ -330,7 +330,7 @@ define quadglcomputenodes(N)
local places k l x w t1 t2 t3 t4 t5 r tmp;
if (__CZ__gl_order == N && __CZ__gl_prec == epsilon())
return;
return;
__CZ__gl_x = mat[N];
__CZ__gl_w = mat[N];
@@ -344,28 +344,28 @@ define quadglcomputenodes(N)
* Trick shamelessly stolen from D. Bailey et .al (program "arprec")
*/
for (k = 1; k <= N//2; k++) {
r = bround(cos(pi() * (k - .25) / (N + .5)), places);
while (1) {
t1 = 1, t2 = 0;
for (l = 1; l <= N; l++) {
t3 = t2;
t2 = t1;
t1 = bround(((2 * l - 1) * r * t2 - (l - 1) * t3) / l, places);
}
t4 = bround(N * (r * t1 - t2) / ((r ^ 2) - 1), places);
t5 = r;
tmp = t1 / t4;
r = r - tmp;
if (abs(tmp) <= epsilon())
break;
}
x = r;
w = bround(2 / ((1 - r ^ 2) * t4 ^ 2), places);
r = bround(cos(pi() * (k - .25) / (N + .5)), places);
while (1) {
t1 = 1, t2 = 0;
for (l = 1; l <= N; l++) {
t3 = t2;
t2 = t1;
t1 = bround(((2 * l - 1) * r * t2 - (l - 1) * t3) / l, places);
}
t4 = bround(N * (r * t1 - t2) / ((r ^ 2) - 1), places);
t5 = r;
tmp = t1 / t4;
r = r - tmp;
if (abs(tmp) <= epsilon())
break;
}
x = r;
w = bround(2 / ((1 - r ^ 2) * t4 ^ 2), places);
__CZ__gl_x[k - 1] = x;
__CZ__gl_w[k - 1] = w;
__CZ__gl_x[N - k] = -__CZ__gl_x[k - 1];
__CZ__gl_w[N - k] = __CZ__gl_w[k - 1];
__CZ__gl_x[k - 1] = x;
__CZ__gl_w[k - 1] = w;
__CZ__gl_x[N - k] = -__CZ__gl_x[k - 1];
__CZ__gl_w[N - k] = __CZ__gl_w[k - 1];
}
return;
}
@@ -386,64 +386,64 @@ define quadglcore(a, b, n)
eps = epsilon(epsilon() * 1e-2);
places = highbit(1 + int (1 / epsilon())) +1;
if (!isnull(n))
order = n;
order = n;
else {
m = int (4 + max(0, ln(places / 30.0) / ln(2))) + 2;
order = 3 * 2 ^ (m - 1);
m = int (4 + max(0, ln(places / 30.0) / ln(2))) + 2;
order = 3 * 2 ^ (m - 1);
}
quadglcomputenodes(order, 1);
if (isinfinite(a) || isinfinite(b)) {
if (isninf(a) && ispinf(b)) {
for (k = 0; k < order; k++) {
x1 = __CZ__gl_x[k];
w1 = __CZ__gl_w[k];
if (isninf(a) && ispinf(b)) {
for (k = 0; k < order; k++) {
x1 = __CZ__gl_x[k];
w1 = __CZ__gl_w[k];
x = bround(x1 * (1 - x1 ^ 2) ^ (-1 / 2), places);
w = bround(w1 * (((1 - x1 ^ 2) ^ (-1 / 2)) / (1 - x1 ^ 2)),
places);
sum += bround(w * f(x), places);
}
} else if (isninf(a) && !iscinf(b)) {
for (k = 0; k < order; k++) {
x1 = __CZ__gl_x[k];
w1 = __CZ__gl_w[k];
x = bround(x1 * (1 - x1 ^ 2) ^ (-1 / 2), places);
w = bround(w1 * (((1 - x1 ^ 2) ^ (-1 / 2)) / (1 - x1 ^ 2)),
places);
sum += bround(w * f(x), places);
}
} else if (isninf(a) && !iscinf(b)) {
for (k = 0; k < order; k++) {
x1 = __CZ__gl_x[k];
w1 = __CZ__gl_w[k];
x = bround((b + 1) - (2 / (x1 + 1)), places);
w = bround(w1 * (1 / 2 * (2 / (x1 + 1)) ^ 2), places);
sum += bround(w * f(x), places);
}
} else if (!iscinf(a) && ispinf(b)) {
for (k = 0; k < order; k++) {
x1 = __CZ__gl_x[k];
w1 = __CZ__gl_w[k];
x = bround((a - 1) + (2 / (x1 + 1)), places);
w = bround(w1 * (((1 / 2) * (2 / (x1 + 1)) ^ 2)), places);
sum += bround(w * f(x), places);
}
} else if (isninf(a) || isninf(b)) {
/*TODO: swap(a,b) and negate(w)? Lookup! */
return newerror("quadglcore: reverse limits?");
} else
return
newerror("quadglcore: complex infinity not yet implemented");
ret = sum;
x = bround((b + 1) - (2 / (x1 + 1)), places);
w = bround(w1 * (1 / 2 * (2 / (x1 + 1)) ^ 2), places);
sum += bround(w * f(x), places);
}
} else if (!iscinf(a) && ispinf(b)) {
for (k = 0; k < order; k++) {
x1 = __CZ__gl_x[k];
w1 = __CZ__gl_w[k];
x = bround((a - 1) + (2 / (x1 + 1)), places);
w = bround(w1 * (((1 / 2) * (2 / (x1 + 1)) ^ 2)), places);
sum += bround(w * f(x), places);
}
} else if (isninf(a) || isninf(b)) {
/*TODO: swap(a,b) and negate(w)? Lookup! */
return newerror("quadglcore: reverse limits?");
} else
return
newerror("quadglcore: complex infinity not yet implemented");
ret = sum;
} else {
/* Avoid rounding errors */
if (a == -1 && b == 1) {
c = 1;
d = 0;
} else {
c = (b - a) / 2;
d = (b + a) / 2;
}
sum = 0;
for (k = 0; k < order; k++) {
sum += bround(__CZ__gl_w[k] * f(c * __CZ__gl_x[k] + d), places);
}
ret = c * sum;
/* Avoid rounding errors */
if (a == -1 && b == 1) {
c = 1;
d = 0;
} else {
c = (b - a) / 2;
d = (b + a) / 2;
}
sum = 0;
for (k = 0; k < order; k++) {
sum += bround(__CZ__gl_w[k] * f(c * __CZ__gl_x[k] + d), places);
}
ret = c * sum;
}
epsilon(eps);
return ret;
@@ -452,97 +452,97 @@ define quadglcore(a, b, n)
define quadgl(a, b, points)
{
local k sp results epsbits nsect interval length segment slope C x1 y1 x2
y2;
y2;
local sum D1 D2 D3 D4;
if (param(0) < 2)
return newerror("quadgl: not enough arguments");
return newerror("quadgl: not enough arguments");
epsbits = highbit(1 + int (1 / epsilon())) +1;
if (isnull(points)) {
/* return as given */
return quadglcore(a, b);
/* return as given */
return quadglcore(a, b);
} else {
/* But if we could half the time needed to execute a single operation
* we could do all of it in just twice that time. */
if (isinfinite(a) || isinfinite(b)
&& (!ismat(points) && !islist(points)))
return
newerror(strcat
("quadgl: multiple segments of infinite length ",
"are not yet supported"));
if (ismat(points) || islist(points)) {
sp = size(points);
if (sp == 0)
return
newerror(strcat
("quadgl: variable 'points` must be a list or ",
"1d-matrix of a length > 0"));
/* check if all points are numbers */
for (k = 0; k < sp; k++) {
if (!isnum(points[k]))
return
newerror(strcat
("quadgl: elements of 'points` must be ",
"numbers only"));
}
/* We have n-1 intervals and a and b, hence n-1 + 2 results */
results = mat[sp + 1];
/* But if we could half the time needed to execute a single operation
* we could do all of it in just twice that time. */
if (isinfinite(a) || isinfinite(b)
&& (!ismat(points) && !islist(points)))
return
newerror(strcat
("quadgl: multiple segments of infinite length ",
"are not yet supported"));
if (ismat(points) || islist(points)) {
sp = size(points);
if (sp == 0)
return
newerror(strcat
("quadgl: variable 'points` must be a list or ",
"1d-matrix of a length > 0"));
/* check if all points are numbers */
for (k = 0; k < sp; k++) {
if (!isnum(points[k]))
return
newerror(strcat
("quadgl: elements of 'points` must be ",
"numbers only"));
}
/* We have n-1 intervals and a and b, hence n-1 + 2 results */
results = mat[sp + 1];
if (a != points[0]) {
results[0] = quadglcore(a, points[0]);
results[0] = quadglcore(a, points[0]);
} else {
results[0] = 0;
}
if (sp == 1) {
if (b != points[0]) {
results[1] = quadglcore(points[0], b);
if (sp == 1) {
if (b != points[0]) {
results[1] = quadglcore(points[0], b);
} else {
results[1] = 0;
}
} else {
for (k = 1; k < sp; k++) {
results[k] = quadglcore(points[k - 1], points[k]);
}
} else {
for (k = 1; k < sp; k++) {
results[k] = quadglcore(points[k - 1], points[k]);
}
if (b != points[k - 1]) {
results[k] = quadglcore(points[k - 1], b);
results[k] = quadglcore(points[k - 1], b);
} else {
results[k] = 0;
}
}
} else {
if (!isint(points) || points <= 0)
return newerror(strcat("quadgl: variable 'points` must be a ",
"list or a positive integer"));
/* Taking "points" as the number of equally spaced intervals */
results = mat[points + 1];
/* It is easy if a,b lie on the real line */
if (isreal(a) && isreal(b)) {
length = abs(a - b);
segment = length / points;
}
} else {
if (!isint(points) || points <= 0)
return newerror(strcat("quadgl: variable 'points` must be a ",
"list or a positive integer"));
/* Taking "points" as the number of equally spaced intervals */
results = mat[points + 1];
/* It is easy if a,b lie on the real line */
if (isreal(a) && isreal(b)) {
length = abs(a - b);
segment = length / points;
for (k = 1; k <= points; k++) {
results[k - 1] =
quadglcore(a + (k - 1) * segment, a + k * segment);
}
} else {
/* Other contours by way of a list of points */
slope = (im(b) - im(a)) / (re(b) - re(a));
C = (im(a) + slope) * re(a);
length = abs(re(a) - re(b));
segment = length / points;
for (k = 1; k <= points; k++) {
results[k - 1] =
quadglcore(a + (k - 1) * segment, a + k * segment);
}
} else {
/* Other contours by way of a list of points */
slope = (im(b) - im(a)) / (re(b) - re(a));
C = (im(a) + slope) * re(a);
length = abs(re(a) - re(b));
segment = length / points;
/* y = mx+C where m is the slope, x is the real part and y the
* imaginary part */
/* y = mx+C where m is the slope, x is the real part and y the
* imaginary part */
if(re(a)>re(b))swap(a,b);
for (k = re(a); k <= (re(b)); k+=segment) {
x1 = slope*(k) + C;
results[k] = quadglcore(k + x1 * 1i);
}
} /* else of isreal */
} /* else of ismat|islist */
} /* else of isnull(points) */
for (k = re(a); k <= (re(b)); k+=segment) {
x1 = slope*(k) + C;
results[k] = quadglcore(k + x1 * 1i);
}
} /* else of isreal */
} /* else of ismat|islist */
} /* else of isnull(points) */
/* With a bit of undeserved luck we have a result by now. */
sp = size(results);
for (k = 0; k < sp; k++) {
sum += results[k];
sum += results[k];
}
return sum;
}
@@ -550,49 +550,49 @@ define quadgl(a, b, points)
define quad(a, b, points = -1, method = "tanhsinh")
{
if (isnull(a) || isnull(b) || param(0) < 2)
return newerror("quad: both limits must be given");
return newerror("quad: both limits must be given");
if (isstr(a)) {
if (strncmp(a, "cinf", 1) == 0)
return
newerror(strcat
("quad: complex infinity not yet supported, use",
" 'pinf' or 'ninf' respectively"));
if (strncmp(a, "cinf", 1) == 0)
return
newerror(strcat
("quad: complex infinity not yet supported, use",
" 'pinf' or 'ninf' respectively"));
}
if (isstr(b)) {
if (strncmp(b, "cinf", 1) == 0)
return
newerror(strcat
("quad: complex infinity not yet supported, use",
" 'pinf' or 'ninf' respectively"));
if (strncmp(b, "cinf", 1) == 0)
return
newerror(strcat
("quad: complex infinity not yet supported, use",
" 'pinf' or 'ninf' respectively"));
}
if (param(0) == 3) {
if (isstr(points))
method = points;
if (isstr(points))
method = points;
}
if (strncmp(method, "tanhsinh", 1) == 0) {
if (!isstr(points)) {
if (points == -1) {
return quadts(a, b);
} else {
return quadts(a, b, points);
}
} else {
return quadts(a, b);
}
if (!isstr(points)) {
if (points == -1) {
return quadts(a, b);
} else {
return quadts(a, b, points);
}
} else {
return quadts(a, b);
}
}
if (strncmp(method, "gausslegendre", 1) == 0) {
if (!isstr(points)) {
if (points == -1) {
return quadgl(a, b);
} else {
return quadgl(a, b, points);
}
} else {
return quadgl(a, b);
}
if (!isstr(points)) {
if (points == -1) {
return quadgl(a, b);
} else {
return quadgl(a, b, points);
}
} else {
return quadgl(a, b);
}
}
}
@@ -602,33 +602,33 @@ define makerange(start, end, steps)
local segment;
steps = int (steps);
if (steps < 1) {
return newerror("makerange: number of steps must be > 0");
return newerror("makerange: number of steps must be > 0");
}
if (!isnum(start) || !isnum(end)) {
return newerror("makerange: only numbers are supported yet");
return newerror("makerange: only numbers are supported yet");
}
if (isreal(start) && isreal(end)) {
step = (end - start) / (steps);
print step;
ret = mat[steps + 1];
for (k = 0; k <= steps; k++) {
ret[k] = k * step + start;
}
step = (end - start) / (steps);
print step;
ret = mat[steps + 1];
for (k = 0; k <= steps; k++) {
ret[k] = k * step + start;
}
} else {
ret = mat[steps + 1];
if (re(start) > re(end)) {
swap(start, end);
}
ret = mat[steps + 1];
if (re(start) > re(end)) {
swap(start, end);
}
slope = (im(end) - im(start)) / (re(end) - re(start));
C = im(start) - slope * re(start);
length = abs(re(start) - re(end));
segment = length / (steps);
slope = (im(end) - im(start)) / (re(end) - re(start));
C = im(start) - slope * re(start);
length = abs(re(start) - re(end));
segment = length / (steps);
for (k = re(start), l = 0; k <= (re(end)); k += segment, l++) {
x1 = slope * (k) + C;
ret[l] = k + x1 * 1i;
}
for (k = re(start), l = 0; k <= (re(end)); k += segment, l++) {
x1 = slope * (k) + C;
ret[l] = k + x1 * 1i;
}
}
return ret;
@@ -638,23 +638,23 @@ define makecircle(radius, center, points)
{
local ret k a b twopi centerx centery;
if (!isint(points) || points < 2) {
return
newerror("makecircle: number of points is not a positive integer");
return
newerror("makecircle: number of points is not a positive integer");
}
if (!isnum(center)) {
return newerror("makecircle: center does not lie on the complex plane");
return newerror("makecircle: center does not lie on the complex plane");
}
if (!isreal(radius) || radius <= 0) {
return newerror("makecircle: radius is not a real > 0");
return newerror("makecircle: radius is not a real > 0");
}
ret = mat[points];
twopi = 2 * pi();
centerx = re(center);
centery = im(center);
for (k = 0; k < points; k++) {
a = centerx + radius * cos(twopi * k / points);
b = centery + radius * sin(twopi * k / points);
ret[k] = a + b * 1i;
a = centerx + radius * cos(twopi * k / points);
b = centery + radius * sin(twopi * k / points);
ret[k] = a + b * 1i;
}
return ret;
}
@@ -663,32 +663,32 @@ define makeellipse(angle, a, b, center, points)
{
local ret k x y twopi centerx centery;
if (!isint(points) || points < 2) {
return
newerror("makeellipse: number of points is not a positive integer");
return
newerror("makeellipse: number of points is not a positive integer");
}
if (!isnum(center)) {
return
newerror("makeellipse: center does not lie on the complex plane");
return
newerror("makeellipse: center does not lie on the complex plane");
}
if (!isreal(a) || a <= 0) {
return newerror("makecircle: a is not a real > 0");
return newerror("makecircle: a is not a real > 0");
}
if (!isreal(b) || b <= 0) {
return newerror("makecircle: b is not a real > 0");
return newerror("makecircle: b is not a real > 0");
}
if (!isreal(angle)) {
return newerror("makecircle: angle is not a real");
return newerror("makecircle: angle is not a real");
}
ret = mat[points];
twopi = 2 * pi();
centerx = re(center);
centery = im(center);
for (k = 0; k < points; k++) {
x = centerx + a * cos(twopi * k / points) * cos(angle)
- b * sin(twopi * k / points) * sin(angle);
y = centerx + a * cos(twopi * k / points) * sin(angle)
+ b * sin(twopi * k / points) * cos(angle);
ret[k] = x + y * 1i;
x = centerx + a * cos(twopi * k / points) * cos(angle)
- b * sin(twopi * k / points) * sin(angle);
y = centerx + a * cos(twopi * k / points) * sin(angle)
+ b * sin(twopi * k / points) * cos(angle);
ret[k] = x + y * 1i;
}
return ret;
}
@@ -698,13 +698,13 @@ define makepoints()
local ret k;
ret = mat[param(0)];
for (k = 0; k < param(0); k++) {
if (!isnum(param(k + 1))) {
return
newerror(strcat
("makepoints: parameter number \"", str(k + 1),
"\" is not a number"));
}
ret[k] = param(k + 1);
if (!isnum(param(k + 1))) {
return
newerror(strcat
("makepoints: parameter number \"", str(k + 1),
"\" is not a number"));
}
ret[k] = param(k + 1);
}
return ret;
}

View File

@@ -17,8 +17,8 @@
* 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: 2013/08/11 01:31:28
* File existed as early as: 2013
* Under source code control: 2013/08/11 01:31:28
* File existed as early as: 2013
*/
@@ -109,10 +109,10 @@ define lambertw_series_print(){
The exact branch must be given explicitly, e.g.:
; lambertw(-exp(-1)+.001)-lambertw_series(-exp(-1)+.001,epsilon()*1e-10,0)
-0.14758879113205794065490184399030194122136720202792-
-0.14758879113205794065490184399030194122136720202792-
0.00000000000000000000000000000000000000000000000000i
; lambertw(-exp(-1)+.001)-lambertw_series(-exp(-1)+.001,epsilon()*1e-10,1)
0.00000000000000000000000000000000000000000000000000-
0.00000000000000000000000000000000000000000000000000-
0.00000000000000000000000000000000000000000000000000i
*/
define lambertw_series(z,eps,branch,terms){
@@ -210,34 +210,34 @@ define lambertw(z,branch){
sufficient precision itself (M below was calculated by Mathematica and also
with the series above with epsilon(1e-200)):
; epsilon(1e-50)
0.00000000000000000001
0.00000000000000000001
; display(50)
20
20
; M=-0.9999999999999999999999997668356018402875796636464119050387
; lambertw(-exp(-1)+1e-50,0)-M
-0.00000000000000000000000002678416515423276355643684
-0.00000000000000000000000002678416515423276355643684
; epsilon(1e-60)
0.0000000000000000000000000000000000000000000000000
0.0000000000000000000000000000000000000000000000000
; A=-exp(-1)+1e-50
; epsilon(1e-50)
0.00000000000000000000000000000000000000000000000000
0.00000000000000000000000000000000000000000000000000
; lambertw(A,0)-M
-0.00000000000000000000000000000000000231185460220585
-0.00000000000000000000000000000000000231185460220585
; lambertw_series(A,epsilon(),0)-M
-0.00000000000000000000000000000000000132145133161626
-0.00000000000000000000000000000000000132145133161626
; epsilon(1e-100)
0.00000000000000000000000000000000000000000000000001
0.00000000000000000000000000000000000000000000000001
; A=-exp(-1)+1e-50
; epsilon(1e-65)
0.00000000000000000000000000000000000000000000000000
0.00000000000000000000000000000000000000000000000000
; lambertw_series(A,epsilon(),0)-M
0.00000000000000000000000000000000000000000000000000
0.00000000000000000000000000000000000000000000000000
; lambertw_series(-exp(-1)+1e-50,epsilon(),0)-M
-0.00000000000000000000000000000000000000002959444084
-0.00000000000000000000000000000000000000002959444084
; epsilon(1e-74)
0.00000000000000000000000000000000000000000000000000
0.00000000000000000000000000000000000000000000000000
; lambertw_series(-exp(-1)+1e-50,epsilon(),0)-M
-0.00000000000000000000000000000000000000000000000006
-0.00000000000000000000000000000000000000000000000006
*/
closeness = abs(z-branchpoint);
if( closeness< 1){

View File

@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,23 +17,23 @@
* 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: 2005/12/12 06:41:50
* File existed as early as: 2005
* Under source code control: 2005/12/12 06:41:50
* File existed as early as: 2005
*
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
/*
* linear - perform a simple two point 2D linear interpolation
*
* given:
* x0, y0 first known point on the line
* x1, y1 second known point on the line
* x a given point to interpolate on
* x0, y0 first known point on the line
* x1, y1 second known point on the line
* x a given point to interpolate on
*
* returns:
* y such that (x,y) is on the line defined by (x0,y0) and (x1,y1)
* y such that (x,y) is on the line defined by (x0,y0) and (x1,y1)
*
* NOTE: The line cannot be vertical. So x0 != y0.
*/
@@ -41,10 +41,10 @@ define linear(x0, y0, x1, y1, x)
{
/* firewall */
if (!isnum(x0) || ! isnum(y0) || !isnum(x1) || ! isnum(y1) || !isnum(x)) {
quit "non-numeric argument passed to linear";
quit "non-numeric argument passed to linear";
}
if (x0 == x1) {
quit "linear given a line with an infinite slope";
quit "linear given a line with an infinite slope";
}
/* return y = y0 + (delta_Y/delta_X) * (x - x0) */

View File

@@ -17,8 +17,8 @@
* 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: 2013/08/11 01:31:28
* File existed as early as: 2013
* Under source code control: 2013/08/11 01:31:28
* File existed as early as: 2013
*/

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,11 +17,11 @@
* 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: 1991/01/11 05:41:43
* File existed as early as: 1991
* Under source code control: 1991/01/11 05:41:43
* File existed as early as: 1991
*
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
/*
@@ -31,260 +31,260 @@
*
* These values were taken from:
*
* "Prime numbers and Computer Methods for Factorization", by Hans Riesel,
* Birkhauser, 1985, pp 384-387.
* "Prime numbers and Computer Methods for Factorization", by Hans Riesel,
* Birkhauser, 1985, pp 384-387.
*
* This routine assumes that the file "lucas.cal" has been loaded.
*
* NOTE: There are several errors in Riesel's table that have been corrected
* in this file:
* in this file:
*
* 193*2^87-1 is prime
* 193*2^97-1 is NOT prime
* 199*2^211-1 is prime
* 199*2^221-1 is NOT prime
* 193*2^87-1 is prime
* 193*2^97-1 is NOT prime
* 199*2^211-1 is prime
* 199*2^221-1 is NOT prime
*/
static prime_cnt = 1145; /* number of primes in the list */
static prime_cnt = 1145; /* number of primes in the list */
/* h = prime parameters */
static mat h_p[prime_cnt] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* element 0 */
1, 1, 1, 1, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 7, 7, 7, 7,
7, 7, 7, 7, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 11, 11, 11, 11, 11, 11, 11,
11, 11, 11, 13, 13, 13, 13, 13, 13, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, /* 100 */
15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 23, 23,
23, 23, 23, 23, 23, 23, 23, 25, 25, 25,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
25, 25, 25, 27, 27, 27, 27, 27, 27, 27, /* 200 */
27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 27, 27, 27, 29, 29, 29,
29, 29, 31, 31, 31, 31, 31, 31, 31, 31,
31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
33, 33, 33, 33, 35, 35, 35, 35, 35, 35,
35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
35, 37, 39, 39, 39, 39, 39, 39, 39, 39,
39, 41, 41, 41, 41, 41, 41, 41, 41, 41, /* 300 */
41, 41, 41, 41, 43, 43, 43, 43, 43, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 47, 47, 47, 47, 49,
49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
49, 49, 49, 49, 49, 49, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 53, 53, 53, 53, 53, 53, 53, 53, 53,
53, 55, 55, 55, 55, 55, 55, 55, 55, 55, /* 400 */
55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
57, 57, 57, 57, 57, 57, 57, 57, 59, 59,
59, 59, 59, 59, 61, 61, 61, 61, 61, 61,
61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
61, 63, 63, 63, 63, 63, 63, 63, 63, 63,
63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
63, 63, 63, 63, 65, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
65, 65, 67, 67, 67, 67, 67, 67, 67, 67, /* 500 */
69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
69, 69, 71, 71, 71, 73, 73, 73, 73, 73,
73, 75, 75, 75, 75, 75, 75, 75, 75, 75,
75, 75, 75, 75, 75, 75, 75, 75, 75, 75,
75, 75, 75, 75, 75, 75, 75, 77, 77, 77,
77, 77, 77, 77, 77, 77, 77, 77, 77, 79,
79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
81, 81, 81, 81, 81, 81, 81, 81, 81, 81, /* 600 */
81, 81, 81, 83, 83, 83, 83, 83, 83, 83,
83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
83, 83, 83, 83, 83, 85, 85, 85, 85, 85,
85, 85, 85, 85, 87, 87, 87, 87, 87, 87,
87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
87, 87, 87, 87, 87, 87, 89, 89, 89, 89,
89, 89, 89, 89, 89, 91, 91, 91, 91, 91,
91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
91, 91, 91, 91, 91, 91, 91, 93, 93, 93,
93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* 700 */
93, 93, 93, 93, 93, 95, 95, 95, 95, 95,
95, 95, 95, 95, 95, 97, 97, 97, 97, 97,
99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 101, 101, 101, 101,
103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
103, 103, 103, 105, 105, 105, 105, 105, 105, 105,
105, 105, 105, 105, 105, 105, 105, 105, 105, 105,
105, 105, 107, 107, 107, 107, 107, 107, 107, 107,
107, 107, 107, 107, 107, 107, 109, 109, 109, 109,
109, 113, 113, 113, 113, 113, 113, 113, 113, 113, /* 800 */
113, 115, 115, 115, 115, 115, 115, 115, 115, 115,
115, 115, 115, 115, 115, 115, 115, 119, 119, 119,
119, 119, 119, 119, 119, 121, 121, 121, 121, 121,
121, 121, 121, 121, 121, 121, 121, 125, 125, 125,
125, 125, 125, 127, 127, 131, 131, 131, 131, 131,
131, 131, 131, 131, 131, 133, 133, 133, 133, 133,
133, 133, 133, 133, 133, 133, 133, 133, 137, 137,
137, 137, 139, 139, 139, 139, 139, 139, 139, 139,
139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
139, 139, 139, 139, 139, 139, 139, 139, 139, 143, /* 900 */
143, 143, 143, 143, 143, 143, 143, 143, 143, 143,
143, 143, 143, 143, 143, 143, 143, 143, 143, 143,
143, 143, 143, 145, 145, 145, 145, 145, 145, 145,
145, 145, 145, 145, 149, 149, 149, 149, 149, 149,
149, 151, 151, 151, 155, 155, 155, 155, 155, 155,
155, 155, 155, 155, 155, 155, 157, 157, 157, 157,
157, 157, 157, 157, 157, 161, 161, 161, 161, 161,
161, 161, 161, 161, 161, 161, 161, 161, 161, 161,
163, 163, 163, 163, 167, 167, 167, 167, 167, 167,
167, 167, 167, 167, 167, 167, 169, 169, 169, 169, /* 1000 */
169, 169, 169, 169, 169, 169, 169, 169, 173, 173,
173, 173, 173, 173, 173, 173, 173, 173, 173, 173,
173, 173, 173, 173, 175, 175, 175, 175, 175, 175,
175, 175, 175, 175, 175, 175, 175, 175, 175, 175,
179, 179, 179, 181, 181, 181, 181, 181, 181, 181,
181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
181, 181, 181, 181, 181, 181, 181, 181, 185, 185,
185, 185, 185, 185, 185, 185, 185, 185, 187, 187,
187, 187, 187, 191, 193, 193, 193, 193, 193, 193,
193, 197, 197, 197, 197, 197, 197, 197, 197, 197, /* 1100 */
197, 197, 197, 197, 197, 197, 197, 197, 197, 199,
199, 199, 199, 199, 199, 199, 199, 199, 199, 199,
199, 199, 199, 199, 199, 199, 199, 199, 199, 199,
199, 199, 199, 199, 199
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* element 0 */
1, 1, 1, 1, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 7, 7, 7, 7,
7, 7, 7, 7, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 11, 11, 11, 11, 11, 11, 11,
11, 11, 11, 13, 13, 13, 13, 13, 13, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, /* 100 */
15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 23, 23,
23, 23, 23, 23, 23, 23, 23, 25, 25, 25,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
25, 25, 25, 27, 27, 27, 27, 27, 27, 27, /* 200 */
27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
27, 27, 27, 27, 27, 27, 27, 29, 29, 29,
29, 29, 31, 31, 31, 31, 31, 31, 31, 31,
31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
33, 33, 33, 33, 35, 35, 35, 35, 35, 35,
35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
35, 37, 39, 39, 39, 39, 39, 39, 39, 39,
39, 41, 41, 41, 41, 41, 41, 41, 41, 41, /* 300 */
41, 41, 41, 41, 43, 43, 43, 43, 43, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 47, 47, 47, 47, 49,
49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
49, 49, 49, 49, 49, 49, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
51, 53, 53, 53, 53, 53, 53, 53, 53, 53,
53, 55, 55, 55, 55, 55, 55, 55, 55, 55, /* 400 */
55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
57, 57, 57, 57, 57, 57, 57, 57, 59, 59,
59, 59, 59, 59, 61, 61, 61, 61, 61, 61,
61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
61, 63, 63, 63, 63, 63, 63, 63, 63, 63,
63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
63, 63, 63, 63, 65, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
65, 65, 67, 67, 67, 67, 67, 67, 67, 67, /* 500 */
69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
69, 69, 71, 71, 71, 73, 73, 73, 73, 73,
73, 75, 75, 75, 75, 75, 75, 75, 75, 75,
75, 75, 75, 75, 75, 75, 75, 75, 75, 75,
75, 75, 75, 75, 75, 75, 75, 77, 77, 77,
77, 77, 77, 77, 77, 77, 77, 77, 77, 79,
79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
81, 81, 81, 81, 81, 81, 81, 81, 81, 81, /* 600 */
81, 81, 81, 83, 83, 83, 83, 83, 83, 83,
83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
83, 83, 83, 83, 83, 85, 85, 85, 85, 85,
85, 85, 85, 85, 87, 87, 87, 87, 87, 87,
87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
87, 87, 87, 87, 87, 87, 89, 89, 89, 89,
89, 89, 89, 89, 89, 91, 91, 91, 91, 91,
91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
91, 91, 91, 91, 91, 91, 91, 93, 93, 93,
93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* 700 */
93, 93, 93, 93, 93, 95, 95, 95, 95, 95,
95, 95, 95, 95, 95, 97, 97, 97, 97, 97,
99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 101, 101, 101, 101,
103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
103, 103, 103, 105, 105, 105, 105, 105, 105, 105,
105, 105, 105, 105, 105, 105, 105, 105, 105, 105,
105, 105, 107, 107, 107, 107, 107, 107, 107, 107,
107, 107, 107, 107, 107, 107, 109, 109, 109, 109,
109, 113, 113, 113, 113, 113, 113, 113, 113, 113, /* 800 */
113, 115, 115, 115, 115, 115, 115, 115, 115, 115,
115, 115, 115, 115, 115, 115, 115, 119, 119, 119,
119, 119, 119, 119, 119, 121, 121, 121, 121, 121,
121, 121, 121, 121, 121, 121, 121, 125, 125, 125,
125, 125, 125, 127, 127, 131, 131, 131, 131, 131,
131, 131, 131, 131, 131, 133, 133, 133, 133, 133,
133, 133, 133, 133, 133, 133, 133, 133, 137, 137,
137, 137, 139, 139, 139, 139, 139, 139, 139, 139,
139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
139, 139, 139, 139, 139, 139, 139, 139, 139, 143, /* 900 */
143, 143, 143, 143, 143, 143, 143, 143, 143, 143,
143, 143, 143, 143, 143, 143, 143, 143, 143, 143,
143, 143, 143, 145, 145, 145, 145, 145, 145, 145,
145, 145, 145, 145, 149, 149, 149, 149, 149, 149,
149, 151, 151, 151, 155, 155, 155, 155, 155, 155,
155, 155, 155, 155, 155, 155, 157, 157, 157, 157,
157, 157, 157, 157, 157, 161, 161, 161, 161, 161,
161, 161, 161, 161, 161, 161, 161, 161, 161, 161,
163, 163, 163, 163, 167, 167, 167, 167, 167, 167,
167, 167, 167, 167, 167, 167, 169, 169, 169, 169, /* 1000 */
169, 169, 169, 169, 169, 169, 169, 169, 173, 173,
173, 173, 173, 173, 173, 173, 173, 173, 173, 173,
173, 173, 173, 173, 175, 175, 175, 175, 175, 175,
175, 175, 175, 175, 175, 175, 175, 175, 175, 175,
179, 179, 179, 181, 181, 181, 181, 181, 181, 181,
181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
181, 181, 181, 181, 181, 181, 181, 181, 185, 185,
185, 185, 185, 185, 185, 185, 185, 185, 187, 187,
187, 187, 187, 191, 193, 193, 193, 193, 193, 193,
193, 197, 197, 197, 197, 197, 197, 197, 197, 197, /* 1100 */
197, 197, 197, 197, 197, 197, 197, 197, 197, 199,
199, 199, 199, 199, 199, 199, 199, 199, 199, 199,
199, 199, 199, 199, 199, 199, 199, 199, 199, 199,
199, 199, 199, 199, 199
};
/* n (exponent) prime parameters */
static mat n_p[prime_cnt] = {
2, 3, 5, 7, 13, 17, 19, 31, 61, 89, /* element 0 */
107, 127, 521, 607, 1, 2, 3, 4, 6, 7,
11, 18, 34, 38, 43, 55, 64, 76, 94, 103,
143, 206, 216, 306, 324, 391, 458, 470, 827, 2,
4, 8, 10, 12, 14, 18, 32, 48, 54, 72,
148, 184, 248, 270, 274, 420, 1, 5, 9, 17,
21, 29, 45, 177, 1, 3, 7, 13, 15, 21,
43, 63, 99, 109, 159, 211, 309, 343, 415, 469,
781, 871, 939, 2, 26, 50, 54, 126, 134, 246,
354, 362, 950, 3, 7, 23, 287, 291, 795, 1,
2, 4, 5, 10, 14, 17, 31, 41, 73, 80, /* 100 */
82, 116, 125, 145, 157, 172, 202, 224, 266, 289,
293, 463, 2, 4, 6, 16, 20, 36, 54, 60,
96, 124, 150, 252, 356, 460, 612, 654, 664, 698,
702, 972, 1, 3, 5, 21, 41, 49, 89, 133,
141, 165, 189, 293, 305, 395, 651, 665, 771, 801,
923, 953, 1, 2, 3, 7, 10, 13, 18, 27,
37, 51, 74, 157, 271, 458, 530, 891, 4, 6,
12, 46, 72, 244, 264, 544, 888, 3, 9, 11,
17, 23, 35, 39, 75, 105, 107, 155, 215, 335,
635, 651, 687, 1, 2, 4, 5, 8, 10, 14, /* 200 */
28, 37, 38, 70, 121, 122, 160, 170, 253, 329,
362, 454, 485, 500, 574, 892, 962, 4, 16, 76,
148, 184, 1, 5, 7, 11, 13, 23, 33, 35,
37, 47, 115, 205, 235, 271, 409, 739, 837, 887,
2, 3, 6, 8, 10, 22, 35, 42, 43, 46,
56, 91, 102, 106, 142, 190, 208, 266, 330, 360,
382, 462, 503, 815, 2, 6, 10, 20, 44, 114,
146, 156, 174, 260, 306, 380, 654, 686, 702, 814,
906, 1, 3, 24, 105, 153, 188, 605, 795, 813,
839, 2, 10, 14, 18, 50, 114, 122, 294, 362, /* 300 */
554, 582, 638, 758, 7, 31, 67, 251, 767, 1,
2, 3, 4, 5, 6, 8, 9, 14, 15, 16,
22, 28, 29, 36, 37, 54, 59, 85, 93, 117,
119, 161, 189, 193, 256, 308, 322, 327, 411, 466,
577, 591, 902, 928, 946, 4, 14, 70, 78, 1,
5, 7, 9, 13, 15, 29, 33, 39, 55, 81,
95, 205, 279, 581, 807, 813, 1, 9, 10, 19,
22, 57, 69, 97, 141, 169, 171, 195, 238, 735,
885, 2, 6, 8, 42, 50, 62, 362, 488, 642,
846, 1, 3, 5, 7, 15, 33, 41, 57, 69, /* 400 */
75, 77, 131, 133, 153, 247, 305, 351, 409, 471,
1, 2, 4, 5, 8, 10, 20, 22, 25, 26,
32, 44, 62, 77, 158, 317, 500, 713, 12, 16,
72, 160, 256, 916, 3, 5, 9, 13, 17, 19,
25, 39, 63, 67, 75, 119, 147, 225, 419, 715,
895, 2, 3, 8, 11, 14, 16, 28, 32, 39,
66, 68, 91, 98, 116, 126, 164, 191, 298, 323,
443, 714, 758, 759, 4, 6, 12, 22, 28, 52,
78, 94, 124, 162, 174, 192, 204, 304, 376, 808,
930, 972, 5, 9, 21, 45, 65, 77, 273, 677, /* 500 */
1, 4, 5, 7, 9, 11, 13, 17, 19, 23,
29, 37, 49, 61, 79, 99, 121, 133, 141, 164,
173, 181, 185, 193, 233, 299, 313, 351, 377, 540,
569, 909, 2, 14, 410, 7, 11, 19, 71, 79,
131, 1, 3, 5, 6, 18, 19, 20, 22, 28,
29, 39, 43, 49, 75, 85, 92, 111, 126, 136,
159, 162, 237, 349, 381, 767, 969, 2, 4, 14,
26, 58, 60, 64, 100, 122, 212, 566, 638, 1,
3, 7, 15, 43, 57, 61, 75, 145, 217, 247,
3, 5, 11, 17, 21, 27, 81, 101, 107, 327, /* 600 */
383, 387, 941, 2, 4, 8, 10, 14, 18, 22,
24, 26, 28, 36, 42, 58, 64, 78, 158, 198,
206, 424, 550, 676, 904, 5, 11, 71, 113, 115,
355, 473, 563, 883, 1, 2, 8, 9, 10, 12,
22, 29, 32, 50, 57, 69, 81, 122, 138, 200,
296, 514, 656, 682, 778, 881, 4, 8, 12, 24,
48, 52, 64, 84, 96, 1, 3, 9, 13, 15,
17, 19, 23, 47, 57, 67, 73, 77, 81, 83,
191, 301, 321, 435, 867, 869, 917, 3, 4, 7,
10, 15, 18, 19, 24, 27, 39, 60, 84, 111, /* 700 */
171, 192, 222, 639, 954, 2, 6, 26, 32, 66,
128, 170, 288, 320, 470, 1, 9, 45, 177, 585,
1, 4, 5, 7, 8, 11, 19, 25, 28, 35,
65, 79, 212, 271, 361, 461, 10, 18, 54, 70,
3, 7, 11, 19, 63, 75, 95, 127, 155, 163,
171, 283, 563, 2, 3, 5, 6, 8, 9, 25,
32, 65, 113, 119, 155, 177, 299, 335, 426, 462,
617, 896, 10, 12, 18, 24, 28, 40, 90, 132,
214, 238, 322, 532, 858, 940, 9, 149, 177, 419,
617, 8, 14, 74, 80, 274, 334, 590, 608, 614, /* 800 */
650, 1, 3, 11, 13, 19, 21, 31, 49, 59,
69, 73, 115, 129, 397, 623, 769, 12, 16, 52,
160, 192, 216, 376, 436, 1, 3, 21, 27, 37,
43, 91, 117, 141, 163, 373, 421, 2, 4, 44,
182, 496, 904, 25, 113, 2, 14, 34, 38, 42,
78, 90, 178, 778, 974, 3, 11, 15, 19, 31,
59, 75, 103, 163, 235, 375, 615, 767, 2, 18,
38, 62, 1, 5, 7, 9, 15, 19, 21, 35,
37, 39, 41, 49, 69, 111, 115, 141, 159, 181,
201, 217, 487, 567, 677, 765, 811, 841, 917, 2, /* 900 */
4, 6, 8, 12, 18, 26, 32, 34, 36, 42,
60, 78, 82, 84, 88, 154, 174, 208, 256, 366,
448, 478, 746, 5, 13, 15, 31, 77, 151, 181,
245, 445, 447, 883, 4, 16, 48, 60, 240, 256,
304, 5, 221, 641, 2, 8, 14, 16, 44, 46,
82, 172, 196, 254, 556, 806, 1, 5, 33, 121,
125, 305, 445, 473, 513, 2, 6, 18, 22, 34,
54, 98, 122, 146, 222, 306, 422, 654, 682, 862,
3, 31, 63, 303, 4, 6, 8, 10, 16, 32,
38, 42, 52, 456, 576, 668, 1, 5, 11, 17, /* 1000 */
67, 137, 157, 203, 209, 227, 263, 917, 2, 4,
6, 16, 32, 50, 76, 80, 96, 104, 162, 212,
230, 260, 480, 612, 1, 3, 9, 21, 23, 41,
47, 57, 69, 83, 193, 249, 291, 421, 433, 997,
8, 68, 108, 3, 5, 7, 9, 11, 17, 23,
31, 35, 43, 47, 83, 85, 99, 101, 195, 267,
281, 363, 391, 519, 623, 653, 673, 701, 2, 6,
10, 18, 26, 40, 46, 78, 230, 542, 1, 17,
21, 53, 253, 226, 3, 15, 27, 63, 87, 135,
543, 2, 16, 20, 22, 40, 82, 112, 178, 230, /* 1100 */
302, 304, 328, 374, 442, 472, 500, 580, 694, 1,
5, 7, 15, 19, 23, 25, 27, 43, 65, 99,
125, 141, 165, 201, 211, 331, 369, 389, 445, 461,
463, 467, 513, 583, 835
2, 3, 5, 7, 13, 17, 19, 31, 61, 89, /* element 0 */
107, 127, 521, 607, 1, 2, 3, 4, 6, 7,
11, 18, 34, 38, 43, 55, 64, 76, 94, 103,
143, 206, 216, 306, 324, 391, 458, 470, 827, 2,
4, 8, 10, 12, 14, 18, 32, 48, 54, 72,
148, 184, 248, 270, 274, 420, 1, 5, 9, 17,
21, 29, 45, 177, 1, 3, 7, 13, 15, 21,
43, 63, 99, 109, 159, 211, 309, 343, 415, 469,
781, 871, 939, 2, 26, 50, 54, 126, 134, 246,
354, 362, 950, 3, 7, 23, 287, 291, 795, 1,
2, 4, 5, 10, 14, 17, 31, 41, 73, 80, /* 100 */
82, 116, 125, 145, 157, 172, 202, 224, 266, 289,
293, 463, 2, 4, 6, 16, 20, 36, 54, 60,
96, 124, 150, 252, 356, 460, 612, 654, 664, 698,
702, 972, 1, 3, 5, 21, 41, 49, 89, 133,
141, 165, 189, 293, 305, 395, 651, 665, 771, 801,
923, 953, 1, 2, 3, 7, 10, 13, 18, 27,
37, 51, 74, 157, 271, 458, 530, 891, 4, 6,
12, 46, 72, 244, 264, 544, 888, 3, 9, 11,
17, 23, 35, 39, 75, 105, 107, 155, 215, 335,
635, 651, 687, 1, 2, 4, 5, 8, 10, 14, /* 200 */
28, 37, 38, 70, 121, 122, 160, 170, 253, 329,
362, 454, 485, 500, 574, 892, 962, 4, 16, 76,
148, 184, 1, 5, 7, 11, 13, 23, 33, 35,
37, 47, 115, 205, 235, 271, 409, 739, 837, 887,
2, 3, 6, 8, 10, 22, 35, 42, 43, 46,
56, 91, 102, 106, 142, 190, 208, 266, 330, 360,
382, 462, 503, 815, 2, 6, 10, 20, 44, 114,
146, 156, 174, 260, 306, 380, 654, 686, 702, 814,
906, 1, 3, 24, 105, 153, 188, 605, 795, 813,
839, 2, 10, 14, 18, 50, 114, 122, 294, 362, /* 300 */
554, 582, 638, 758, 7, 31, 67, 251, 767, 1,
2, 3, 4, 5, 6, 8, 9, 14, 15, 16,
22, 28, 29, 36, 37, 54, 59, 85, 93, 117,
119, 161, 189, 193, 256, 308, 322, 327, 411, 466,
577, 591, 902, 928, 946, 4, 14, 70, 78, 1,
5, 7, 9, 13, 15, 29, 33, 39, 55, 81,
95, 205, 279, 581, 807, 813, 1, 9, 10, 19,
22, 57, 69, 97, 141, 169, 171, 195, 238, 735,
885, 2, 6, 8, 42, 50, 62, 362, 488, 642,
846, 1, 3, 5, 7, 15, 33, 41, 57, 69, /* 400 */
75, 77, 131, 133, 153, 247, 305, 351, 409, 471,
1, 2, 4, 5, 8, 10, 20, 22, 25, 26,
32, 44, 62, 77, 158, 317, 500, 713, 12, 16,
72, 160, 256, 916, 3, 5, 9, 13, 17, 19,
25, 39, 63, 67, 75, 119, 147, 225, 419, 715,
895, 2, 3, 8, 11, 14, 16, 28, 32, 39,
66, 68, 91, 98, 116, 126, 164, 191, 298, 323,
443, 714, 758, 759, 4, 6, 12, 22, 28, 52,
78, 94, 124, 162, 174, 192, 204, 304, 376, 808,
930, 972, 5, 9, 21, 45, 65, 77, 273, 677, /* 500 */
1, 4, 5, 7, 9, 11, 13, 17, 19, 23,
29, 37, 49, 61, 79, 99, 121, 133, 141, 164,
173, 181, 185, 193, 233, 299, 313, 351, 377, 540,
569, 909, 2, 14, 410, 7, 11, 19, 71, 79,
131, 1, 3, 5, 6, 18, 19, 20, 22, 28,
29, 39, 43, 49, 75, 85, 92, 111, 126, 136,
159, 162, 237, 349, 381, 767, 969, 2, 4, 14,
26, 58, 60, 64, 100, 122, 212, 566, 638, 1,
3, 7, 15, 43, 57, 61, 75, 145, 217, 247,
3, 5, 11, 17, 21, 27, 81, 101, 107, 327, /* 600 */
383, 387, 941, 2, 4, 8, 10, 14, 18, 22,
24, 26, 28, 36, 42, 58, 64, 78, 158, 198,
206, 424, 550, 676, 904, 5, 11, 71, 113, 115,
355, 473, 563, 883, 1, 2, 8, 9, 10, 12,
22, 29, 32, 50, 57, 69, 81, 122, 138, 200,
296, 514, 656, 682, 778, 881, 4, 8, 12, 24,
48, 52, 64, 84, 96, 1, 3, 9, 13, 15,
17, 19, 23, 47, 57, 67, 73, 77, 81, 83,
191, 301, 321, 435, 867, 869, 917, 3, 4, 7,
10, 15, 18, 19, 24, 27, 39, 60, 84, 111, /* 700 */
171, 192, 222, 639, 954, 2, 6, 26, 32, 66,
128, 170, 288, 320, 470, 1, 9, 45, 177, 585,
1, 4, 5, 7, 8, 11, 19, 25, 28, 35,
65, 79, 212, 271, 361, 461, 10, 18, 54, 70,
3, 7, 11, 19, 63, 75, 95, 127, 155, 163,
171, 283, 563, 2, 3, 5, 6, 8, 9, 25,
32, 65, 113, 119, 155, 177, 299, 335, 426, 462,
617, 896, 10, 12, 18, 24, 28, 40, 90, 132,
214, 238, 322, 532, 858, 940, 9, 149, 177, 419,
617, 8, 14, 74, 80, 274, 334, 590, 608, 614, /* 800 */
650, 1, 3, 11, 13, 19, 21, 31, 49, 59,
69, 73, 115, 129, 397, 623, 769, 12, 16, 52,
160, 192, 216, 376, 436, 1, 3, 21, 27, 37,
43, 91, 117, 141, 163, 373, 421, 2, 4, 44,
182, 496, 904, 25, 113, 2, 14, 34, 38, 42,
78, 90, 178, 778, 974, 3, 11, 15, 19, 31,
59, 75, 103, 163, 235, 375, 615, 767, 2, 18,
38, 62, 1, 5, 7, 9, 15, 19, 21, 35,
37, 39, 41, 49, 69, 111, 115, 141, 159, 181,
201, 217, 487, 567, 677, 765, 811, 841, 917, 2, /* 900 */
4, 6, 8, 12, 18, 26, 32, 34, 36, 42,
60, 78, 82, 84, 88, 154, 174, 208, 256, 366,
448, 478, 746, 5, 13, 15, 31, 77, 151, 181,
245, 445, 447, 883, 4, 16, 48, 60, 240, 256,
304, 5, 221, 641, 2, 8, 14, 16, 44, 46,
82, 172, 196, 254, 556, 806, 1, 5, 33, 121,
125, 305, 445, 473, 513, 2, 6, 18, 22, 34,
54, 98, 122, 146, 222, 306, 422, 654, 682, 862,
3, 31, 63, 303, 4, 6, 8, 10, 16, 32,
38, 42, 52, 456, 576, 668, 1, 5, 11, 17, /* 1000 */
67, 137, 157, 203, 209, 227, 263, 917, 2, 4,
6, 16, 32, 50, 76, 80, 96, 104, 162, 212,
230, 260, 480, 612, 1, 3, 9, 21, 23, 41,
47, 57, 69, 83, 193, 249, 291, 421, 433, 997,
8, 68, 108, 3, 5, 7, 9, 11, 17, 23,
31, 35, 43, 47, 83, 85, 99, 101, 195, 267,
281, 363, 391, 519, 623, 653, 673, 701, 2, 6,
10, 18, 26, 40, 46, 78, 230, 542, 1, 17,
21, 53, 253, 226, 3, 15, 27, 63, 87, 135,
543, 2, 16, 20, 22, 40, 82, 112, 178, 230, /* 1100 */
302, 304, 328, 374, 442, 472, 500, 580, 694, 1,
5, 7, 15, 19, 23, 25, 27, 43, 65, 99,
125, 141, 165, 201, 211, 331, 369, 389, 445, 461,
463, 467, 513, 583, 835
};
@@ -299,82 +299,82 @@ read -once "lucas.cal";
* when n_p is below a given limit.
*
* input:
* high_n skip tests on n_p[i] > high_n
* [quiet] if given and != 0, then do not print individual test results
* high_n skip tests on n_p[i] > high_n
* [quiet] if given and != 0, then do not print individual test results
*
* returns:
* 1 all is OK
* 0 something went wrong
* 1 all is OK
* 0 something went wrong
*/
define
lucas_chk(high_n, quiet)
{
local i; /* index */
local result; /* 0 => non-prime, 1 => prime, -1 => bad test */
local error; /* number of errors and bad tests found */
local i; /* index */
local result; /* 0 => non-prime, 1 => prime, -1 => bad test */
local error; /* number of errors and bad tests found */
/*
* firewall
*/
if (!isint(high_n)) {
ldebug("test_lucas", "high_n is non-int");
quit "FATAL: bad args: high_n must be an integer";
}
if (param(0) == 1) {
quiet = 0;
}
/*
* firewall
*/
if (!isint(high_n)) {
ldebug("test_lucas", "high_n is non-int");
quit "FATAL: bad args: high_n must be an integer";
}
if (param(0) == 1) {
quiet = 0;
}
/*
* scan thru the above prime table
*/
error = 0;
for (i=0; i < prime_cnt; ++i) {
/*
* scan thru the above prime table
*/
error = 0;
for (i=0; i < prime_cnt; ++i) {
/* skip primes where h>=2^n */
if (highbit(h_p[i]) >= n_p[i]) {
if (config("resource_debug") & 8) {
print "h>=2^n skip:", h_p[i]:"*2^":n_p[i]:"-1";
}
continue;
}
/* skip primes where h>=2^n */
if (highbit(h_p[i]) >= n_p[i]) {
if (config("resource_debug") & 8) {
print "h>=2^n skip:", h_p[i]:"*2^":n_p[i]:"-1";
}
continue;
}
/* test the prime if it is small enough */
if (n_p[i] <= high_n) {
/* test the prime if it is small enough */
if (n_p[i] <= high_n) {
/* test the table value */
result = lucas(h_p[i], n_p[i]);
/* test the table value */
result = lucas(h_p[i], n_p[i]);
/* report the test */
if (result == 0) {
print "ERROR, bad primality test of",\
h_p[i]:"*2^":n_p[i]:"-1";
++error;
} else if (result == 1) {
if (quiet == 0) {
print h_p[i]:"*2^":n_p[i]:"-1 is prime";
}
} else if (result == -1) {
print "ERROR, failed to compute v(1) for",\
h_p[i]:"*2^":n_p[i]:"-1";
++error;
} else {
print "ERROR, bogus return value:", result;
++error;
}
}
}
/* report the test */
if (result == 0) {
print "ERROR, bad primality test of",\
h_p[i]:"*2^":n_p[i]:"-1";
++error;
} else if (result == 1) {
if (quiet == 0) {
print h_p[i]:"*2^":n_p[i]:"-1 is prime";
}
} else if (result == -1) {
print "ERROR, failed to compute v(1) for",\
h_p[i]:"*2^":n_p[i]:"-1";
++error;
} else {
print "ERROR, bogus return value:", result;
++error;
}
}
}
/* return the full status */
if (error == 0) {
if (quiet == 0) {
print "lucas_chk(":high_n:") passed";
}
return 1;
} else if (error == 1) {
print "lucas_chk(":high_n:") failed", error, "test";
return 0;
} else {
print "lucas_chk(":high_n:") failed", error, "tests";
return 0;
}
/* return the full status */
if (error == 0) {
if (quiet == 0) {
print "lucas_chk(":high_n:") passed";
}
return 1;
} else if (error == 1) {
print "lucas_chk(":high_n:") failed", error, "test";
return 0;
} else {
print "lucas_chk(":high_n:") failed", error, "tests";
return 0;
}
}

View File

@@ -11,7 +11,7 @@
*
* 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
* 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
@@ -19,10 +19,10 @@
* 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: 1991/05/22 21:56:36
* File existed as early as: 1991
* Under source code control: 1991/05/22 21:56:36
* File existed as early as: 1991
*
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
/*
@@ -32,26 +32,26 @@
define mersenne(p)
{
local u, i, p_mask;
local u, i, p_mask;
/* firewall */
if (! isint(p))
quit "p is not an integer";
/* firewall */
if (! isint(p))
quit "p is not an integer";
/* two is a special case */
if (p == 2)
return 1;
/* two is a special case */
if (p == 2)
return 1;
/* if p is not prime, then 2^p-1 is not prime */
if (! ptest(p,1))
return 0;
/* if p is not prime, then 2^p-1 is not prime */
if (! ptest(p,1))
return 0;
/* lltest: u(i+1) = u(i)^2 - 2 mod 2^p-1 */
u = 4;
for (i = 2; i < p; ++i) {
u = hnrmod(u^2 - 2, 1, p, -1);
}
/* lltest: u(i+1) = u(i)^2 - 2 mod 2^p-1 */
u = 4;
for (i = 2; i < p; ++i) {
u = hnrmod(u^2 - 2, 1, p, -1);
}
/* 2^p-1 is prime iff u(p) = 0 mod 2^p-1 */
return (u == 0);
/* 2^p-1 is prime iff u(p) = 0 mod 2^p-1 */
return (u == 0);
}

View File

@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,11 +17,11 @@
* 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: 1996/07/06 06:09:40
* File existed as early as: 1996
* Under source code control: 1996/07/06 06:09:40
* File existed as early as: 1996
*
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
/*
@@ -29,12 +29,12 @@
*
* We will assume that mfactor is called with p_elim == 17.
*
* n = (the Mersenne exponent we are testing)
* Q = 4*2*3*5*7*11*13*17 (4 * pfact(of some reasonable integer))
* n = (the Mersenne exponent we are testing)
* Q = 4*2*3*5*7*11*13*17 (4 * pfact(of some reasonable integer))
*
* We first determine all values of h mod Q such that:
*
* gcd(h*n+1, Q) == 1 and h*n+1 == +/-1 mod 8
* gcd(h*n+1, Q) == 1 and h*n+1 == +/-1 mod 8
*
* There will be 2*1*2*4*6*10*12*16 such values of h.
*
@@ -45,59 +45,59 @@
*
* We need only test factors of the form:
*
* (Q*g*n + hx) + 1
* (Q*g*n + hx) + 1
*
* where:
*
* g is an integer >= 0
* hx is computed from hset[] difference value described above
* g is an integer >= 0
* hx is computed from hset[] difference value described above
*
* Note that (Q*g*n + hx) is always even and that hx is a multiple
* of n. Thus the typical factor form:
*
* 2*k*n + 1
* 2*k*n + 1
*
* implies that:
*
* k = (Q*g + hx/n)/2
* k = (Q*g + hx/n)/2
*
* This allows us to quickly eliminate factor values that are divisible
* by 2, 3, 5, 7, 11, 13 or 17. (well <= p value found below)
* by 2, 3, 5, 7, 11, 13 or 17. (well <= p value found below)
*
* The following loop shows how test_factor is advanced to higher test
* values using hset[]. Here, hcount is the number of elements in hset[].
* values using hset[]. Here, hcount is the number of elements in hset[].
* It can be shown that hset[0] == 0. We add hset[hcount] to the hset[]
* array for looping control convenience.
*
* (* increase test_factor thru other possible test values *)
* test_factor = 0;
* hindx = 0;
* do {
* while (++hindx <= hcount) {
* test_factor += hset[hindx];
* }
* hindx = 0;
* } while (test_factor < some_limit);
* (* increase test_factor thru other possible test values *)
* test_factor = 0;
* hindx = 0;
* do {
* while (++hindx <= hcount) {
* test_factor += hset[hindx];
* }
* hindx = 0;
* } while (test_factor < some_limit);
*
* The test, mfactor(67, 1, 10000) took on an 200 MHz r4k (user CPU seconds):
*
* 210.83 (prior to use of hset[])
* 78.35 (hset[] for p_elim = 7)
* 73.87 (hset[] for p_elim = 11)
* 73.92 (hset[] for p_elim = 13)
* 234.16 (hset[] for p_elim = 17)
* p_elim == 19 requires over 190 Megs of memory
* 210.83 (prior to use of hset[])
* 78.35 (hset[] for p_elim = 7)
* 73.87 (hset[] for p_elim = 11)
* 73.92 (hset[] for p_elim = 13)
* 234.16 (hset[] for p_elim = 17)
* p_elim == 19 requires over 190 Megs of memory
*
* Over a long period of time, the call to load_hset() becomes insignificant.
* If we look at the user CPU seconds from the first 10000 cycle to the
* end of the test we find:
*
* 205.00 (prior to use of hset[])
* 75.89 (hset[] for p_elim = 7)
* 73.74 (hset[] for p_elim = 11)
* 70.61 (hset[] for p_elim = 13)
* 57.78 (hset[] for p_elim = 17)
* p_elim == 19 rejected because of memory size
* 205.00 (prior to use of hset[])
* 75.89 (hset[] for p_elim = 7)
* 73.74 (hset[] for p_elim = 11)
* 70.61 (hset[] for p_elim = 13)
* 57.78 (hset[] for p_elim = 17)
* p_elim == 19 rejected because of memory size
*
* The p_elim == 17 overhead takes ~3 minutes on an 200 MHz r4k CPU and
* requires about ~13 Megs of memory. The p_elim == 13 overhead
@@ -108,8 +108,8 @@
* for p_elim == 13.
*
* NOTE: The values above are prior to optimizations where hset[] was
* multiplied by n plus other optimizations. Thus, the CPU
* times you may get will not likely match the above values.
* multiplied by n plus other optimizations. Thus, the CPU
* times you may get will not likely match the above values.
*/
@@ -118,198 +118,198 @@
*
* Mersenne numbers are numbers of the form:
*
* 2^n-1 for integer n > 0
* 2^n-1 for integer n > 0
*
* We know that factors of a Mersenne number are of the form:
*
* 2*k*n+1 and +/- 1 mod 8
* 2*k*n+1 and +/- 1 mod 8
*
* We make use of the hset[] difference array to eliminate factor
* candidates that would otherwise be divisible by 2, 3, 5, 7 ... p_elim.
*
* given:
* n attempt to factor M(n) = 2^n-1
* start_k the value k in 2*k*n+1 to start the search (def: 1)
* rept_loop loop cycle reporting (def: 10000)
* p_elim largest prime to eliminate from test factors (def: 17)
* n attempt to factor M(n) = 2^n-1
* start_k the value k in 2*k*n+1 to start the search (def: 1)
* rept_loop loop cycle reporting (def: 10000)
* p_elim largest prime to eliminate from test factors (def: 17)
*
* returns:
* factor of (2^n)-1
* factor of (2^n)-1
*
* NOTE: The p_elim argument is optional and defaults to 17. A p_elim value
* of 17 is faster than 13 for even medium length runs. However 13
* uses less memory and has a shorter startup time.
* of 17 is faster than 13 for even medium length runs. However 13
* uses less memory and has a shorter startup time.
*/
define mfactor(n, start_k, rept_loop, p_elim)
{
local Q; /* 4*pfact(p_elim), hset[] cycle size */
local hcount; /* elements in the hset[] difference array */
local loop; /* report loop count */
local q; /* test factor of 2^n-1 */
local g; /* g as in test candidate form: (Q*g*hset[i])*n + 1 */
local hindx; /* hset[] index */
local i;
local tmp;
local tmp2;
local Q; /* 4*pfact(p_elim), hset[] cycle size */
local hcount; /* elements in the hset[] difference array */
local loop; /* report loop count */
local q; /* test factor of 2^n-1 */
local g; /* g as in test candidate form: (Q*g*hset[i])*n + 1 */
local hindx; /* hset[] index */
local i;
local tmp;
local tmp2;
/*
* firewall
*/
if (!isint(n) || n <= 0) {
quit "n must be an integer > 0";
}
if (!isint(start_k)) {
start_k = 1;
} else if (!isint(start_k) || start_k <= 0) {
quit "start_k must be an integer > 0";
}
if (!isint(rept_loop)) {
rept_loop = 10000;
}
if (rept_loop < 1) {
quit "rept_loop must be an integer > 0";
}
if (!isint(p_elim)) {
p_elim = 17;
}
if (p_elim < 3) {
quit "p_elim must be an integer > 2 (try 13 or 17)";
}
/*
* firewall
*/
if (!isint(n) || n <= 0) {
quit "n must be an integer > 0";
}
if (!isint(start_k)) {
start_k = 1;
} else if (!isint(start_k) || start_k <= 0) {
quit "start_k must be an integer > 0";
}
if (!isint(rept_loop)) {
rept_loop = 10000;
}
if (rept_loop < 1) {
quit "rept_loop must be an integer > 0";
}
if (!isint(p_elim)) {
p_elim = 17;
}
if (p_elim < 3) {
quit "p_elim must be an integer > 2 (try 13 or 17)";
}
/*
* declare our global values
*/
Q = 4*pfact(p_elim);
hcount = 2;
/* allocate the h difference array */
for (i=2; i <= p_elim; i = nextcand(i)) {
hcount *= (i-1);
}
local mat hset[hcount+1];
/*
* declare our global values
*/
Q = 4*pfact(p_elim);
hcount = 2;
/* allocate the h difference array */
for (i=2; i <= p_elim; i = nextcand(i)) {
hcount *= (i-1);
}
local mat hset[hcount+1];
/*
* load the hset[] difference array
*/
{
local x; /* h*n+1 mod 8 */
local h; /* potential h value */
local last_h; /* previous valid h value */
/*
* load the hset[] difference array
*/
{
local x; /* h*n+1 mod 8 */
local h; /* potential h value */
local last_h; /* previous valid h value */
last_h = 0;
for (i=0,h=0; h < Q; ++h) {
if (gcd(h*n+1,Q) == 1) {
x = (h*n+1) % 8;
if (x == 1 || x == 7) {
hset[i++] = (h-last_h) * n;
last_h = h;
}
}
}
hset[hcount] = Q*n - last_h*n;
}
last_h = 0;
for (i=0,h=0; h < Q; ++h) {
if (gcd(h*n+1,Q) == 1) {
x = (h*n+1) % 8;
if (x == 1 || x == 7) {
hset[i++] = (h-last_h) * n;
last_h = h;
}
}
}
hset[hcount] = Q*n - last_h*n;
}
/*
* setup
*
* determine the next g and hset[] index (hindx) values such that:
*
* 2*start_k <= (Q*g + hset[hindx])
*
* and (Q*g + hset[hindx]) is a minimum and where:
*
* Q = (4 * pfact(of some reasonable integer))
* g = (some integer) (hset[] cycle number)
*
* We also compute 'q', the next test candidate.
*/
g = (2*start_k) // Q;
tmp = 2*start_k - Q*g;
for (tmp2=0, hindx=0;
hindx < hcount && (tmp2 += hset[hindx]/n) < tmp;
++hindx) {
}
if (hindx == hcount) {
/* we are beyond the end of a hset[] cycle, start at the next */
++g;
hindx = 0;
tmp2 = hset[0]/n;
}
q = (Q*g + tmp2)*n + 1;
/*
* setup
*
* determine the next g and hset[] index (hindx) values such that:
*
* 2*start_k <= (Q*g + hset[hindx])
*
* and (Q*g + hset[hindx]) is a minimum and where:
*
* Q = (4 * pfact(of some reasonable integer))
* g = (some integer) (hset[] cycle number)
*
* We also compute 'q', the next test candidate.
*/
g = (2*start_k) // Q;
tmp = 2*start_k - Q*g;
for (tmp2=0, hindx=0;
hindx < hcount && (tmp2 += hset[hindx]/n) < tmp;
++hindx) {
}
if (hindx == hcount) {
/* we are beyond the end of a hset[] cycle, start at the next */
++g;
hindx = 0;
tmp2 = hset[0]/n;
}
q = (Q*g + tmp2)*n + 1;
/*
* look for a factor
*
* We ignore factors that themselves are divisible by a prime <=
* some small prime p.
*
* This process is guaranteed to find the smallest factor
* of 2^n-1. A smallest factor of 2^n-1 must be prime, otherwise
* the divisors of that factor would also be factors of 2^n-1.
* Thus we know that if a test factor itself is not prime, it
* cannot be the smallest factor of 2^n-1.
*
* Eliminating all non-prime test factors would take too long.
* However we can eliminate 80.81% of the test factors
* by not using test factors that are divisible by a prime <= 17.
*/
if (pmod(2,n,q) == 1) {
return q;
} else {
/* report this loop */
printf("at 2*%d*%d+1, CPU: %f\n",
(q-1)/(2*n), n, usertime());
fflush(files(1));
loop = 0;
}
do {
/*
* determine if we need to report
*
* NOTE: (q-1)/(2*n) is the k value from 2*k*n + 1.
*/
if (rept_loop <= ++loop) {
/* report this loop */
printf("at 2*%d*%d+1, CPU: %f\n",
(q-1)/(2*n), n, usertime());
fflush(files(1));
loop = 0;
}
/*
* look for a factor
*
* We ignore factors that themselves are divisible by a prime <=
* some small prime p.
*
* This process is guaranteed to find the smallest factor
* of 2^n-1. A smallest factor of 2^n-1 must be prime, otherwise
* the divisors of that factor would also be factors of 2^n-1.
* Thus we know that if a test factor itself is not prime, it
* cannot be the smallest factor of 2^n-1.
*
* Eliminating all non-prime test factors would take too long.
* However we can eliminate 80.81% of the test factors
* by not using test factors that are divisible by a prime <= 17.
*/
if (pmod(2,n,q) == 1) {
return q;
} else {
/* report this loop */
printf("at 2*%d*%d+1, CPU: %f\n",
(q-1)/(2*n), n, usertime());
fflush(files(1));
loop = 0;
}
do {
/*
* determine if we need to report
*
* NOTE: (q-1)/(2*n) is the k value from 2*k*n + 1.
*/
if (rept_loop <= ++loop) {
/* report this loop */
printf("at 2*%d*%d+1, CPU: %f\n",
(q-1)/(2*n), n, usertime());
fflush(files(1));
loop = 0;
}
/*
* skip if divisible by a prime <= 449
*
* The value 281 was determined by timing loops
* which found that 281 was at or near the
* minimum time to factor 2^(2^127-1)-1.
*
* The addition of the do { ... } while (factor(q, 449)>1);
* loop reduced the factoring loop time (36504 k values with
* the hset[] initialization time removed) from 25.69 sec to
* 15.62 sec of CPU time on a 200MHz r4k.
*/
do {
/*
* determine the next factor candidate
*/
q += hset[++hindx];
if (hindx >= hcount) {
hindx = 0;
/*
* if we cared about g,
* then we wound ++g here too
*/
}
} while (factor(q, 449) > 1);
} while (pmod(2,n,q) != 1);
/*
* skip if divisible by a prime <= 449
*
* The value 281 was determined by timing loops
* which found that 281 was at or near the
* minimum time to factor 2^(2^127-1)-1.
*
* The addition of the do { ... } while (factor(q, 449)>1);
* loop reduced the factoring loop time (36504 k values with
* the hset[] initialization time removed) from 25.69 sec to
* 15.62 sec of CPU time on a 200MHz r4k.
*/
do {
/*
* determine the next factor candidate
*/
q += hset[++hindx];
if (hindx >= hcount) {
hindx = 0;
/*
* if we cared about g,
* then we wound ++g here too
*/
}
} while (factor(q, 449) > 1);
} while (pmod(2,n,q) != 1);
/*
* return the factor found
*
* q is a factor of (2^n)-1
*/
return q;
/*
* return the factor found
*
* q is a factor of (2^n)-1
*/
return q;
}
if (config("resource_debug") & 3) {
print "mfactor(n [, start_k=1 [, rept_loop=10000 [, p_elim=17]]])"
print "mfactor(n [, start_k=1 [, rept_loop=10000 [, p_elim=17]]])"
}

View File

@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,192 +17,192 @@
* 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: 1990/02/15 01:50:34
* File existed as early as: before 1990
* Under source code control: 1990/02/15 01:50:34
* File existed as early as: before 1990
*
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
obj mod {a}; /* definition of the object */
obj mod {a}; /* definition of the object */
global mod_value = 100; /* modulus value (value of N) */
global mod_value = 100; /* modulus value (value of N) */
define lmod(a)
{
local obj mod x;
local obj mod x;
if (!isreal(a) || !isint(a))
quit "Bad argument for lmod function";
x.a = a % mod_value;
return x;
if (!isreal(a) || !isint(a))
quit "Bad argument for lmod function";
x.a = a % mod_value;
return x;
}
define mod_print(a)
{
if (digits(mod_value) <= 20)
print a.a, "(mod", mod_value : ")" :;
else
print a.a, "(mod N)" :;
if (digits(mod_value) <= 20)
print a.a, "(mod", mod_value : ")" :;
else
print a.a, "(mod N)" :;
}
define mod_one()
{
return lmod(1);
return lmod(1);
}
define mod_cmp(a, b)
{
if (isnum(a))
return (a % mod_value) != b.a;
if (isnum(b))
return (b % mod_value) != a.a;
return a.a != b.a;
if (isnum(a))
return (a % mod_value) != b.a;
if (isnum(b))
return (b % mod_value) != a.a;
return a.a != b.a;
}
define mod_rel(a, b)
{
if (isnum(a))
a = lmod(a);
if (isnum(b))
b = lmod(b);
if (a.a < b.a)
return -1;
return a.a != b.a;
if (isnum(a))
a = lmod(a);
if (isnum(b))
b = lmod(b);
if (a.a < b.a)
return -1;
return a.a != b.a;
}
define mod_add(a, b)
{
local obj mod x;
local obj mod x;
if (isnum(b)) {
if (!isint(b))
quit "Adding non-integer";
x.a = (a.a + b) % mod_value;
return x;
}
if (isnum(a)) {
if (!isint(a))
quit "Adding non-integer";
x.a = (a + b.a) % mod_value;
return x;
}
x.a = (a.a + b.a) % mod_value;
return x;
if (isnum(b)) {
if (!isint(b))
quit "Adding non-integer";
x.a = (a.a + b) % mod_value;
return x;
}
if (isnum(a)) {
if (!isint(a))
quit "Adding non-integer";
x.a = (a + b.a) % mod_value;
return x;
}
x.a = (a.a + b.a) % mod_value;
return x;
}
define mod_sub(a, b)
{
return a + (-b);
return a + (-b);
}
define mod_neg(a)
{
local obj mod x;
local obj mod x;
x.a = mod_value - a.a;
return x;
x.a = mod_value - a.a;
return x;
}
define mod_mul(a, b)
{
local obj mod x;
local obj mod x;
if (isnum(b)) {
if (!isint(b))
quit "Multiplying by non-integer";
x.a = (a.a * b) % mod_value;
return x;
}
if (isnum(a)) {
if (!isint(a))
quit "Multiplying by non-integer";
x.a = (a * b.a) % mod_value;
return x;
}
x.a = (a.a * b.a) % mod_value;
return x;
if (isnum(b)) {
if (!isint(b))
quit "Multiplying by non-integer";
x.a = (a.a * b) % mod_value;
return x;
}
if (isnum(a)) {
if (!isint(a))
quit "Multiplying by non-integer";
x.a = (a * b.a) % mod_value;
return x;
}
x.a = (a.a * b.a) % mod_value;
return x;
}
define mod_square(a)
{
local obj mod x;
local obj mod x;
x.a = a.a^2 % mod_value;
return x;
x.a = a.a^2 % mod_value;
return x;
}
define mod_inc(a)
{
local x;
local x;
x = a;
if (++x.a == mod_value)
x.a = 0;
return x;
x = a;
if (++x.a == mod_value)
x.a = 0;
return x;
}
define mod_dec(a)
{
local x;
local x;
x = a;
if (--x.a < 0)
x.a = mod_value - 1;
return x;
x = a;
if (--x.a < 0)
x.a = mod_value - 1;
return x;
}
define mod_inv(a)
{
local obj mod x;
local obj mod x;
x.a = minv(a.a, mod_value);
return x;
x.a = minv(a.a, mod_value);
return x;
}
define mod_div(a, b)
{
local c;
local obj mod x;
local obj mod y;
if (isnum(a))
a = lmod(a);
if (isnum(b))
b = lmod(b);
c = gcd(a.a, b.a);
x.a = a.a / c;
y.a = b.a / c;
return x * inverse(y);
local c;
local obj mod x;
local obj mod y;
if (isnum(a))
a = lmod(a);
if (isnum(b))
b = lmod(b);
c = gcd(a.a, b.a);
x.a = a.a / c;
y.a = b.a / c;
return x * inverse(y);
}
define mod_pow(a, b)
{
local x, y, z;
local x, y, z;
obj mod x;
y = a;
z = b;
if (b < 0) {
y = inverse(a);
z = -b;
}
x.a = pmod(y.a, z, mod_value);
return x;
obj mod x;
y = a;
z = b;
if (b < 0) {
y = inverse(a);
z = -b;
}
x.a = pmod(y.a, z, mod_value);
return x;
}

View File

@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,10 +17,10 @@
* 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: 1997/09/07 23:53:51
* File existed as early as: 1997
* Under source code control: 1997/09/07 23:53:51
* File existed as early as: 1997
*
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
/*
@@ -40,14 +40,14 @@
*
* In an assignment of a set-valued lvalue to an lvalue, as in
*
* A = set(1,2,3);
* B = A;
* A = set(1,2,3);
* B = A;
*
* the sets share the same data string, so a change to either has the effect
* of changing both. A set equal to A but with a different string can be
* created by
*
* B = A | set()
* B = A | set()
*
* The functions empty() and full() return the empty set and the set of all
* integers in [0,B] respectively.
@@ -57,58 +57,58 @@
* test(A) returns 0 or 1 according as A is or is not the empty set
*
* isin(A, n) for set A and integer n returns 1 if n is in A, 0 if
* 0 <= n <= B and n is not in A, the null value if n < 0 or n > B.
* 0 <= n <= B and n is not in A, the null value if n < 0 or n > B.
*
* addmember(A, n) adds n as a member of A, provided n is in [0, B];
* this is also achieved by A |= n.
* this is also achieved by A |= n.
*
* rmmember(A, n) removes n from A if it is a member; this is also achieved
* by A \= n.
* by A \= n.
*
* The following unary and binary operations are defined for sets A, B.
* For binary operations with one argument a set and the other an
* integer n, the integer taken to represent set(n).
* For binary operations with one argument a set and the other an
* integer n, the integer taken to represent set(n).
*
* A | B = union of A and B, integers in at least one of A and B
* A & B = intersection of A and B, integers in both A and B
* A ~ B = symmetric difference (boolean sum) of A and Bi, integers
* in exactly one of A and B
* A \ B = set difference, integers in A but not in B
* A | B = union of A and B, integers in at least one of A and B
* A & B = intersection of A and B, integers in both A and B
* A ~ B = symmetric difference (boolean sum) of A and Bi, integers
* in exactly one of A and B
* A \ B = set difference, integers in A but not in B
*
* ~A = complement of A, integers not in A
* #A = number of integers in A
* !A = 1 or 0 according as A is empty or not empty
* +A = sum of the members of A
* ~A = complement of A, integers not in A
* #A = number of integers in A
* !A = 1 or 0 according as A is empty or not empty
* +A = sum of the members of A
*
* min(A) = least member of A, -1 for empty set
* max(A) = greatest member of A, -1 for empty set
* sum(A) = sum of the members of A
* min(A) = least member of A, -1 for empty set
* max(A) = greatest member of A, -1 for empty set
* sum(A) = sum of the members of A
*
* In the following a and b denote arbitrary members of A and B:
*
* A + B = set of sums a + b
* A - B = set of differences a - b
* A * B = set of products a * b
* A ^ n = set of powers a ^ n
* A % m = set of integers congruent to a mod m
* A + B = set of sums a + b
* A - B = set of differences a - b
* A * B = set of products a * b
* A ^ n = set of powers a ^ n
* A % m = set of integers congruent to a mod m
*
* A == B returns 1 or not according as A and B are equal or not
* A != B = !(A == B)
* A <= B returns 1 if A is a subset of B, i.e. every member of A is
* a member of B
* A < B = ((A <= B) && (A != B))
* A >= B = (B <= A)
* A > B = (B < A)
* A == B returns 1 or not according as A and B are equal or not
* A != B = !(A == B)
* A <= B returns 1 if A is a subset of B, i.e. every member of A is
* a member of B
* A < B = ((A <= B) && (A != B))
* A >= B = (B <= A)
* A > B = (B < A)
*
* Expressions may be formed from the above "arithmetic" operations in
* the usual way, with parentheses for variations from the usual precedence
* rules. For example
*
* A + 3 * A ^ 2 + (A - B) ^ 3
* A + 3 * A ^ 2 + (A - B) ^ 3
*
* returns the set of integers expressible as
*
* a_1 + 3 * a_2 ^ 2 + (a_3 - b) ^3
* a_1 + 3 * a_2 ^ 2 + (a_3 - b) ^3
*
* where a_1, a_2, a_3 are in A, and b is in B.
*
@@ -119,28 +119,28 @@
* isinterval(A) returns 1 if A is a non-empty interval, 0 otherwise.
*
* randset(n, a, b) returns a random set of n integers between a and b
* inclusive; a defaults to 0, b to N-1. An error occurs if
* n is too large.
* inclusive; a defaults to 0, b to N-1. An error occurs if
* n is too large.
*
* polyvals(L, A) for L = list(c_0, c_1, c_2, ...) returns the set of
* values of
*
* c_0 + c_1 * a + c_2 * a^2 + ...
* c_0 + c_1 * a + c_2 * a^2 + ...
*
* for a in the set A.
*
* polyvals2(L, A, B) returns the set of values of poly(L, i, j) for i in
* A and j in B. Here L is a list whose members are integers or
* lists of integers, the latter representing polynomials in the
* second variable. For example, with L = list(0, list(0, 1), 1),
* polyvals2(L, A, B) will return the values of i^2 + i * j for
* i in A, j in B.
* A and j in B. Here L is a list whose members are integers or
* lists of integers, the latter representing polynomials in the
* second variable. For example, with L = list(0, list(0, 1), 1),
* polyvals2(L, A, B) will return the values of i^2 + i * j for
* i in A, j in B.
*
*/
static N; /* Number of integers in [0,B], = B + 1 */
static M; /* Maximum string size required, = N // 8 */
static N; /* Number of integers in [0,B], = B + 1 */
static M; /* Maximum string size required, = N // 8 */
obj set {s};
@@ -148,17 +148,17 @@ define isset(a) = istype(a, obj set);
define setbound(n)
{
local v;
local v;
v = N - 1;
if (isnull(n))
return v;
if (!isint(n) || n < 0)
quit "Bad argument for setbound";
N = n + 1;
M = quo(N, 8, 1); /* M // 8 rounded up */
if (v >= 0)
return v;
v = N - 1;
if (isnull(n))
return v;
if (!isint(n) || n < 0)
quit "Bad argument for setbound";
N = n + 1;
M = quo(N, 8, 1); /* M // 8 rounded up */
if (v >= 0)
return v;
}
setbound(100);
@@ -167,90 +167,90 @@ define empty() = obj set = {""};
define full()
{
local v;
local v;
obj set v;
v.s = M * char(-1);
if (!ismult(N, 8)) v.s[M-1] = 255 >> (8 - N & 7);
return v;
obj set v;
v.s = M * char(-1);
if (!ismult(N, 8)) v.s[M-1] = 255 >> (8 - N & 7);
return v;
}
define isin(a, b)
{
if (!isset(a) || !isint(b))
quit "Bad argument for isin";
return bit(a.s, b);
if (!isset(a) || !isint(b))
quit "Bad argument for isin";
return bit(a.s, b);
}
define addmember(a, n)
{
if (!isset(a) || !isint(n))
quit "Bad argument for addmember";
if (n < N && n >= 0)
setbit(a.s, n);
if (!isset(a) || !isint(n))
quit "Bad argument for addmember";
if (n < N && n >= 0)
setbit(a.s, n);
}
define rmmember(a, n)
{
if (n < N && n >= 0)
setbit(a.s, n, 0);
if (n < N && n >= 0)
setbit(a.s, n, 0);
}
define set()
{
local i, v, s;
local i, v, s;
s = M * char(0);
for (i = 1; i <= param(0); i++) {
v = param(i);
if (!isint(v))
quit "Non-integral argument for set";
if (v >= 0 && v < N)
setbit(s, v);
}
return mkset(s);
s = M * char(0);
for (i = 1; i <= param(0); i++) {
v = param(i);
if (!isint(v))
quit "Non-integral argument for set";
if (v >= 0 && v < N)
setbit(s, v);
}
return mkset(s);
}
define mkset(s)
{
local h, m;
local h, m;
if (!isstr(s))
quit "Non-string argument for mkset";
h = highbit(s);
if (h >= N)
quit "Too-long string for mkset";
m = quo(h + 1, 8, 1);
return obj set = {head(s, m)};
if (!isstr(s))
quit "Non-string argument for mkset";
h = highbit(s);
if (h >= N)
quit "Too-long string for mkset";
m = quo(h + 1, 8, 1);
return obj set = {head(s, m)};
}
define primes(a,b)
{
local i, s, m;
local i, s, m;
if (isnull(b)) {
if (isnull(a)) {
a = 0;
b = N - 1;
}
else b = 0;
}
if (isnull(b)) {
if (isnull(a)) {
a = 0;
b = N - 1;
}
else b = 0;
}
if (!isint(a) || !isint(b))
quit "Non-integer argument for primes";
if (a > b)
swap(a,b);
if (b < 0 || a >= N)
return empty();
a = max(a, 0);
b = min(b, N-1);
s = M * char(0);
for (i = a; i <= b; i++)
if (isprime(i))
setbit(s, i);
return mkset(s);
if (!isint(a) || !isint(b))
quit "Non-integer argument for primes";
if (a > b)
swap(a,b);
if (b < 0 || a >= N)
return empty();
a = max(a, 0);
b = min(b, N-1);
s = M * char(0);
for (i = a; i <= b; i++)
if (isprime(i))
setbit(s, i);
return mkset(s);
}
define set_max(a) = highbit(a.s);
@@ -261,56 +261,56 @@ define set_not(a) = !a.s;
define set_cmp(a,b)
{
if (isset(a) && isset(b))
return a.s != b.s;
return 1;
if (isset(a) && isset(b))
return a.s != b.s;
return 1;
}
define set_rel(a,b)
{
local c;
local c;
if (a == b)
return 0;
if (isset(a)) {
if (isset(b)) {
c = a & b;
if (c == a)
return -1;
if (c == b)
return 1;
return;
}
if (!isint(b))
return set_rel(a, set(b));
}
if (isint(a))
return set_rel(set(a), b);
if (a == b)
return 0;
if (isset(a)) {
if (isset(b)) {
c = a & b;
if (c == a)
return -1;
if (c == b)
return 1;
return;
}
if (!isint(b))
return set_rel(a, set(b));
}
if (isint(a))
return set_rel(set(a), b);
}
define set_or(a, b)
{
if (isset(a)) {
if (isset(b))
return obj set = {a.s | b.s};
if (isint(b))
return a | set(b);
}
if (isint(a))
return set(a) | b;
return newerror("Bad argument for set_or");
if (isset(a)) {
if (isset(b))
return obj set = {a.s | b.s};
if (isint(b))
return a | set(b);
}
if (isint(a))
return set(a) | b;
return newerror("Bad argument for set_or");
}
define set_and(a, b)
{
if (isint(a))
return set(a) & b;
if (isint(b))
return a & set(b);
if (!isset(a) || !isset(b))
return newerror("Bad argument for set_and");
return mkset(a.s & b.s);
if (isint(a))
return set(a) & b;
if (isint(b))
return a & set(b);
if (!isset(a) || !isset(b))
return newerror("Bad argument for set_and");
return mkset(a.s & b.s);
}
@@ -318,295 +318,295 @@ define set_comp(a) = full() \ a;
define set_setminus(a,b)
{
if (isint(a))
return set(a) \ b;
if (isint(b))
return a \ set(b);
if (!isset(a) || !isset(b))
return newerror("Bad argument for set_setminus");
return mkset(a.s \ b.s);
if (isint(a))
return set(a) \ b;
if (isint(b))
return a \ set(b);
if (!isset(a) || !isset(b))
return newerror("Bad argument for set_setminus");
return mkset(a.s \ b.s);
}
define set_xor(a,b)
{
if (isint(a))
return set(a) ~ b;
if (isint(b))
return a ~ set(b);
if (!isset(a) || !isset(b))
return newerror("Bad argument for set_xor");
return mkset(a.s ~ b.s);
if (isint(a))
return set(a) ~ b;
if (isint(b))
return a ~ set(b);
if (!isset(a) || !isset(b))
return newerror("Bad argument for set_xor");
return mkset(a.s ~ b.s);
}
define set_content(a) = #a.s;
define set_add(a, b)
{
local s, i, j, m, n;
local s, i, j, m, n;
if (isint(a))
return set(a) + b;
if (isint(b))
return a + set(b);
if (!isset(a) || !isset(b))
return newerror("Bad argument for set_add");
if (!a || !b)
return empty();
m = highbit(a.s);
n = highbit(b.s);
s = M * char(0);
for (i = 0; i <= m; i++)
if (isin(a, i))
for (j = 0; j <= n && i + j < N; j++)
if (isin(b, j))
setbit(s, i + j);
return mkset(s);
if (isint(a))
return set(a) + b;
if (isint(b))
return a + set(b);
if (!isset(a) || !isset(b))
return newerror("Bad argument for set_add");
if (!a || !b)
return empty();
m = highbit(a.s);
n = highbit(b.s);
s = M * char(0);
for (i = 0; i <= m; i++)
if (isin(a, i))
for (j = 0; j <= n && i + j < N; j++)
if (isin(b, j))
setbit(s, i + j);
return mkset(s);
}
define set_sub(a,b)
{
local s, i, j, m, n;
local s, i, j, m, n;
if (isint(b))
return a - set(b);
if (isint(a))
return set(a) - b;
if (isset(a) && isset(b)) {
if (!a || !b)
return empty();
m = highbit(a.s);
n = highbit(b.s);
s = M * char(0);
for (i = 0; i <= m; i++)
if (isin(a, i))
for (j = 0; j <= n && j <= i; j++)
if (isin(b, j))
setbit(s, i - j);
return mkset(s);
}
return newerror("Bad argument for set_sub");
if (isint(b))
return a - set(b);
if (isint(a))
return set(a) - b;
if (isset(a) && isset(b)) {
if (!a || !b)
return empty();
m = highbit(a.s);
n = highbit(b.s);
s = M * char(0);
for (i = 0; i <= m; i++)
if (isin(a, i))
for (j = 0; j <= n && j <= i; j++)
if (isin(b, j))
setbit(s, i - j);
return mkset(s);
}
return newerror("Bad argument for set_sub");
}
define set_mul(a, b)
{
local s, i, j, m, n;
local s, i, j, m, n;
if (isset(a)) {
s = M * char(0);
m = highbit(a.s);
if (isset(b)) {
if (!a || !b)
return empty();
n = highbit(b.s);
for (i = 0; i <= m; ++i)
if (isin(a, i))
for (j = 1; j <= n && i * j < N; ++j)
if (isin(b, j))
setbit(s, i * j);
return mkset(s);
}
if (isint(b)) {
if (b == 0) {
if (a)
return set(0);
return empty();
}
s = M * char(0);
for (i = 0; i <= m && b * i < N; ++i)
if (isin(a, i))
setbit(s, b * i);
return mkset(s);
}
}
if (isint(a))
return b * a;
return newerror("Bad argument for set_mul");
if (isset(a)) {
s = M * char(0);
m = highbit(a.s);
if (isset(b)) {
if (!a || !b)
return empty();
n = highbit(b.s);
for (i = 0; i <= m; ++i)
if (isin(a, i))
for (j = 1; j <= n && i * j < N; ++j)
if (isin(b, j))
setbit(s, i * j);
return mkset(s);
}
if (isint(b)) {
if (b == 0) {
if (a)
return set(0);
return empty();
}
s = M * char(0);
for (i = 0; i <= m && b * i < N; ++i)
if (isin(a, i))
setbit(s, b * i);
return mkset(s);
}
}
if (isint(a))
return b * a;
return newerror("Bad argument for set_mul");
}
define set_square(a)
{
local s, i, m;
local s, i, m;
s = M * char(0);
m = highbit(a.s);
for (i = 0; i <= m && i^2 < N; ++i)
if (bit(a.s, i))
setbit(s, i^2);
return mkset(s);
s = M * char(0);
m = highbit(a.s);
for (i = 0; i <= m && i^2 < N; ++i)
if (bit(a.s, i))
setbit(s, i^2);
return mkset(s);
}
define set_pow(a, n)
{
local s, i, m;
local s, i, m;
if (!isint(n) || n < 0)
quit "Bad exponent for set_power";
s = M * char(0);
m = highbit(a.s);
for (i = 0; i <= m && i^n < N; ++i)
if (bit(a.s, i))
setbit(s, i^n);
return mkset(s);
if (!isint(n) || n < 0)
quit "Bad exponent for set_power";
s = M * char(0);
m = highbit(a.s);
for (i = 0; i <= m && i^n < N; ++i)
if (bit(a.s, i))
setbit(s, i^n);
return mkset(s);
}
define set_sum(a)
{
local v, m, i;
local v, m, i;
v = 0;
m = highbit(a.s);
for (i = 0; i <= m; ++i)
if (bit(a.s, i))
v += i;
return v;
v = 0;
m = highbit(a.s);
for (i = 0; i <= m; ++i)
if (bit(a.s, i))
v += i;
return v;
}
define set_plus(a) = set_sum(a);
define interval(a, b)
{
local i, j, s;
static tail = "\0\1\3\7\17\37\77\177\377";
local i, j, s;
static tail = "\0\1\3\7\17\37\77\177\377";
if (!isint(a) || !isint(b))
quit "Non-integer argument for interval";
if (a > b)
swap(a, b);
if (b < 0 || a >= N)
return empty();
a = max(a, 0);
b = min(b, N-1);
i = quo(a, 8, 0);
j = quo(b, 8, 0);
s = M * char(0);
if (i == j) {
s[i] = tail[b + 1 - 8 * i] \ tail[a - 8 * i];
return mkset(s);
}
s[i] = ~tail[a - 8 * i];
while (++i < j)
s[i] = -1;
s[j] = tail[b + 1 - 8 * j];
return mkset(s);
if (!isint(a) || !isint(b))
quit "Non-integer argument for interval";
if (a > b)
swap(a, b);
if (b < 0 || a >= N)
return empty();
a = max(a, 0);
b = min(b, N-1);
i = quo(a, 8, 0);
j = quo(b, 8, 0);
s = M * char(0);
if (i == j) {
s[i] = tail[b + 1 - 8 * i] \ tail[a - 8 * i];
return mkset(s);
}
s[i] = ~tail[a - 8 * i];
while (++i < j)
s[i] = -1;
s[j] = tail[b + 1 - 8 * j];
return mkset(s);
}
define isinterval(a)
{
local i, max, s;
local i, max, s;
if (!isset(a))
quit "Non-set argument for isinterval";
if (!isset(a))
quit "Non-set argument for isinterval";
s = a.s;
if (!s)
return 0;
for (i = lowbit(s) + 1, max = highbit(s); i < max; i++)
if (!bit(s, i))
return 0;
return 1;
s = a.s;
if (!s)
return 0;
for (i = lowbit(s) + 1, max = highbit(s); i < max; i++)
if (!bit(s, i))
return 0;
return 1;
}
define set_mod(a, b)
{
local s, m, i, j;
local s, m, i, j;
if (isset(a) && isint(b)) {
s = M * char(0);
m = highbit(a.s);
for (i = 0; i <= m; i++)
if (bit(a.s, i))
for (j = 0; j < N; j++)
if (meq(i, j, b))
setbit(s, j);
return mkset(s);
}
return newerror("Bad argument for set_mod");
if (isset(a) && isint(b)) {
s = M * char(0);
m = highbit(a.s);
for (i = 0; i <= m; i++)
if (bit(a.s, i))
for (j = 0; j < N; j++)
if (meq(i, j, b))
setbit(s, j);
return mkset(s);
}
return newerror("Bad argument for set_mod");
}
define randset(n, a, b)
{
local m, s, i;
local m, s, i;
if (isnull(a))
a = 0;
if (isnull(b))
b = N - 1;
if (!isint(n) || !isint(a) || !isint(b) || n < 0 || a < 0 || b < 0)
quit "Bad argument for randset";
if (a > b)
swap(a, b);
m = b - a + 1;
if (n > m)
return newerror("Too many numbers specified for randset");
if (2 * n > m)
return interval(a,b) \ randset(m - n, a, b);
++b;
s = M * char(0);
while (n-- > 0) {
do
i = rand(a, b);
while
(bit(s, i));
setbit(s, i);
}
return mkset(s);
if (isnull(a))
a = 0;
if (isnull(b))
b = N - 1;
if (!isint(n) || !isint(a) || !isint(b) || n < 0 || a < 0 || b < 0)
quit "Bad argument for randset";
if (a > b)
swap(a, b);
m = b - a + 1;
if (n > m)
return newerror("Too many numbers specified for randset");
if (2 * n > m)
return interval(a,b) \ randset(m - n, a, b);
++b;
s = M * char(0);
while (n-- > 0) {
do
i = rand(a, b);
while
(bit(s, i));
setbit(s, i);
}
return mkset(s);
}
define polyvals(L, A)
{
local s, m, v, i;
local s, m, v, i;
if (!islist(L))
quit "Non-list first argument for polyvals";
if (!isset(A))
quit "Non-set second argument for polyvals";
m = highbit(A.s);
s = M * char(0);
for (i = 0; i <= m; i++)
if (bit(A.s, i)) {
v = poly(L,i);
if (v >> 0 && v < N)
setbit(s, v);
}
return mkset(s);
if (!islist(L))
quit "Non-list first argument for polyvals";
if (!isset(A))
quit "Non-set second argument for polyvals";
m = highbit(A.s);
s = M * char(0);
for (i = 0; i <= m; i++)
if (bit(A.s, i)) {
v = poly(L,i);
if (v >> 0 && v < N)
setbit(s, v);
}
return mkset(s);
}
define polyvals2(L, A, B)
{
local s1, s2, s, m, n, i, j, v;
local s1, s2, s, m, n, i, j, v;
s1 = A.s;
s2 = B.s;
m = highbit(s1);
n = highbit(s2);
s = M * char(0);
for (i = 0; i <= m; i++)
if (bit(s1, i))
for (j = 0; j <= n; j++)
if (bit(s2, j)) {
v = poly(L, i, j);
if (v >= 0 && v < N)
setbit(s, v);
}
return mkset(s);
s1 = A.s;
s2 = B.s;
m = highbit(s1);
n = highbit(s2);
s = M * char(0);
for (i = 0; i <= m; i++)
if (bit(s1, i))
for (j = 0; j <= n; j++)
if (bit(s2, j)) {
v = poly(L, i, j);
if (v >= 0 && v < N)
setbit(s, v);
}
return mkset(s);
}
define set_print(a)
{
local i, s, m;
local i, s, m;
s = a.s;
i = lowbit(s);
print "set(":;
if (i >= 0) {
print i:;
m = highbit(s);
while (++i <= m)
if (bit(s, i))
print ",":i:;
}
print ")",;
s = a.s;
i = lowbit(s);
print "set(":;
if (i >= 0) {
print i:;
m = highbit(s);
while (++i <= m)
if (bit(s, i))
print ",":i:;
}
print ")",;
}
local N, M; /* End scope of static variables N, M */
local N, M; /* End scope of static variables N, M */

641
cal/palindrome.cal Normal file
View File

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

View File

@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,10 +17,10 @@
* 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: 1990/02/15 01:50:34
* File existed as early as: before 1990
* Under source code control: 1990/02/15 01:50:34
* File existed as early as: before 1990
*
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
/*
@@ -31,60 +31,60 @@
define pell(D)
{
local X, Y;
local X, Y;
X = pellx(D);
if (isnull(X)) {
print "D=":D:" is square";
return;
}
Y = isqrt((X^2 - 1) / D);
print X : "^2 - " : D : "*" : Y : "^2 = " : X^2 - D*Y^2;
X = pellx(D);
if (isnull(X)) {
print "D=":D:" is square";
return;
}
Y = isqrt((X^2 - 1) / D);
print X : "^2 - " : D : "*" : Y : "^2 = " : X^2 - D*Y^2;
}
/*
* Function to solve Pell's equation
* Returns the solution X to:
* X^2 - D * Y^2 = 1
* X^2 - D * Y^2 = 1
*/
define pellx(D)
{
local R, Rp, U, Up, V, Vp, A, T, Q1, Q2, n;
local mat ans[2,2];
local mat tmp[2,2];
local R, Rp, U, Up, V, Vp, A, T, Q1, Q2, n;
local mat ans[2,2];
local mat tmp[2,2];
R = isqrt(D);
Vp = D - R^2;
if (Vp == 0)
return;
Rp = R + R;
U = Rp;
Up = U;
V = 1;
A = 0;
n = 0;
ans[0,0] = 1;
ans[1,1] = 1;
tmp[0,1] = 1;
tmp[1,0] = 1;
do {
T = V;
V = A * (Up - U) + Vp;
Vp = T;
A = U // V;
Up = U;
U = Rp - U % V;
tmp[0,0] = A;
ans *= tmp;
n++;
} while (A != Rp);
Q2 = ans[[1]];
Q1 = isqrt(Q2^2 * D + 1);
if (isodd(n)) {
T = Q1^2 + D * Q2^2;
Q2 = Q1 * Q2 * 2;
Q1 = T;
}
return Q1;
R = isqrt(D);
Vp = D - R^2;
if (Vp == 0)
return;
Rp = R + R;
U = Rp;
Up = U;
V = 1;
A = 0;
n = 0;
ans[0,0] = 1;
ans[1,1] = 1;
tmp[0,1] = 1;
tmp[1,0] = 1;
do {
T = V;
V = A * (Up - U) + Vp;
Vp = T;
A = U // V;
Up = U;
U = Rp - U % V;
tmp[0,0] = A;
ans *= tmp;
n++;
} while (A != Rp);
Q2 = ans[[1]];
Q1 = isqrt(Q2^2 * D + 1);
if (isodd(n)) {
T = Q1^2 + D * Q2^2;
Q2 = Q1 * Q2 * 2;
Q1 = T;
}
return Q1;
}

View File

@@ -1,7 +1,7 @@
/*
* pi - various routines to calculate pi
*
* Copyright (C) 1999-2004 David I. Bell
* Copyright (C) 1999-2004,2021 David I. Bell
*
* Calc is open software; you can redistribute it and/or modify it under
* the terms of the version 2.1 of the GNU Lesser General Public License
@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,10 +17,10 @@
* 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: 1991/05/22 21:56:37
* File existed as early as: 1991
* Under source code control: 1991/05/22 21:56:37
* File existed as early as: 1991
*
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
/*
@@ -31,50 +31,50 @@
define qpi(epsilon)
{
local niter, yn, ym, tm, an, am, t, tn, sqrt2, epsilon2, count, digits;
local bits, bits2;
local niter, yn, ym, tm, an, am, t, tn, sqrt2, epsilon2, count, digits;
local bits, bits2;
if (isnull(epsilon))
epsilon = epsilon();
digits = digits(1/epsilon);
if (digits <= 8) { niter = 1; epsilon = 1e-8; }
else if (digits <= 40) { niter = 2; epsilon = 1e-40; }
else if (digits <= 170) { niter = 3; epsilon = 1e-170; }
else if (digits <= 693) { niter = 4; epsilon = 1e-693; }
else {
niter = 4;
t = 693;
while (t < digits) {
++niter;
t *= 4;
}
}
epsilon2 = epsilon/(digits/10 + 1);
digits = digits(1/epsilon2);
sqrt2 = sqrt(2, epsilon2);
bits = abs(ilog2(epsilon)) + 1;
bits2 = abs(ilog2(epsilon2)) + 1;
yn = sqrt2 - 1;
an = 6 - 4 * sqrt2;
tn = 2;
for (count = 0; count < niter; ++count) {
ym = yn;
am = an;
tn *= 4;
t = sqrt(sqrt(1-ym^4, epsilon2), epsilon2);
yn = (1-t)/(1+t);
an = (1+yn)^4*am-tn*yn*(1+yn+yn^2);
yn = bround(yn, bits2);
an = bround(an, bits2);
}
return (bround(1/an, bits));
if (isnull(epsilon))
epsilon = epsilon();
digits = digits(1/epsilon);
if (digits <= 8) { niter = 1; epsilon = 1e-8; }
else if (digits <= 40) { niter = 2; epsilon = 1e-40; }
else if (digits <= 170) { niter = 3; epsilon = 1e-170; }
else if (digits <= 693) { niter = 4; epsilon = 1e-693; }
else {
niter = 4;
t = 693;
while (t < digits) {
++niter;
t *= 4;
}
}
epsilon2 = epsilon/(digits/10 + 1);
digits = digits(1/epsilon2);
sqrt2 = sqrt(2, epsilon2);
bits = abs(ilog2(epsilon)) + 1;
bits2 = abs(ilog2(epsilon2)) + 1;
yn = sqrt2 - 1;
an = 6 - 4 * sqrt2;
tn = 2;
for (count = 0; count < niter; ++count) {
ym = yn;
am = an;
tn *= 4;
t = sqrt(sqrt(1-ym^4, epsilon2), epsilon2);
yn = (1-t)/(1+t);
an = (1+yn)^4*am-tn*yn*(1+yn+yn^2);
yn = bround(yn, bits2);
an = bround(an, bits2);
}
return (bround(1/an, bits));
}
/*
* Print digits of PI forever, neatly formatted, using calc.
*
* Written by Klaus Alexander Seistrup <klaus@seistrup.dk>
* Written by Klaus Alexander Seistrup <klaus at seistrup dot dk>
* on a dull Friday evening in November 1999.
*
* Inspired by an algorithm conceived by Lambert Meertens.
@@ -86,58 +86,58 @@ define qpi(epsilon)
define piforever()
{
local k = 2;
local a = 4;
local b = 1;
local a1 = 12;
local b1 = 4;
local a2, b2, p, q, d, d1;
local stdout = files(1);
local first = 1, row = -1, col = 0;
local k = 2;
local a = 4;
local b = 1;
local a1 = 12;
local b1 = 4;
local a2, b2, p, q, d, d1;
local stdout = files(1);
local first = 1, row = -1, col = 0;
while (1) {
/*
* Next approximation
*/
p = k * k;
q = k + ++k;
while (1) {
/*
* Next approximation
*/
p = k * k;
q = k + ++k;
a2 = a;
b2 = b;
a2 = a;
b2 = b;
a = a1;
a1 = p * a2 + q * a1;
b = b1;
b1 = p * b2 + q * b1;
a = a1;
a1 = p * a2 + q * a1;
b = b1;
b1 = p * b2 + q * b1;
/*
* Print common digits
*/
d = a // b;
d1 = a1 // b1;
/*
* Print common digits
*/
d = a // b;
d1 = a1 // b1;
while (d == d1) {
if (first) {
printf("%d.", d);
first = 0;
} else {
if (!(col % 50)) {
printf("\n");
col = 0;
if (!(++row % 20)) {
printf("\n");
row = 0;
}
}
printf("%d", d);
if (!(++col % 10))
printf(" ");
}
a = 10 * (a % b);
a1 = 10 * (a1 % b1);
d = a // b;
d1 = a1 // b1;
}
fflush(stdout);
}
while (d == d1) {
if (first) {
printf("%d.", d);
first = 0;
} else {
if (!(col % 50)) {
printf("\n");
col = 0;
if (!(++row % 20)) {
printf("\n");
row = 0;
}
}
printf("%d", d);
if (!(++col % 10))
printf(" ");
}
a = 10 * (a % b);
a1 = 10 * (a1 % b1);
d = a // b;
d1 = a1 // b1;
}
fflush(stdout);
}
}

View File

@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,51 +17,51 @@
* 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: 1996/07/09 03:14:14
* File existed as early as: 1996
* Under source code control: 1996/07/09 03:14:14
* File existed as early as: 1996
*
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
/*
* Here is an iterative method of finding the number of primes less than
* or equal to a given number. This method is from "Computer Recreations"
* or equal to a given number. This method is from "Computer Recreations"
* June 1996 issue of Scientific American.
*
* NOTE: For reasonable values of x, the builtin function pix(x) is
* much faster. This code is provided because the method
* is interesting.
* much faster. This code is provided because the method
* is interesting.
*/
define pi_of_x(x)
{
local An; /* A(n) */
local An1; /* A(n-1) */
local An2; /* A(n-2) */
local An3; /* A(n-3) */
local primes; /* number of primes found */
local n; /* loop counter */
local An; /* A(n) */
local An1; /* A(n-1) */
local An2; /* A(n-2) */
local An3; /* A(n-3) */
local primes; /* number of primes found */
local n; /* loop counter */
/*
* setup
*/
An1 = 2;
An2 = 0;
An3 = 3;
primes = 1;
/*
* setup
*/
An1 = 2;
An2 = 0;
An3 = 3;
primes = 1;
/*
* main A(n+1)=A(n-1)+A(n-2) sequence loop
*/
for (n = 3; n < x; ++n) {
An = An2 + An3;
An3 = An2;
An2 = An1;
An1 = An;
if (An % n == 0)
++primes;
}
return primes;
/*
* main A(n+1)=A(n-1)+A(n-2) sequence loop
*/
for (n = 3; n < x; ++n) {
An = An2 + An3;
An3 = An2;
An2 = An1;
An1 = An;
if (An % n == 0)
++primes;
}
return primes;
}

View File

@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,32 +17,32 @@
* 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: 1991/05/22 21:56:37
* File existed as early as: 1991
* Under source code control: 1991/05/22 21:56:37
* File existed as early as: 1991
*
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
define pfactor(N, B, ai, af)
{
local a, k, i, d;
local a, k, i, d;
if (isnull(B))
B = 1000;
if (isnull(ai))
ai = 2;
if (isnull(af))
af = ai + 20;
k = lcmfact(B);
d = lfactor(N, B);
if (d > 1)
return d;
for (a = ai; a <= af; a++) {
i = pmod(a, k, N);
d = gcd(i - 1, N);
if ((d > 1) && (d != N))
return d;
}
return 1;
if (isnull(B))
B = 1000;
if (isnull(ai))
ai = 2;
if (isnull(af))
af = ai + 20;
k = lcmfact(B);
d = lfactor(N, B);
if (d > 1)
return d;
for (a = ai; a <= af; a++) {
i = pmod(a, k, N);
d = gcd(i - 1, N);
if ((d > 1) && (d != N))
return d;
}
return 1;
}

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,10 +17,10 @@
* 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: 1995/12/18 04:43:25
* File existed as early as: 1995
* Under source code control: 1995/12/18 04:43:25
* File existed as early as: 1995
*
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
/*
@@ -32,7 +32,7 @@
* entering "end", "exit" or "quit"; "end" returns to the level from
* which adder() is called, e.g. with:
*
* for (;;) adder()
* for (;;) adder()
*
* entering "end" would start a new edition with sum = 0; "quit" and
* "exit" return to the top level.
@@ -43,25 +43,25 @@
* thus the string may include variables, assignments, functions, etc.
* as in:
*
* 2 + 3
* x = 2 + 3, x^3
* x^2
* local x = 2; while (x < 100) x *= 2; x % 100
* x
* exp(2, 1e-5)
* sum
* print sum^2;
* 3; print sum^2;
* 2 + 3
* x = 2 + 3, x^3
* x^2
* local x = 2; while (x < 100) x *= 2; x % 100
* x
* exp(2, 1e-5)
* sum
* print sum^2;
* 3; print sum^2;
*
* (Here the second line creates x as a global variable; the local
* variable x in the fourth line has no effect on the global x. In
* variable x in the fourth line has no effect on the global x. In
* the last three lines, sum is the sum of numbers already entered, so
* the third last line doubles the value of sum. The value returned
* by "print sum^2;" is the null value, so the second last line adds
* nothing to sum. The last line returns the value 3, i.e. the last
* non-null value found for the expressions separated by semicolons,
* so sum will be increased by 3 after the "print sum^2;" command
* is executed. XXX The terminating semicolon is essential in the
* is executed. XXX The terminating semicolon is essential in the
* last two lines. A command like eval("print 7;") is acceptable to
* calc but eval("print 7") causes an exit from calc. XXX)
*
@@ -72,44 +72,44 @@
*
* Calling showvalues(str) assumes str defines a function of x as in:
*
* "sin(x)", "x^2 + 3*x", "exp(x, 1e-5)".
* "sin(x)", "x^2 + 3*x", "exp(x, 1e-5)".
*
* Values of the function so defined are returned for values of x
* entered in response to the ? prompt. Operation is terminated by
* entered in response to the ? prompt. Operation is terminated by
* entering "end", "exit" or "quit".
*/
define adder() {
global sum = 0;
local s, t;
for (;;) {
s = prompt("? ");
if (s == "end")
break;
t = eval(s);
if (!isnum(t)) {
print "Please enter a number";
continue;
}
sum += t;
print "\t":sum;
}
global sum = 0;
local s, t;
for (;;) {
s = prompt("? ");
if (s == "end")
break;
t = eval(s);
if (!isnum(t)) {
print "Please enter a number";
continue;
}
sum += t;
print "\t":sum;
}
}
global prompt_x;
define showvalues(str) {
local s;
for (;;) {
s = prompt("? ");
if (s == "end")
break;
prompt_x = eval(s);
if (!isnum(prompt_x)) {
print "Please enter a number";
continue;
}
print "\t":eval(str);
}
local s;
for (;;) {
s = prompt("? ");
if (s == "end")
break;
prompt_x = eval(s);
if (!isnum(prompt_x)) {
print "Please enter a number";
continue;
}
print "\t":eval(str);
}
}

View File

@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,10 +17,10 @@
* 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: 1990/02/15 01:50:35
* File existed as early as: before 1990
* Under source code control: 1990/02/15 01:50:35
* File existed as early as: before 1990
*
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
/*
@@ -31,40 +31,40 @@
define psqrt(u, p)
{
local p1, q, n, y, r, v, w, t, k;
local p1, q, n, y, r, v, w, t, k;
p1 = p - 1;
r = lowbit(p1);
q = p >> r;
t = 1 << (r - 1);
for (n = 2; ; n++) {
if (ptest(n, 1) == 0)
continue;
y = pmod(n, q, p);
k = pmod(y, t, p);
if (k == 1)
continue;
if (k != p1)
return;
break;
}
t = pmod(u, (q - 1) / 2, p);
v = (t * u) % p;
w = (t^2 * u) % p;
while (w != 1) {
k = 0;
t = w;
do {
k++;
t = t^2 % p;
} while (t != 1);
if (k == r)
return;
t = pmod(y, 1 << (r - k - 1), p);
y = t^2 % p;
v = (v * t) % p;
w = (w * y) % p;
r = k;
}
return min(v, p - v);
p1 = p - 1;
r = lowbit(p1);
q = p >> r;
t = 1 << (r - 1);
for (n = 2; ; n++) {
if (ptest(n, 1) == 0)
continue;
y = pmod(n, q, p);
k = pmod(y, t, p);
if (k == 1)
continue;
if (k != p1)
return;
break;
}
t = pmod(u, (q - 1) / 2, p);
v = (t * u) % p;
w = (t^2 * u) % p;
while (w != 1) {
k = 0;
t = w;
do {
k++;
t = t^2 % p;
} while (t != 1);
if (k == r)
return;
t = pmod(y, 1 << (r - k - 1), p);
y = t^2 % p;
v = (v * t) % p;
w = (w * y) % p;
r = k;
}
return min(v, p - v);
}

View File

@@ -1,9 +1,9 @@
/*
* qtime - Display time as English sentence
*
* Copyright (C) 1999 Klaus Alexander Seistrup and Landon Curt Noll
* Copyright (C) 1999,2021 Klaus Alexander Seistrup and Landon Curt Noll
*
* Written by: Klaus Alexander Seistrup <kseis@magnetic-ink.dk>
* Written by: Klaus Alexander Seistrup <kseis at magnetic-ink dot dk>
* With mods by: Landon Curt Noll <http://www.isthe.com/chongo/>
*
* Calc is open software; you can redistribute it and/or modify it under
@@ -12,7 +12,7 @@
*
* 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
* 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
@@ -20,21 +20,21 @@
* 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: 1999/10/13 04:10:33
* File existed as early as: 1999
* Under source code control: 1999/10/13 04:10:33
* File existed as early as: 1999
*
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
/*
* usage:
* qtime(utc_hr_offset)
* qtime(utc_hr_offset)
*
* utc_hr_offset Offset from UTC in hours.
* utc_hr_offset Offset from UTC in hours.
*
* See:
* http://www.magnetic-ink.dk/download/qtime.html
* http://www.magnetic-ink.dk/download/qtime.html
*
* for examples of qtime() written on other languages.
*/
@@ -45,42 +45,42 @@
*/
define qtime(utc_hr_offset)
{
static mat hr[12] = {
"twelve", "one", "two", "three", "four", "five",
"six", "seven", "eight", "nine", "ten", "eleven"
};
static mat mn[7] = {
"", "five ", "ten ", "a quarter ", "twenty ", "twenty-five ", "half "
};
static mat ny[5] = {
"nearly ", "almost ", "", "just after ", "after "
};
static mat up[3] = {
"to ", "", "past "
};
local adj_mins = (((time() + utc_hr_offset*3600) % 86400) + 30)//60+27;
local hours = (adj_mins // 60) % 12;
local minutes = adj_mins % 60;
local almost = minutes % 5;
local divisions = (minutes // 5) - 5;
local to_past_idx = divisions > 0 ? 1 : 0;
static mat hr[12] = {
"twelve", "one", "two", "three", "four", "five",
"six", "seven", "eight", "nine", "ten", "eleven"
};
static mat mn[7] = {
"", "five ", "ten ", "a quarter ", "twenty ", "twenty-five ", "half "
};
static mat ny[5] = {
"nearly ", "almost ", "", "just after ", "after "
};
static mat up[3] = {
"to ", "", "past "
};
local adj_mins = (((time() + utc_hr_offset*3600) % 86400) + 30)//60+27;
local hours = (adj_mins // 60) % 12;
local minutes = adj_mins % 60;
local almost = minutes % 5;
local divisions = (minutes // 5) - 5;
local to_past_idx = divisions > 0 ? 1 : 0;
if (divisions < 0) {
divisions = -divisions;
to_past_idx = -1;
}
++to_past_idx;
if (divisions < 0) {
divisions = -divisions;
to_past_idx = -1;
}
++to_past_idx;
/*
* Print the English sentence
*
* We avoid forward and back quotes just to show that the char()
* builtin function can be used in conjunction with a printf.
*/
printf("It%cs %s%s%s%s",
char(0x27), ny[almost], mn[divisions],
up[to_past_idx], hr[hours]);
if (divisions == 0)
printf(" o%cclock", char(0x27));
print ".";
/*
* Print the English sentence
*
* We avoid forward and back quotes just to show that the char()
* builtin function can be used in conjunction with a printf.
*/
printf("It%cs %s%s%s%s",
char(0x27), ny[almost], mn[divisions],
up[to_past_idx], hr[hours]);
if (divisions == 0)
printf(" o%cclock", char(0x27));
print ".";
}

View File

@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,205 +17,205 @@
* 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: 1990/02/15 01:50:35
* File existed as early as: before 1990
* Under source code control: 1990/02/15 01:50:35
* File existed as early as: before 1990
*
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
/*
* Routines to handle quaternions of the form:
* a + bi + cj + dk
* a + bi + cj + dk
*
* Note: In this module, quaternians are manipulated in the form:
* s + v
* s + v
* Where s is a scalar and v is a vector of size 3.
*/
obj quat {s, v}; /* definition of the quaternion object */
obj quat {s, v}; /* definition of the quaternion object */
define quat(a,b,c,d)
{
local obj quat x;
local obj quat x;
x.s = isnull(a) ? 0 : a;
mat x.v[3];
x.v[0] = isnull(b) ? 0 : b;
x.v[1] = isnull(c) ? 0 : c;
x.v[2] = isnull(d) ? 0 : d;
return x;
x.s = isnull(a) ? 0 : a;
mat x.v[3];
x.v[0] = isnull(b) ? 0 : b;
x.v[1] = isnull(c) ? 0 : c;
x.v[2] = isnull(d) ? 0 : d;
return x;
}
define quat_print(a)
{
print "quat(" : a.s : ", " : a.v[0] : ", " :
a.v[1] : ", " : a.v[2] : ")" :;
print "quat(" : a.s : ", " : a.v[0] : ", " :
a.v[1] : ", " : a.v[2] : ")" :;
}
define quat_norm(a)
{
return a.s^2 + dp(a.v, a.v);
return a.s^2 + dp(a.v, a.v);
}
define quat_abs(a, e)
{
return sqrt(a.s^2 + dp(a.v, a.v), e);
return sqrt(a.s^2 + dp(a.v, a.v), e);
}
define quat_conj(a)
{
local obj quat x;
local obj quat x;
x.s = a.s;
x.v = -a.v;
return x;
x.s = a.s;
x.v = -a.v;
return x;
}
define quat_add(a, b)
{
local obj quat x;
local obj quat x;
if (!istype(b, x)) {
x.s = a.s + b;
x.v = a.v;
return x;
}
if (!istype(a, x)) {
x.s = a + b.s;
x.v = b.v;
return x;
}
x.s = a.s + b.s;
x.v = a.v + b.v;
if (x.v)
return x;
return x.s;
if (!istype(b, x)) {
x.s = a.s + b;
x.v = a.v;
return x;
}
if (!istype(a, x)) {
x.s = a + b.s;
x.v = b.v;
return x;
}
x.s = a.s + b.s;
x.v = a.v + b.v;
if (x.v)
return x;
return x.s;
}
define quat_sub(a, b)
{
local obj quat x;
local obj quat x;
if (!istype(b, x)) {
x.s = a.s - b;
x.v = a.v;
return x;
}
if (!istype(a, x)) {
x.s = a - b.s;
x.v = -b.v;
return x;
}
x.s = a.s - b.s;
x.v = a.v - b.v;
if (x.v)
return x;
return x.s;
if (!istype(b, x)) {
x.s = a.s - b;
x.v = a.v;
return x;
}
if (!istype(a, x)) {
x.s = a - b.s;
x.v = -b.v;
return x;
}
x.s = a.s - b.s;
x.v = a.v - b.v;
if (x.v)
return x;
return x.s;
}
define quat_inc(a)
{
local x;
local x;
x = a;
x.s++;
return x;
x = a;
x.s++;
return x;
}
define quat_dec(a)
{
local x;
local x;
x = a;
x.s--;
return x;
x = a;
x.s--;
return x;
}
define quat_neg(a)
{
local obj quat x;
local obj quat x;
x.s = -a.s;
x.v = -a.v;
return x;
x.s = -a.s;
x.v = -a.v;
return x;
}
define quat_mul(a, b)
{
local obj quat x;
local obj quat x;
if (!istype(b, x)) {
x.s = a.s * b;
x.v = a.v * b;
} else if (!istype(a, x)) {
x.s = b.s * a;
x.v = b.v * a;
} else {
x.s = a.s * b.s - dp(a.v, b.v);
x.v = a.s * b.v + b.s * a.v + cp(a.v, b.v);
}
if (x.v)
return x;
return x.s;
if (!istype(b, x)) {
x.s = a.s * b;
x.v = a.v * b;
} else if (!istype(a, x)) {
x.s = b.s * a;
x.v = b.v * a;
} else {
x.s = a.s * b.s - dp(a.v, b.v);
x.v = a.s * b.v + b.s * a.v + cp(a.v, b.v);
}
if (x.v)
return x;
return x.s;
}
define quat_div(a, b)
{
local obj quat x;
local obj quat x;
if (!istype(b, x)) {
x.s = a.s / b;
x.v = a.v / b;
return x;
}
return a * quat_inv(b);
if (!istype(b, x)) {
x.s = a.s / b;
x.v = a.v / b;
return x;
}
return a * quat_inv(b);
}
define quat_inv(a)
{
local x, q2;
local x, q2;
obj quat x;
q2 = a.s^2 + dp(a.v, a.v);
x.s = a.s / q2;
x.v = a.v / (-q2);
return x;
obj quat x;
q2 = a.s^2 + dp(a.v, a.v);
x.s = a.s / q2;
x.v = a.v / (-q2);
return x;
}
define quat_scale(a, b)
{
local obj quat x;
local obj quat x;
x.s = scale(a.s, b);
x.v = scale(a.v, b);
return x;
x.s = scale(a.s, b);
x.v = scale(a.v, b);
return x;
}
define quat_shift(a, b)
{
local obj quat x;
local obj quat x;
x.s = a.s << b;
x.v = a.v << b;
if (x.v)
return x;
return x.s;
x.s = a.s << b;
x.v = a.v << b;
if (x.v)
return x;
return x.s;
}
if (config("resource_debug") & 3) {

View File

@@ -1,7 +1,7 @@
/*
* randbitrun - check rand bit run lengths of the a55 generator
* randbitrun - check rand bit run lengths of the subtractive 100 shuffle generator
*
* Copyright (C) 1999 Landon Curt Noll
* Copyright (C) 1999,2023 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
@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,11 +17,11 @@
* 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: 1995/02/13 03:43:11
* File existed as early as: 1995
* Under source code control: 1995/02/13 03:43:11
* File existed as early as: 1995
*
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
/*
@@ -32,30 +32,30 @@
define randbitrun(run_cnt)
{
local i; /* index */
local max_run; /* longest run */
local long_run_cnt; /* number of runs longer than MAX_RUN */
local run; /* current run length */
local tally_sum; /* sum of all tally values */
local last; /* last random number */
local current; /* current random number */
local MAX_RUN = 18; /* max run we will keep track of */
local i; /* index */
local max_run; /* longest run */
local long_run_cnt; /* number of runs longer than MAX_RUN */
local run; /* current run length */
local tally_sum; /* sum of all tally values */
local last; /* last random number */
local current; /* current random number */
local MAX_RUN = 18; /* max run we will keep track of */
local mat tally[1:MAX_RUN]; /* tally of length of a rise run of 'x' */
local mat prob[1:MAX_RUN]; /* prob[x] = probability of 'x' length run */
local mat prob[1:MAX_RUN]; /* prob[x] = probability of 'x' length run */
/*
* parse args
*/
if (param(0) == 0) {
run_cnt = 65536;
run_cnt = 65536;
}
/*
* run setup
*/
max_run = 0; /* no runs yet */
long_run_cnt = 0; /* no long runs set */
current = randbit(1); /* our first number */
max_run = 0; /* no runs yet */
long_run_cnt = 0; /* no long runs set */
current = randbit(1); /* our first number */
run = 1;
/*
@@ -63,10 +63,10 @@ define randbitrun(run_cnt)
*
* A bit run length of 'r' occurs with a probability of:
*
* 1/2^n;
* 1/2^n;
*/
for (i=1; i <= MAX_RUN; ++i) {
prob[i] = 1.0/(1<<i);
prob[i] = 1.0/(1<<i);
}
/*
@@ -74,31 +74,31 @@ define randbitrun(run_cnt)
*/
for (i=0; i < run_cnt; ++i) {
/* get our current number */
last = current;
current = randbit(1);
/* get our current number */
last = current;
current = randbit(1);
/* look for a run break */
if (current != last) {
/* look for a run break */
if (current != last) {
/* record the stats */
if (run > max_run) {
max_run = run;
}
if (run > MAX_RUN) {
++long_run_cnt;
} else {
++tally[run];
}
/* record the stats */
if (run > max_run) {
max_run = run;
}
if (run > MAX_RUN) {
++long_run_cnt;
} else {
++tally[run];
}
/* start a new run */
current = randbit(1);
run = 1;
/* start a new run */
current = randbit(1);
run = 1;
/* note the continuing run */
} else {
++run;
}
/* note the continuing run */
} else {
++run;
}
}
/* determine the number of runs found */
tally_sum = matsum(tally) + long_run_cnt;
@@ -109,9 +109,9 @@ define randbitrun(run_cnt)
printf("rand runbit test used %d values to produce %d runs\n",
run_cnt, tally_sum);
for (i=1; i <= MAX_RUN; ++i) {
printf("length=%d\tprob=%9.7f\texpect=%d \tcount=%d \terr=%9.7f\n",
i, prob[i], round(tally_sum*prob[i]), tally[i],
(tally[i] - round(tally_sum*prob[i]))/tally_sum);
printf("length=%d\tprob=%9.7f\texpect=%d \tcount=%d \terr=%9.7f\n",
i, prob[i], round(tally_sum*prob[i]), tally[i],
(tally[i] - round(tally_sum*prob[i]))/tally_sum);
}
printf("length>%d\t\t\t\t\tcount=%d\n", MAX_RUN, long_run_cnt);
printf("max length=%d\n", max_run);

View File

@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,11 +17,11 @@
* 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: 1994/03/14 23:11:21
* File existed as early as: 1994
* Under source code control: 1994/03/14 23:11:21
* File existed as early as: 1994
*
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
@@ -32,37 +32,37 @@ read -once "lucas.cal"
* randmprime - find a random prime of the form h*2^n-1 of a given size
*
* given:
* bits minimum bits in prime to return
* seed random seed for srandom()
* [dbg] if given, enable debugging
* bits minimum bits in prime to return
* seed random seed for srandom()
* [dbg] if given, enable debugging
*
* returns:
* a prime of the form h*2^n-1
* a prime of the form h*2^n-1
*/
define
randmprime(bits, seed, dbg)
{
local n; /* n as in h*2^n-1 */
local h; /* h as in h*2^n-1 */
local plush; /* value added to h since the beginning */
local init; /* initial CPU time */
local start; /* CPU time before last test */
local stop; /* CPU time after last test */
local tmp; /* just a tmp place holder value */
local ret; /* h*2^n-1 that is prime */
local n; /* n as in h*2^n-1 */
local h; /* h as in h*2^n-1 */
local plush; /* value added to h since the beginning */
local init; /* initial CPU time */
local start; /* CPU time before last test */
local stop; /* CPU time after last test */
local tmp; /* just a tmp place holder value */
local ret; /* h*2^n-1 that is prime */
/* firewall */
if (param(0) < 2 || param(0) > 3) {
quit "bad usage: rndprime(dig, seed [,dbg])";
quit "bad usage: rndprime(dig, seed [,dbg])";
}
if (!isint(bits) || bits < 0 || !isint(seed) || seed < 0) {
quit "args must be non-negative integers";
quit "args must be non-negative integers";
}
if (bits < 1) {
bits = 1;
bits = 1;
}
if (param(0) == 2 || dbg < 0) {
dbg = 0;
dbg = 0;
}
/* seed generator */
@@ -76,57 +76,57 @@ randmprime(bits, seed, dbg)
++n;
}
if (dbg >= 1) {
print "DEBUG3: initial h =", h;
print "DEBUG3: initial n =", n;
print "DEBUG3: initial h =", h;
print "DEBUG3: initial n =", n;
}
/*
* loop until we find a prime
*/
if (dbg >= 1) {
start = usertime();
init = usertime();
plush = 0;
print "DEBUG1: testing (h+" : plush : ")*2^" : n : "-1";
start = usertime();
init = usertime();
plush = 0;
print "DEBUG1: testing (h+" : plush : ")*2^" : n : "-1";
}
while (lucas(h,n) == 0) {
/* bump h, and n if needed */
if (dbg >= 2) {
stop = usertime();
print "DEBUG2: last test:", stop-start, " total time:", stop-init;
}
if (dbg >= 1) {
print "DEBUG1: composite: (h+" : plush : ")*2^" : n : "-1";
plush += 2;
}
h += 2;
while (highbit(h) >= n) {
++n;
}
if (dbg >= 1) {
print "DEBUG1: testing (h+" : plush : ")*2^" : n : "-1";
start = stop;
}
/* bump h, and n if needed */
if (dbg >= 2) {
stop = usertime();
print "DEBUG2: last test:", stop-start, " total time:", stop-init;
}
if (dbg >= 1) {
print "DEBUG1: composite: (h+" : plush : ")*2^" : n : "-1";
plush += 2;
}
h += 2;
while (highbit(h) >= n) {
++n;
}
if (dbg >= 1) {
print "DEBUG1: testing (h+" : plush : ")*2^" : n : "-1";
start = stop;
}
}
/* found a prime */
if (dbg >= 2) {
stop = usertime();
print "DEBUG2: last test:", stop-start, " total time:", stop-init;
print "DEBUG3: " : h : "*2^" : n : "-1 is prime";
stop = usertime();
print "DEBUG2: last test:", stop-start, " total time:", stop-init;
print "DEBUG3: " : h : "*2^" : n : "-1 is prime";
}
if (dbg >= 1) {
print "DEBUG1: prime: (h+" : plush : ")*2^" : n : "-1";
print "DEBUG1: prime: (h+" : plush : ")*2^" : n : "-1";
}
ret = h*2^n-1;
if (dbg >= 3) {
print "DEBUG3: highbit(h):", highbit(h);
print "DEBUG3: digits(h):", digits(h);
print "DEBUG3: highbit(n):", highbit(n);
print "DEBUG3: digits(2^n):", int(n*ln(10)/ln(2)+1);
print "DEBUG3: highbit(h*2^n-1):", highbit(ret);
print "DEBUG3: digits(h*2^n)-1:", digits(ret);
print "DEBUG3: highbit(h):", highbit(h);
print "DEBUG3: digits(h):", digits(h);
print "DEBUG3: highbit(n):", highbit(n);
print "DEBUG3: digits(2^n):", int(n*ln(10)/ln(2)+1);
print "DEBUG3: highbit(h*2^n-1):", highbit(ret);
print "DEBUG3: digits(h*2^n)-1:", digits(ret);
}
return ret;
}

View File

@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,11 +17,11 @@
* 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: 1995/02/13 03:43:11
* File existed as early as: 1995
* Under source code control: 1995/02/13 03:43:11
* File existed as early as: 1995
*
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
/*
@@ -32,30 +32,30 @@
define randombitrun(run_cnt)
{
local i; /* index */
local max_run; /* longest run */
local long_run_cnt; /* number of runs longer than MAX_RUN */
local run; /* current run length */
local tally_sum; /* sum of all tally values */
local last; /* last random number */
local current; /* current random number */
local MAX_RUN = 18; /* max run we will keep track of */
local i; /* index */
local max_run; /* longest run */
local long_run_cnt; /* number of runs longer than MAX_RUN */
local run; /* current run length */
local tally_sum; /* sum of all tally values */
local last; /* last random number */
local current; /* current random number */
local MAX_RUN = 18; /* max run we will keep track of */
local mat tally[1:MAX_RUN]; /* tally of length of a rise run of 'x' */
local mat prob[1:MAX_RUN]; /* prob[x] = probability of 'x' length run */
local mat prob[1:MAX_RUN]; /* prob[x] = probability of 'x' length run */
/*
* parse args
*/
if (param(0) == 0) {
run_cnt = 65536;
run_cnt = 65536;
}
/*
* run setup
*/
max_run = 0; /* no runs yet */
long_run_cnt = 0; /* no long runs set */
current = randombit(1); /* our first number */
max_run = 0; /* no runs yet */
long_run_cnt = 0; /* no long runs set */
current = randombit(1); /* our first number */
run = 1;
/*
@@ -63,10 +63,10 @@ define randombitrun(run_cnt)
*
* A bit run length of 'r' occurs with a probability of:
*
* 1/2^n;
* 1/2^n;
*/
for (i=1; i <= MAX_RUN; ++i) {
prob[i] = 1.0/(1<<i);
prob[i] = 1.0/(1<<i);
}
/*
@@ -74,31 +74,31 @@ define randombitrun(run_cnt)
*/
for (i=0; i < run_cnt; ++i) {
/* get our current number */
last = current;
current = randombit(1);
/* get our current number */
last = current;
current = randombit(1);
/* look for a run break */
if (current != last) {
/* look for a run break */
if (current != last) {
/* record the stats */
if (run > max_run) {
max_run = run;
}
if (run > MAX_RUN) {
++long_run_cnt;
} else {
++tally[run];
}
/* record the stats */
if (run > max_run) {
max_run = run;
}
if (run > MAX_RUN) {
++long_run_cnt;
} else {
++tally[run];
}
/* start a new run */
current = randombit(1);
run = 1;
/* start a new run */
current = randombit(1);
run = 1;
/* note the continuing run */
} else {
++run;
}
/* note the continuing run */
} else {
++run;
}
}
/* determine the number of runs found */
tally_sum = matsum(tally) + long_run_cnt;
@@ -109,9 +109,9 @@ define randombitrun(run_cnt)
printf("random runbit test used %d values to produce %d runs\n",
run_cnt, tally_sum);
for (i=1; i <= MAX_RUN; ++i) {
printf("length=%d\tprob=%9.7f\texpect=%d \tcount=%d \terr=%9.7f\n",
i, prob[i], round(tally_sum*prob[i]), tally[i],
(tally[i] - round(tally_sum*prob[i]))/tally_sum);
printf("length=%d\tprob=%9.7f\texpect=%d \tcount=%d \terr=%9.7f\n",
i, prob[i], round(tally_sum*prob[i]), tally[i],
(tally[i] - round(tally_sum*prob[i]))/tally_sum);
}
printf("length>%d\t\t\t\t\tcount=%d\n", MAX_RUN, long_run_cnt);
printf("max length=%d\n", max_run);

View File

@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,11 +17,11 @@
* 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: 1997/02/19 03:35:59
* File existed as early as: 1997
* Under source code control: 1997/02/19 03:35:59
* File existed as early as: 1997
*
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
/*
@@ -41,30 +41,30 @@
define randomrun(run_cnt)
{
local i; /* index */
local max_run; /* longest run */
local long_run_cnt; /* number of runs longer than MAX_RUN */
local run; /* current run length */
local tally_sum; /* sum of all tally values */
local last; /* last random number */
local current; /* current random number */
local MAX_RUN = 9; /* max run we will keep track of */
local i; /* index */
local max_run; /* longest run */
local long_run_cnt; /* number of runs longer than MAX_RUN */
local run; /* current run length */
local tally_sum; /* sum of all tally values */
local last; /* last random number */
local current; /* current random number */
local MAX_RUN = 9; /* max run we will keep track of */
local mat tally[1:MAX_RUN]; /* tally of length of a rise run of 'x' */
local mat prob[1:MAX_RUN]; /* prob[x] = probability of 'x' length run */
local mat prob[1:MAX_RUN]; /* prob[x] = probability of 'x' length run */
/*
* parse args
*/
if (param(0) == 0) {
run_cnt = 65536;
run_cnt = 65536;
}
/*
* run setup
*/
max_run = 0; /* no runs yet */
long_run_cnt = 0; /* no long runs set */
current = random(); /* our first number */
max_run = 0; /* no runs yet */
long_run_cnt = 0; /* no long runs set */
current = random(); /* our first number */
run = 1;
/*
@@ -72,10 +72,10 @@ define randomrun(run_cnt)
*
* A run length of 'r' occurs with a probability of:
*
* 1/r! - 1/(r+1)!
* 1/r! - 1/(r+1)!
*/
for (i=1; i <= MAX_RUN; ++i) {
prob[i] = 1.0/fact(i) - 1.0/fact(i+1);
prob[i] = 1.0/fact(i) - 1.0/fact(i+1);
}
/*
@@ -83,31 +83,31 @@ define randomrun(run_cnt)
*/
for (i=0; i < run_cnt; ++i) {
/* get our current number */
last = current;
current = random();
/* get our current number */
last = current;
current = random();
/* look for a run break */
if (current < last) {
/* look for a run break */
if (current < last) {
/* record the stats */
if (run > max_run) {
max_run = run;
}
if (run > MAX_RUN) {
++long_run_cnt;
} else {
++tally[run];
}
/* record the stats */
if (run > max_run) {
max_run = run;
}
if (run > MAX_RUN) {
++long_run_cnt;
} else {
++tally[run];
}
/* start a new run */
current = random();
run = 1;
/* start a new run */
current = random();
run = 1;
/* note the continuing run */
} else {
++run;
}
/* note the continuing run */
} else {
++run;
}
}
/* determine the number of runs found */
tally_sum = matsum(tally) + long_run_cnt;
@@ -118,9 +118,9 @@ define randomrun(run_cnt)
printf("random run test used %d values to produce %d runs\n",
run_cnt, tally_sum);
for (i=1; i <= MAX_RUN; ++i) {
printf("length=%d\tprob=%9.7f\texpect=%d \tcount=%d \terr=%9.7f\n",
i, prob[i], round(tally_sum*prob[i]), tally[i],
(tally[i] - round(tally_sum*prob[i]))/tally_sum);
printf("length=%d\tprob=%9.7f\texpect=%d \tcount=%d \terr=%9.7f\n",
i, prob[i], round(tally_sum*prob[i]), tally[i],
(tally[i] - round(tally_sum*prob[i]))/tally_sum);
}
printf("length>%d\t\t\t\t\tcount=%d\n", MAX_RUN, long_run_cnt);
printf("max length=%d\n", max_run);

View File

@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,10 +17,10 @@
* 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: 1995/02/12 20:00:06
* File existed as early as: 1995
* Under source code control: 1995/02/12 20:00:06
* File existed as early as: 1995
*
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
/*
@@ -40,30 +40,30 @@
define randrun(run_cnt)
{
local i; /* index */
local max_run; /* longest run */
local long_run_cnt; /* number of runs longer than MAX_RUN */
local run; /* current run length */
local tally_sum; /* sum of all tally values */
local last; /* last random number */
local current; /* current random number */
local MAX_RUN = 9; /* max run we will keep track of */
local i; /* index */
local max_run; /* longest run */
local long_run_cnt; /* number of runs longer than MAX_RUN */
local run; /* current run length */
local tally_sum; /* sum of all tally values */
local last; /* last random number */
local current; /* current random number */
local MAX_RUN = 9; /* max run we will keep track of */
local mat tally[1:MAX_RUN]; /* tally of length of a rise run of 'x' */
local mat prob[1:MAX_RUN]; /* prob[x] = probability of 'x' length run */
local mat prob[1:MAX_RUN]; /* prob[x] = probability of 'x' length run */
/*
* parse args
*/
if (param(0) == 0) {
run_cnt = 65536;
run_cnt = 65536;
}
/*
* run setup
*/
max_run = 0; /* no runs yet */
long_run_cnt = 0; /* no long runs set */
current = rand(); /* our first number */
max_run = 0; /* no runs yet */
long_run_cnt = 0; /* no long runs set */
current = rand(); /* our first number */
run = 1;
/*
@@ -71,10 +71,10 @@ define randrun(run_cnt)
*
* A run length of 'r' occurs with a probability of:
*
* 1/r! - 1/(r+1)!
* 1/r! - 1/(r+1)!
*/
for (i=1; i <= MAX_RUN; ++i) {
prob[i] = 1.0/fact(i) - 1.0/fact(i+1);
prob[i] = 1.0/fact(i) - 1.0/fact(i+1);
}
/*
@@ -82,31 +82,31 @@ define randrun(run_cnt)
*/
for (i=0; i < run_cnt; ++i) {
/* get our current number */
last = current;
current = rand();
/* get our current number */
last = current;
current = rand();
/* look for a run break */
if (current < last) {
/* look for a run break */
if (current < last) {
/* record the stats */
if (run > max_run) {
max_run = run;
}
if (run > MAX_RUN) {
++long_run_cnt;
} else {
++tally[run];
}
/* record the stats */
if (run > max_run) {
max_run = run;
}
if (run > MAX_RUN) {
++long_run_cnt;
} else {
++tally[run];
}
/* start a new run */
current = rand();
run = 1;
/* start a new run */
current = rand();
run = 1;
/* note the continuing run */
} else {
++run;
}
/* note the continuing run */
} else {
++run;
}
}
/* determine the number of runs found */
tally_sum = matsum(tally) + long_run_cnt;
@@ -117,9 +117,9 @@ define randrun(run_cnt)
printf("rand run test used %d values to produce %d runs\n",
run_cnt, tally_sum);
for (i=1; i <= MAX_RUN; ++i) {
printf("length=%d\tprob=%9.7f\texpect=%d \tcount=%d \terr=%9.7f\n",
i, prob[i], round(tally_sum*prob[i]), tally[i],
(tally[i] - round(tally_sum*prob[i]))/tally_sum);
printf("length=%d\tprob=%9.7f\texpect=%d \tcount=%d \terr=%9.7f\n",
i, prob[i], round(tally_sum*prob[i]), tally[i],
(tally[i] - round(tally_sum*prob[i]))/tally_sum);
}
printf("length>%d\t\t\t\t\tcount=%d\n", MAX_RUN, long_run_cnt);
printf("max length=%d\n", max_run);

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,11 +17,11 @@
* 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: 2003/01/05 00:00:01
* File existed as early as: 2003
* Under source code control: 2003/01/05 00:00:01
* File existed as early as: 2003
*
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
@@ -29,18 +29,18 @@
* repeat - return the value of a repeated set of digits
*
* usage:
* repeat(digit_set, repeat_count)
* repeat(digit_set, repeat_count)
*/
define repeat(digit_set, repeat_count)
{
local digit_count; /* digits in the digit_set */
local digit_count; /* digits in the digit_set */
/* firewall */
if (!isint(digit_set) || digit_set <= 0) {
quit "digit set must be an integer > 0";
quit "digit set must be an integer > 0";
}
if (!isint(repeat_count) || repeat_count <= 0) {
quit "repeat count must be an integer > 0";
quit "repeat count must be an integer > 0";
}
/* return repeated set of digits */

View File

@@ -3,22 +3,40 @@
*
* This file was created by Ernest Bowen <ebowen at une dot edu dot au>.
*
* This code has been placed in the public domain. Please do not
* copyright this code.
*
* ERNEST BOWEN DISCLAIMS ALL WARRANTIES WITH REGARD TO
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MER-
* CHANTABILITY AND FITNESS. IN NO EVENT SHALL LANDON CURT
* NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* This file is not covered under version 2.1 of the GNU LGPL.
* This file is covered under "The unlicense":
*
* Under source code control: 2006/03/08 05:54:09
* File existed as early as: 2006
* https://unlicense.org
*
* In particular:
*
* This is free and unencumbered software released into the public domain.
*
* Anyone is free to copy, modify, publish, use, compile, sell, or
* distribute this software, either in source code form or as a compiled
* binary, for any purpose, commercial or non-commercial, and by any
* means.
*
* In jurisdictions that recognize copyright laws, the author or authors
* of this software dedicate any and all copyright interest in the
* software to the public domain. We make this dedication for the benefit
* of the public at large and to the detriment of our heirs and
* successors. We intend this dedication to be an overt act of
* relinquishment in perpetuity of all present and future rights to this
* software under copyright law.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* For more information, please refer to <http://unlicense.org/>
*
* Under source code control: 2006/03/08 05:54:09
* File existed as early as: 2006
*/
up = CUU ="\e[A";

View File

@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,18 +17,18 @@
* 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: 1996/01/01 08:21:00
* File existed as early as: 1996
* Under source code control: 1996/01/01 08:21:00
* File existed as early as: 1996
*
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
/*
* The period of Blum generators with modulus 'n=p*q' (where p and
* q are primes 3 mod 4) is:
*
* lambda(n) = lcm(factors of p-1 & q-1)
* lambda(n) = lcm(factors of p-1 & q-1)
*
* One can construct a generator with a maximal period when
* 'p' and 'q' have the fewest possible factors in common.
@@ -38,118 +38,118 @@
* such primes.
*
* given:
* seed1 - a large random value (at least 10^20 and perhaps < 10^314)
* seed2 - a large random value (at least 10^20 and perhaps < 10^314)
* size - min Blum modulus as a power of 2 (at least 32, perhaps >= 512)
* trials - number of ptest() trials (default 25)
* seed1 - a large random value (at least 10^20 and perhaps < 10^314)
* seed2 - a large random value (at least 10^20 and perhaps < 10^314)
* size - min Blum modulus as a power of 2 (at least 32, perhaps >= 512)
* trials - number of ptest() trials (default 25)
*
* returns:
* the previous random state
* the previous random state
*
* NOTE: The [10^20, 10^314) range comes from the fact that the 13th internal
* modulus is ~10^315. We want the lower bound seed to be reasonably big.
* modulus is ~10^315. We want the lower bound seed to be reasonably big.
*/
define seedrandom(seed1, seed2, size, trials)
{
local p; /* first Blum prime */
local fp; /* prime co-factor of p-1 */
local sp; /* min bit size of p */
local q; /* second Blum prime */
local fq; /* prime co-factor of q-1 */
local sq; /* min bit size of q */
local n; /* Blum modulus */
local binsize; /* smallest power of 2 > n=p*q */
local r; /* initial quadratic residue */
local random_state; /* the initial rand state */
local random_junk; /* rand state that is not needed */
local old_state; /* old random state to return */
local p; /* first Blum prime */
local fp; /* prime co-factor of p-1 */
local sp; /* min bit size of p */
local q; /* second Blum prime */
local fq; /* prime co-factor of q-1 */
local sq; /* min bit size of q */
local n; /* Blum modulus */
local binsize; /* smallest power of 2 > n=p*q */
local r; /* initial quadratic residue */
local random_state; /* the initial rand state */
local random_junk; /* rand state that is not needed */
local old_state; /* old random state to return */
/*
* firewall
*/
if (!isint(seed1)) {
quit "1st arg (seed1) is not an int";
}
if (!isint(seed2)) {
quit "2nd arg (seed2) is not an int";
}
if (!isint(size)) {
quit "3rd arg (size) is not an int";
}
if (!isint(trials)) {
trials = 25;
}
if (digits(seed1) <= 20) {
quit "1st arg (seed1) must be > 10^20 and perhaps < 10^314";
}
if (digits(seed2) <= 20) {
quit "2nd arg (seed2) must be > 10^20 and perhaps < 10^314";
}
if (size < 32) {
quit "3rd arg (size) needs to be >= 32 (perhaps >= 512)";
}
if (trials < 1) {
quit "4th arg (trials) must be > 0";
}
/*
* firewall
*/
if (!isint(seed1)) {
quit "1st arg (seed1) is not an int";
}
if (!isint(seed2)) {
quit "2nd arg (seed2) is not an int";
}
if (!isint(size)) {
quit "3rd arg (size) is not an int";
}
if (!isint(trials)) {
trials = 25;
}
if (digits(seed1) <= 20) {
quit "1st arg (seed1) must be > 10^20 and perhaps < 10^314";
}
if (digits(seed2) <= 20) {
quit "2nd arg (seed2) must be > 10^20 and perhaps < 10^314";
}
if (size < 32) {
quit "3rd arg (size) needs to be >= 32 (perhaps >= 512)";
}
if (trials < 1) {
quit "4th arg (trials) must be > 0";
}
/*
* determine the search parameters
*/
++size; /* convert power of 2 to bit length */
sp = int((size/2)-(size*0.03)+1);
sq = size - sp;
/*
* determine the search parameters
*/
++size; /* convert power of 2 to bit length */
sp = int((size/2)-(size*0.03)+1);
sq = size - sp;
/*
* find the first Blum prime
*/
random_state = srandom(seed1, 13);
do {
do {
fp = nextcand(2^sp+randombit(sp), 1, 1, 3, 4);
p = 2*fp+1;
} while (ptest(p,1,0) == 0);
} while(ptest(p, trials) == 0 || ptest(fp, trials) == 0);
if (config("resource_debug") & 8) {
print "/* 1st Blum prime */ p=", p;
}
/*
* find the first Blum prime
*/
random_state = srandom(seed1, 13);
do {
do {
fp = nextcand(2^sp+randombit(sp), 1, 1, 3, 4);
p = 2*fp+1;
} while (ptest(p,1,0) == 0);
} while(ptest(p, trials) == 0 || ptest(fp, trials) == 0);
if (config("resource_debug") & 8) {
print "/* 1st Blum prime */ p=", p;
}
/*
* find the 2nd Blum prime
*/
random_junk = srandom(seed2, 13);
do {
do {
fq = nextcand(2^sq+randombit(sq), 1, 1, 3, 4);
q = 2*fq+1;
} while (ptest(q,1,0) == 0);
} while(ptest(q, trials) == 0 || ptest(fq, trials) == 0);
if (config("resource_debug") & 8) {
print "/* 2nd Blum prime */ q=", q;
}
/*
* find the 2nd Blum prime
*/
random_junk = srandom(seed2, 13);
do {
do {
fq = nextcand(2^sq+randombit(sq), 1, 1, 3, 4);
q = 2*fq+1;
} while (ptest(q,1,0) == 0);
} while(ptest(q, trials) == 0 || ptest(fq, trials) == 0);
if (config("resource_debug") & 8) {
print "/* 2nd Blum prime */ q=", q;
}
/*
* seed the Blum generator
*/
n = p*q; /* the Blum modulus */
binsize = highbit(n)+1; /* smallest power of 2 > p*q */
r = pmod(rand(1<<ceil(binsize*4/5), 1<<(binsize-2)), 2, n);
if (config("resource_debug") & 8) {
print "/* seed quadratic residue */ r=", r;
print "/* newn", binsize, "bit quadratic residue*/ newn=", n;
}
old_state = srandom(r, n);
/*
* seed the Blum generator
*/
n = p*q; /* the Blum modulus */
binsize = highbit(n)+1; /* smallest power of 2 > p*q */
r = pmod(rand(1<<ceil(binsize*4/5), 1<<(binsize-2)), 2, n);
if (config("resource_debug") & 8) {
print "/* seed quadratic residue */ r=", r;
print "/* newn", binsize, "bit quadratic residue*/ newn=", n;
}
old_state = srandom(r, n);
/*
* restore other states that we altered
*/
random_junk = srandom(random_state);
/*
* restore other states that we altered
*/
random_junk = srandom(random_state);
/*
* return the previous random state
*/
return old_state;
/*
* return the previous random state
*/
return old_state;
}
if (config("resource_debug") & 3) {

View File

@@ -1,7 +1,7 @@
##
## set8700 - dotest line tests for the 8700 set of regress.cal
##
## Copyright (C) 2006 Ernest Bowen and Landon Curt Noll
## Copyright (C) 2006,2021 Ernest Bowen 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
@@ -9,7 +9,7 @@
##
## 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
## 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
@@ -17,11 +17,11 @@
## 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: 2006/05/20 14:10:11
## File existed as early as: 2006
## Under source code control: 2006/05/20 14:10:11
## File existed as early as: 2006
##
## chongo <was here> /\oo/\ http://www.isthe.com/chongo/
## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
## chongo <was here> /\oo/\ http://www.isthe.com/chongo/
## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
strcpy("", "") == ""
@@ -49,7 +49,7 @@ strncpy("ab", "xyz", 3) == "xy"
strcmp("", "") == 0
strcmp("", "a") == -1
strcmp("\n", "\n") == 0
strcmp("\0", "") == 1 ## '\0' treated like other characters
strcmp("\0", "") == 1 ## '\0' treated like other characters
strcmp("ab", "") == 1
strcmp("ab", "a") == 1
strcmp("ab", "ab") == 0
@@ -123,15 +123,15 @@ substr("abcd",5,1) == ""
substr("a\0c\0",2,2) == "\0c" ## '\0' treated like other characters
substr("a\0c\0",2,3) == "\0c\0"
#"" == 0 ## # operator counts number of bits
#"" == 0 ## # operator counts number of bits
#"\0" == 0
# "a" == 3
# "ab" == 6 ## white space ignored
# "ab" == 6 ## white space ignored
# "abc" == 10
# 27 == 4
# 0b1010111011 == 7
7 # 9 == 2 ## 7 # 9 = abs(7 - 9)
7 # 9 == 2 ## 7 # 9 = abs(7 - 9)
3/4 # 2/3 == 1/12
a = 5, a #= 2, a == 3
@@ -159,7 +159,7 @@ set8700_A = 42, protect(set8700_A,1024), set8700_B = set8700_A, protect(set8700_
set8700_A = 6 * 7, protect(set8700_A) == 1024
set8700_A == set8700_B
## Testing matrix protectioon
## Testing matrix protection
set8700_A = mat [3] = {1, 2, list(3,4)}; 1
protect(set8700_A, 65, 1), protect(set8700_A) == 1089
protect(set8700_A[0]) == 65
@@ -181,9 +181,9 @@ protect(set8700_A[2]) == 1024
protect(set8700_A[2][0], 512), protect(set8700_A[2][0]) == 1536
## Testing simple assignment of matrix
set8700_B = set8700_A, protect(set8700_B) == 1024 ## protect(set8700_A) copied
protect(set8700_B[2]) == 1024 ## protect(set8700_A[2]) copied
protect(set8700_B[2][0]) == 1536 ## protect(set8700_A[2][0]) copied
set8700_B = set8700_A, protect(set8700_B) == 1024 ## protect(set8700_A) copied
protect(set8700_B[2]) == 1024 ## protect(set8700_A[2]) copied
protect(set8700_B[2][0]) == 1536 ## protect(set8700_A[2][0]) copied
## copying matrix to list
set8700_B = list(5,6,7), protect(set8700_B) == 1024
@@ -192,18 +192,18 @@ protect(set8700_B[2]) == 0
protect(set8700_A,0), protect(set8700_A) == 0
copy(set8700_A,set8700_B), set8700_B[0] == 1 && set8700_B[1] == 2
set8700_B[2] == list(3,4)
protect(set8700_B) == 1024 ## protect(set8700_A) not copied
protect(set8700_B[0]) == 1024 ## protect(set8700_A[0]) copied
protect(set8700_B[2][0]) == 1536 ## protect(set8700_A[2][0]) copied
protect(set8700_B) == 1024 ## protect(set8700_A) not copied
protect(set8700_B[0]) == 1024 ## protect(set8700_A[0]) copied
protect(set8700_B[2][0]) == 1536 ## protect(set8700_A[2][0]) copied
## copying matrix to matrix
set8700_B = mat[3], protect(set8700_B) == 1024
protect(set8700_B[2]) == 0
copy(set8700_A,set8700_B), set8700_B[0] == 1 && set8700_B[1] == 2
set8700_B[2] == list(3,4)
protect(set8700_B) == 1024 ## protect(set8700_A) not copied
protect(set8700_B[0]) == 1024 ## protect(set8700_A[0]) copied
protect(set8700_B[2][0]) == 1536 ## protect(set8700_A[2][0]) copied
protect(set8700_B) == 1024 ## protect(set8700_A) not copied
protect(set8700_B[0]) == 1024 ## protect(set8700_A[0]) copied
protect(set8700_B[2][0]) == 1536 ## protect(set8700_A[2][0]) copied
## Testing list protection
set8700_A = list(1, 2, list(3,4)), 1
@@ -212,18 +212,18 @@ protect(set8700_A[2]) == 1024
protect(set8700_A[2][0], 512), protect(set8700_A[2][0]) == 1536
## Simple assignment of list
set8700_B = set8700_A, protect(set8700_B) == 1024 ## protect(set8700_A) copied
protect(set8700_B[2]) == 1024 ## protect(set8700_A[2]) copied
protect(set8700_B[2][0]) == 1536 ## protect(set8700_A[2][0]) copied
set8700_B = set8700_A, protect(set8700_B) == 1024 ## protect(set8700_A) copied
protect(set8700_B[2]) == 1024 ## protect(set8700_A[2]) copied
protect(set8700_B[2][0]) == 1536 ## protect(set8700_A[2][0]) copied
## Copying list to list
set8700_B = list(5,6,7), protect(set8700_B) == 1024
protect(set8700_B[2]) == 0
copy(set8700_A,set8700_B), set8700_B[0] == 1 && set8700_B[1] == 2
set8700_B[2] == list(3,4)
protect(set8700_B) == 1024 ## protect(set8700_A) not copied
protect(set8700_B[0]) == 1024 ## protect(set8700_A[0]) copied
protect(set8700_B[2][0]) == 1536 ## protect(set8700_A[2][0]) copied
protect(set8700_B) == 1024 ## protect(set8700_A) not copied
protect(set8700_B[0]) == 1024 ## protect(set8700_A[0]) copied
protect(set8700_B[2][0]) == 1536 ## protect(set8700_A[2][0]) copied
## Copying list to matrix
set8700_B = mat[3], protect(set8700_B) == 1024
@@ -231,8 +231,8 @@ protect(set8700_B[2]) == 0
copy(set8700_A,set8700_B), set8700_B[0] == 1 && set8700_B[1] == 2
set8700_B[2] == list(3,4)
protect(set8700_B) == 1024
protect(set8700_B[0]) == 1024 ## protect(set8700_A[0]) copied
protect(set8700_B[2][0]) == 1536 ## protect(set8700_A[2][0]) copied
protect(set8700_B[0]) == 1024 ## protect(set8700_A[0]) copied
protect(set8700_B[2][0]) == 1536 ## protect(set8700_A[2][0]) copied
## Protecting one element of a list
set8700_A = list(1,4,3,2), protect(set8700_A[1]) == 0
@@ -241,16 +241,16 @@ protect(set8700_A[1], 1024), protect(set8700_A[1]) == 1024
## Testing sort
set8700_A = sort(set8700_A), set8700_A == list(1,2,3,4)
protect(set8700_A[1]) == 0
protect(set8700_A[3]) == 1024 ## status of 4
protect(set8700_A[3]) == 1024 ## status of 4
## Testings reverse
set8700_A = reverse(set8700_A), set8700_A == list(4,3,2,1)
protect(set8700_A[0]) == 1024 ## status of 4
protect(set8700_A[0]) == 1024 ## status of 4
## Testing swap
swap(set8700_A[0], set8700_A[1]), set8700_A == list(3,4,2,1)
protect(set8700_A[0]) == 0 ## status moved
protect(set8700_A[1]) == 1024 ## 4 retains protection
protect(set8700_A[0]) == 0 ## status moved
protect(set8700_A[1]) == 1024 ## 4 retains protection
## Testing list with protected list argument
protect(set8700_A, 0), protect(set8700_A) == 0
@@ -258,23 +258,23 @@ protect(set8700_A, 512), protect(set8700_A) == 512
protect(set8700_A[1]) == 1024
set8700_L = list(1,set8700_A,3), protect(set8700_L) == 0
protect(set8700_L[0]) == 0
protect(set8700_L[1]) == 512 ## protect(set8700_A) copied
protect(set8700_L[1][1]) == 1024 ## protect(set8700_A[1]) copied
protect(set8700_L[1]) == 512 ## protect(set8700_A) copied
protect(set8700_L[1][1]) == 1024 ## protect(set8700_A[1]) copied
## Testing list with "intialization"
## Testing list with "initialization"
set8700_L = list(1,2,3), protect(set8700_L) == 0
protect(set8700_L[0]) | protect(set8700_L[1]) | protect(set8700_L[2]) == 0 ## All zero
protect(set8700_L[0]) | protect(set8700_L[1]) | protect(set8700_L[2]) == 0 ## All zero
set8700_L = {1,set8700_A}, set8700_L[1] == set8700_A
protect(set8700_L[1]) == 512 ## protect(set8700_A) copied
protect(set8700_L[1][1]) == 1024 ## protect(set8700_A[1]) copied
set8700_L[1] = 2, protect(set8700_L[1]) == 512 ## Not changed
protect(set8700_L[1]) == 512 ## protect(set8700_A) copied
protect(set8700_L[1][1]) == 1024 ## protect(set8700_A[1]) copied
set8700_L[1] = 2, protect(set8700_L[1]) == 512 ## Not changed
## Testing matrix with "initialization"
set8700_M = mat[3] = {1,set8700_A}, protect(set8700_M) == 0
protect(set8700_M[0]) == 0
protect(set8700_M[1]) == 512 ## protect(set8700_A) copied
protect(set8700_M[1]) == 512 ## protect(set8700_A) copied
protect(set8700_M[2]) == 0
protect(set8700_M[1][1]) == 1024 ## protect(set8700_A[1]) copied
protect(set8700_M[1][1]) == 1024 ## protect(set8700_A[1]) copied
## Testing push, pop, append, remove
set8700_A = list(1,2), protect(set8700_A,0,1), protect(set8700_A[0]) == 0
@@ -319,12 +319,12 @@ set8700_x == 7
set8700_x-- == error(10388)
protect(set8700_A,0), protect(set8700_A,16), 1
set8700_A = "abcdef", protect(set8700_A) == 16 ## No copy to set8700_A
set8700_A = "abcdef", protect(set8700_A) == 16 ## No copy to set8700_A
protect(set8700_B,0), set8700_B = "xyz", protect(set8700_B) == 0
copy(set8700_B, set8700_A) == error(10226)
set8700_A == "abcdef" ## set8700_A not changed
set8700_A == "abcdef" ## set8700_A not changed
protect(set8700_A,0), copy(set8700_B,set8700_A), set8700_A == "xyzdef"
protect(set8700_B,128), protect(set8700_B) == 128 ## No copy from set8700_B
protect(set8700_B,128), protect(set8700_B) == 128 ## No copy from set8700_B
copy(set8700_B,set8700_A,,,3) == error(10225)
set8700_A == "xyzdef"
protect(set8700_B,0), copy(set8700_B,set8700_A,,,3), set8700_A == "xyzxyz"
@@ -354,7 +354,7 @@ set8700_x = 7, protect(set8700_x,0), protect(set8700_x, 512), 1
set8700_A = {set8700_x,,set8700_x}, protect(set8700_A[0]) == 1536
protect(set8700_A[1]) == 0
protect(set8700_A[2]) == 512
protect(set8700_A,16), protect(set8700_A) == 16 ## No copy to
protect(set8700_A,16), protect(set8700_A) == 16 ## No copy to
set8700_A == (mat[3] = {7,0,7})
set8700_A = {1,2,3}, errno() == 10390;
set8700_A == (mat[3] = {7,0,7})
@@ -368,7 +368,7 @@ set8700_A = list(2,3,5), modify(set8700_A, 7) == error(10406)
protect(set8700_A,2), modify(set8700_A, "set8700_f") == error(10407)
protect(set8700_A,0), modify(set8700_A, "h") == error(10408)
set8700_B = 42, protect(set8700_B,0), modify(set8700_B, "set8700_f") == error(10409)
set8700_A == list(2,3,5) ## set8700_A not affected by failures
set8700_A == list(2,3,5) ## set8700_A not affected by failures
protect(set8700_A,0,1), modify(set8700_A, "set8700_f") == null()
set8700_A == list(4,9,25)
modify(set8700_A,"set8700_g") == null()
@@ -389,7 +389,7 @@ set8700_L = {{1,2,3},{'a','b','c'}}, set8700_L[0] == (mat[3] = {1,0,3})
set8700_L[1] == (mat[3] = {'a','b',0})
set8700_M = mat[2], protect(set8700_M,0), set8700_M = {1,2,3,4}, set8700_M == (mat[2] = {1,2})
set8700_x = 5, set8700_M = {set8700_x++, set8700_x++, set8700_x++, set8700_x++, set8700_x++}, set8700_M == (mat[2] = {5,6})
set8700_x == 10 ## All initialization terms evaluated
set8700_x == 10 ## All initialization terms evaluated
set8700_S = " ", set8700_S = {'a','b','c','d'}, set8700_S == "abc"
set8700_P = obj set8700_point = {1,2,3,4}, set8700_P.set8700_x == 1 && set8700_P.set8700_y == 2 && set8700_P.set8700_z == 3

View File

@@ -28,7 +28,7 @@ define smallfactors(x0)
local d q x flist tuple w;
if (x >= (2 ^ 32) - 1)
return newerror("smallfactors: number must be < 2^32 -1");
return newerror("smallfactors: number must be < 2^32 -1");
tuple = mat[2];
flist = list();
@@ -37,19 +37,19 @@ define smallfactors(x0)
q = 0;
tuple[0] = d;
if (x < 2)
return 0;
return 0;
do {
q = x // d;
while (x == (q * d)) {
tuple[0] = d;
tuple[1]++;
x = floor(q);
q = x // d;
}
d = nextprime(d);
if (tuple[1] > 0)
append(flist, tuple);
tuple = mat[2];
q = x // d;
while (x == (q * d)) {
tuple[0] = d;
tuple[1]++;
x = floor(q);
q = x // d;
}
d = nextprime(d);
if (tuple[1] > 0)
append(flist, tuple);
tuple = mat[2];
} while (d <= x);
return flist;
}
@@ -58,7 +58,7 @@ define printsmallfactors(flist)
{
local k;
for (k = 0; k < size(flist); k++) {
print flist[k][0]:"^":flist[k][1];
print flist[k][0]:"^":flist[k][1];
}
}

View File

@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,10 +17,10 @@
* 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: 1990/02/15 01:50:37
* File existed as early as: before 1990
* Under source code control: 1990/02/15 01:50:37
* File existed as early as: before 1990
*
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
/*
@@ -32,35 +32,35 @@
define solve(low, high, epsilon)
{
local flow, fhigh, fmid, mid, places;
local flow, fhigh, fmid, mid, places;
if (isnull(epsilon))
epsilon = epsilon();
if (epsilon <= 0)
quit "Non-positive epsilon value";
places = highbit(1 + int(1/epsilon)) + 1;
flow = f(low);
if (abs(flow) < epsilon)
return low;
fhigh = f(high);
if (abs(fhigh) < epsilon)
return high;
if (sgn(flow) == sgn(fhigh))
quit "Non-opposite signs";
while (1) {
mid = bround(high - fhigh * (high - low) / (fhigh - flow),
places);
if ((mid == low) || (mid == high))
places++;
fmid = f(mid);
if (abs(fmid) < epsilon)
return mid;
if (sgn(fmid) == sgn(flow)) {
low = mid;
flow = fmid;
} else {
high = mid;
fhigh = fmid;
}
}
if (isnull(epsilon))
epsilon = epsilon();
if (epsilon <= 0)
quit "Non-positive epsilon value";
places = highbit(1 + int(1/epsilon)) + 1;
flow = f(low);
if (abs(flow) < epsilon)
return low;
fhigh = f(high);
if (abs(fhigh) < epsilon)
return high;
if (sgn(flow) == sgn(fhigh))
quit "Non-opposite signs";
while (1) {
mid = bround(high - fhigh * (high - low) / (fhigh - flow),
places);
if ((mid == low) || (mid == high))
places++;
fmid = f(mid);
if (abs(fmid) < epsilon)
return mid;
if (sgn(fmid) == sgn(flow)) {
low = mid;
flow = fmid;
} else {
high = mid;
fhigh = fmid;
}
}
}

File diff suppressed because it is too large Load Diff

83
cal/splitbits.cal Normal file
View File

@@ -0,0 +1,83 @@
/*
* splitbits - split an integer into list on bit boundardies of a fixed size
*
* Copyright (C) 2018,2023 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: 2006/06/07 14:10:11
* File existed as early as: 2006
*
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
/*
* setup splitbits errors
*/
static E_SPLITBITS_1, E_SPLITBITS_2, E_SPLITBITS_3;
if (! iserror(E_SPLITBITS_1)) E_SPLITBITS_1 = newerror("1st argument to splitbits must be an integer");
if (! iserror(E_SPLITBITS_2)) E_SPLITBITS_2 = newerror("2nd argument to splitbits must be an integer");
if (! iserror(E_SPLITBITS_3)) E_SPLITBITS_3 = newerror("2nd argument must be an integer > 0");
/*
* define splitbits function
*/
define splitbits(x, b)
{
local ret; /* list to return */
local mask; /* 2^b-1 */
local x_is_reg = 0; /* true if x < 0 */
/* firewall */
if (! isint(x)) {
return error(E_SPLITBITS_1);
}
if (! isint(b)) {
return error(E_SPLITBITS_2);
}
if (b <= 0) {
return error(E_SPLITBITS_3);
}
/* special case: x == 0 */
if (x == 0) {
return list(0);
}
/* setup for splitting x */
ret = list();
mask = 2^b-1;
if (x < 0) {
x_is_reg = 1;
x = abs(x);
}
/* split x */
while (x > 0) {
printf("%d %x\n", size(ret), x);
if (x_is_reg) {
append(ret, xor(x & mask, mask));
} else {
append(ret, x & mask);
}
x >>= b;
}
/* return list */
return ret;
}

View File

@@ -17,8 +17,8 @@
* 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: 2013/08/11 01:31:28
* File existed as early as: 2013
* Under source code control: 2013/08/11 01:31:28
* File existed as early as: 2013
*/
@@ -371,7 +371,7 @@ define normalcdf(x,mu,sigma){
define probit(p){
if(p<0 || p > 1) return newerror("probit: p out of domain 0<=p<=1");
return sqrt(2)*ervinv(2*p-1);
return sqrt(2)*erfinv(2*p-1);
}
define normalcdfinv(p,mu,sigma){

View File

@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,10 +17,10 @@
* 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: 1990/02/15 01:50:37
* File existed as early as: before 1990
* Under source code control: 1990/02/15 01:50:37
* File existed as early as: before 1990
*
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
/*
@@ -32,30 +32,30 @@
define ss(p)
{
local a, b, i, p4;
local a, b, i, p4;
if (p == 2) {
print "1^2 + 1^2 = 2";
return;
}
if ((p % 4) != 1) {
print p, "is not of the form 4N+1";
return;
}
if (!ptest(p, min(p-2, 10))) {
print p, "is not a prime";
return;
}
p4 = (p - 1) / 4;
i = 2;
do {
a = pmod(i++, p4, p);
} while ((a^2 % p) == 1);
b = p;
while (b^2 > p) {
i = b % a;
b = a;
a = i;
}
print a : "^2 +" , b : "^2 =" , a^2 + b^2;
if (p == 2) {
print "1^2 + 1^2 = 2";
return;
}
if ((p % 4) != 1) {
print p, "is not of the form 4N+1";
return;
}
if (!ptest(p, min(p-2, 10))) {
print p, "is not a prime";
return;
}
p4 = (p - 1) / 4;
i = 2;
do {
a = pmod(i++, p4, p);
} while ((a^2 % p) == 1);
b = p;
while (b^2 > p) {
i = b % a;
b = a;
a = i;
}
print a : "^2 +" , b : "^2 =" , a^2 + b^2;
}

View File

@@ -1,7 +1,7 @@
/*
* sumtimes - runtimes evaluating sums & squares of large lists and mats
* sumtimes - runtime evaluating sums & squares of large lists and mats
*
* Copyright (C) 2006 Ernest Bowen
* Copyright (C) 2006,2021 Ernest Bowen
*
* 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
@@ -9,7 +9,7 @@
*
* 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
* 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
@@ -17,10 +17,10 @@
* 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: 2006/06/22 17:29
* File existed as early as: 2006
* Under source code control: 2006/06/22 17:29
* File existed as early as: 2006
*
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
*/
@@ -160,7 +160,7 @@ define timehmean(N, M = 10) {
v2 = hmean(sumtimes_A);
sumtimes_t2 = usertime();
print v1, v2;
print "List harmonic meanruntimes";
print "List harmonic mean runtimes";
printf('\tStandard "for" loop:\t\t%.4f\n', sumtimes_t1 - sumtimes_t0);
printf('\tUsing builtin "hmean":\t\t%.4f\n', sumtimes_t2 - sumtimes_t1);
}

Some files were not shown because too many files have changed in this diff Show More