mirror of
https://github.com/lcn2/calc.git
synced 2025-08-19 01:13:27 +03:00
Compare commits
301 Commits
2.12.1.2
...
prod-2.14.
Author | SHA1 | Date | |
---|---|---|---|
|
741ea46853 | ||
|
56b6613da8 | ||
|
e9eef2dfa2 | ||
|
0dbf258696 | ||
|
f6d558783a | ||
|
6f27a32f79 | ||
|
d58f605866 | ||
|
b83c5be515 | ||
|
561928a45c | ||
|
7f89af37f5 | ||
|
4470f1f62e | ||
|
8217c49b94 | ||
|
d2cb03b4cc | ||
|
80f13a4e45 | ||
|
1658343227 | ||
|
3f177f2d81 | ||
|
dcd5a987af | ||
|
cb77888045 | ||
|
ce17b267be | ||
|
738dd0334e | ||
|
7ba1dbdc65 | ||
|
ee70c12481 | ||
|
d4970d66ce | ||
|
c3ea3d28a4 | ||
|
3fa34dabfe | ||
|
ffd4422870 | ||
|
b5b2c3f812 | ||
|
f7dadbf1f8 | ||
|
22e123140c | ||
|
1242700601 | ||
|
5b7dfeaf11 | ||
|
b3c015d338 | ||
|
5985ad2f33 | ||
|
e401c9abf1 | ||
|
ad79b6384d | ||
|
862dbd6777 | ||
|
0d31eb6828 | ||
|
c0be37d4e3 | ||
|
4344532c28 | ||
|
0f6efb29bb | ||
|
39c0cba1ca | ||
|
a68e41248f | ||
|
e213cc5072 | ||
|
95ebb60619 | ||
|
e5c8f00adc | ||
|
265713778f | ||
|
4b08a896b0 | ||
|
44f3778af1 | ||
|
8db8f93ae0 | ||
|
e688c22c0e | ||
|
af72992ead | ||
|
9f3a7817d3 | ||
|
dd0610db0a | ||
|
177a5d00d1 | ||
|
a02f8aa9f9 | ||
|
b7d1fb096d | ||
|
48c4f3b948 | ||
|
2023175fcc | ||
|
c54e2648dc | ||
|
faf40b7149 | ||
|
4b2ae40c86 | ||
|
af57104e25 | ||
|
5ae3ca059a | ||
|
cc5fb9a45b | ||
|
5dcadad8b6 | ||
|
9c67ceeed8 | ||
|
7ffbaf922e | ||
|
f9464652fe | ||
|
b30c5c1855 | ||
|
7417f2e776 | ||
|
71138215a9 | ||
|
241f777d07 | ||
|
9d27f0aaa7 | ||
|
a28edba4e9 | ||
|
de47c960d3 | ||
|
c3a51f42e2 | ||
|
f5c5cea8b0 | ||
|
769ac51f8c | ||
|
cdda633369 | ||
|
50f349f4d7 | ||
|
ef00e00328 | ||
|
bb041098bc | ||
|
f794b8d859 | ||
|
bd990cef1f | ||
|
febb9d96b3 | ||
|
13ae9b804e | ||
|
56cc4897d6 | ||
|
eb940e0a21 | ||
|
f3adb35e36 | ||
|
d1d365d7ba | ||
|
af214b166d | ||
|
51b933dfff | ||
|
c4e5007587 | ||
|
c838798f04 | ||
|
23d49a41fe | ||
|
3d300acca1 | ||
|
8f449ba6d2 | ||
|
f4d754b47d | ||
|
fde724aa2d | ||
|
e411a3e6bf | ||
|
7db81649b0 | ||
|
08fe6f13f4 | ||
|
e11d159c81 | ||
|
dfd66be871 | ||
|
27f977b545 | ||
|
2ca6e789ca | ||
|
ff8f921ebc | ||
|
005b78227a | ||
|
b7a42a9d3d | ||
|
3d1e938cb6 | ||
|
8b98a7c1f6 | ||
|
dbf5acf5e8 | ||
|
5fe5ab1c4b | ||
|
e0cd9bb3db | ||
|
f0f6171354 | ||
|
94861cc6d2 | ||
|
286233e28f | ||
|
99ac7836aa | ||
|
6c0c8e0ef6 | ||
|
8aa5f140bf | ||
|
2fcb9a5995 | ||
|
8b018b697d | ||
|
0e269ecd67 | ||
|
a640bc4656 | ||
|
62a95499ef | ||
|
9e92d4a35a | ||
|
459c07b121 | ||
|
ada15fdabc | ||
|
d5de36841a | ||
|
cf419fb329 | ||
|
abf39b34b6 | ||
|
552252371f | ||
|
7570010a04 | ||
|
a9ee753dc6 | ||
|
ca5a81122a | ||
|
554cd97145 | ||
|
806606f284 | ||
|
7c0ebc5887 | ||
|
45665f94a7 | ||
|
cd736fdbd4 | ||
|
f753884008 | ||
|
1d9a4941ce | ||
|
5bde797ba4 | ||
|
ecba35fc26 | ||
|
a4f8f367c3 | ||
|
41b11ab785 | ||
|
3d33c6c6f4 | ||
|
dbd8926022 | ||
|
f7f110b686 | ||
|
ebf065dcb8 | ||
|
6bc0747a71 | ||
|
04861939fc | ||
|
ca0aaa0c3a | ||
|
f5d5319a51 | ||
|
263b8a78ef | ||
|
3c866367c6 | ||
|
09d7080547 | ||
|
f480c8c5df | ||
|
a230431a3b | ||
|
eaec46982d | ||
|
a86d629982 | ||
|
bcbc0cb766 | ||
|
ac0d84eef8 | ||
|
9b4580d861 | ||
|
2085361df1 | ||
|
bf4657c138 | ||
|
1b5636afed | ||
|
7eba99ac29 | ||
|
de6474bf28 | ||
|
55bc690cd1 | ||
|
6dc62c1ab7 | ||
|
0aca07d278 | ||
|
1ab3b2c313 | ||
|
64e2c6a262 | ||
|
eac02835ed | ||
|
33657bb2cc | ||
|
8af0b351ae | ||
|
3260f90a73 | ||
|
b7e15195f9 | ||
|
c02725f036 | ||
|
507fe026e5 | ||
|
486f4c5626 | ||
|
91991bb729 | ||
|
71a116ca6f | ||
|
8b7e01f426 | ||
|
229345ade8 | ||
|
0f902b95cf | ||
|
8684e1be9c | ||
|
ae3a6129b2 | ||
|
2c72570b8d | ||
|
41803b878e | ||
|
a8be58becb | ||
|
067afc140a | ||
|
41128fada9 | ||
|
f5fae012f9 | ||
|
3d25fb30cb | ||
|
8374586275 | ||
|
68c2edf610 | ||
|
d58a55a1ed | ||
|
ccfa797b68 | ||
|
0f030f0759 | ||
|
af59b9dab2 | ||
|
fa173cd9aa | ||
|
1f8269c0e2 | ||
|
51462b8612 | ||
|
9b69648921 | ||
|
c5e416c41f | ||
|
37ad43c7fd | ||
|
a877cb52c0 | ||
|
4bec694df3 | ||
|
4870a7a164 | ||
|
84ccb37bc3 | ||
|
29c6e9325f | ||
|
81a4a4f828 | ||
|
1cdb5172d8 | ||
|
54a7a3f7bc | ||
|
2ea77e6151 | ||
|
5cfa6199e5 | ||
|
da6ccc146f | ||
|
fcfe237375 | ||
|
5fb3db4558 | ||
|
c8705c1198 | ||
|
0558bafcb6 | ||
|
f58277f53d | ||
|
e555a718c0 | ||
|
b29fcf2dd5 | ||
|
4f86703843 | ||
|
07d8bf0f3e | ||
|
b4cd692bae | ||
|
83c898cc2b | ||
|
c585d7aa78 | ||
|
f42a003d04 | ||
|
8da0471f07 | ||
|
1c20261b93 | ||
|
aeb9a9d473 | ||
|
66883b390d | ||
|
ea533659ce | ||
|
9e81971f25 | ||
|
cbbd866535 | ||
|
bf23f82c29 | ||
|
ec5c584785 | ||
|
6bbb8c0e42 | ||
|
438554b0ed | ||
|
61ba4bc5c8 | ||
|
0145883396 | ||
|
f91bfaab70 | ||
|
36ab4fdc1b | ||
|
1cd89398ad | ||
|
bd3a381783 | ||
|
618f42c960 | ||
|
1363b58060 | ||
|
2c659f40ff | ||
|
4c243a69fe | ||
|
f80eee7a09 | ||
|
a044b9325b | ||
|
c028ea478f | ||
|
62bdba6d22 | ||
|
4d9511243c | ||
|
188fd372ea | ||
|
44ffb0eec9 | ||
|
beb13bf89f | ||
|
a31078bbec | ||
|
7ae4f4009c | ||
|
40fc854006 | ||
|
8dd7a3cd2a | ||
|
2726ae9d23 | ||
|
d25186fc52 | ||
|
28d1e35362 | ||
|
1ae2f953d3 | ||
|
ed4b56d1ec | ||
|
cc2f6f7b85 | ||
|
57a22a6f39 | ||
|
85bfa30897 | ||
|
17e3535595 | ||
|
7f125396c1 | ||
|
7cf611bca8 | ||
|
c9fce6a5bb | ||
|
a1c96f95a6 | ||
|
5e6b3cbd3f | ||
|
5bada5fefd | ||
|
0c20c96a7e | ||
|
e054ea87f2 | ||
|
e229393250 | ||
|
a407c7d197 | ||
|
9ea569152a | ||
|
cbcb5801fb | ||
|
bdf495150e | ||
|
b3648f030f | ||
|
71e88bdc91 | ||
|
ca0dd4560b | ||
|
f62d9fa1e6 | ||
|
253b47942f | ||
|
c773ee736f | ||
|
7d0cc52afe | ||
|
2441df7fdc | ||
|
5c565a7cea | ||
|
810e541281 | ||
|
ee30d787ea | ||
|
4e92927183 | ||
|
fb4a03c1f1 | ||
|
81a523043e |
70
.github/ISSUE_TEMPLATE/calc-bug-report.md
vendored
Normal file
70
.github/ISSUE_TEMPLATE/calc-bug-report.md
vendored
Normal 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.2 2022-02-24
|
||||
|
||||
**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 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 make debug output**
|
||||
IMPORTANT: Please attach the output from `make debug`.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, attach screenshots 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 Monterey, contents of /etc/redhat-releaseor /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.
|
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal 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.
|
71
.github/workflows/codeql-analysis.yml
vendored
Normal file
71
.github/workflows/codeql-analysis.yml
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
# 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' ]
|
||||
# Learn more:
|
||||
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
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.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, 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@v1
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
112
.gitignore
vendored
Normal file
112
.gitignore
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
# 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.
|
||||
#
|
||||
.dynamic
|
||||
.hsrc
|
||||
NOTES
|
||||
align32.h
|
||||
args.h
|
||||
cal/.all
|
||||
calc
|
||||
calc.1
|
||||
calc.usage
|
||||
calcerr.c
|
||||
calcerr.h
|
||||
charbit.h
|
||||
conf.h
|
||||
cscript/.all
|
||||
cscript/4dsphere
|
||||
cscript/README
|
||||
cscript/fproduct
|
||||
cscript/mersenne
|
||||
cscript/piforever
|
||||
cscript/plus
|
||||
cscript/powerterm
|
||||
cscript/simple
|
||||
cscript/square
|
||||
custom/.all
|
||||
custom/libcustcalc*
|
||||
endian
|
||||
endian_calc.h
|
||||
fposval.h
|
||||
have_arc4random.h
|
||||
have_ban_pragma.h
|
||||
have_const.h
|
||||
have_environ.h
|
||||
have_fpos.h
|
||||
have_fpos_pos.h
|
||||
have_getpgid.h
|
||||
have_getprid.h
|
||||
have_getsid.h
|
||||
have_gettime.h
|
||||
have_limits.h
|
||||
have_memmv.h
|
||||
have_newstr.h
|
||||
have_offscl.h
|
||||
have_posscl.h
|
||||
have_rusage.h
|
||||
have_stdlib.h
|
||||
have_stdvs
|
||||
have_strdup.h
|
||||
have_string.h
|
||||
have_strlcat.h
|
||||
have_strlcpy.h
|
||||
have_times.h
|
||||
have_uid_t.h
|
||||
have_unistd.h
|
||||
have_unused.h
|
||||
have_urandom.h
|
||||
have_ustat.h
|
||||
help/.all
|
||||
help/COPYING
|
||||
help/COPYING-LGPL
|
||||
help/binding
|
||||
help/bindings
|
||||
help/bug
|
||||
help/bugs
|
||||
help/builtin
|
||||
help/change
|
||||
help/changes
|
||||
help/contrib
|
||||
help/copy
|
||||
help/cscript
|
||||
help/custom_cal
|
||||
help/errorcode
|
||||
help/errorcodes
|
||||
help/full
|
||||
help/funclist
|
||||
help/funclist.c
|
||||
help/libcalc
|
||||
help/man
|
||||
help/new_custom
|
||||
help/question
|
||||
help/questions
|
||||
help/releases
|
||||
help/resource
|
||||
help/type
|
||||
help/usage
|
||||
libcalc*
|
||||
libcustcalc*
|
||||
longbits
|
||||
longbits.h
|
||||
Makefile.our
|
||||
sample_many
|
||||
sample_rand
|
||||
tags
|
||||
terminal.h
|
||||
ver_calc
|
||||
win32/
|
||||
|
||||
# other commonly excluded patterns
|
||||
#
|
||||
*~
|
||||
*.BAK
|
||||
core*
|
||||
.DS_Store
|
||||
*.dSYM/
|
||||
*.[oa]
|
||||
.*.swp
|
||||
*,v
|
195
BUGS
195
BUGS
@@ -1,12 +1,12 @@
|
||||
If you notice something wrong, strange or broken, try rereading:
|
||||
|
||||
README.FIRST
|
||||
HOWTO.INSTALL
|
||||
BUGS (this file)
|
||||
README.FIRST
|
||||
HOWTO.INSTALL
|
||||
BUGS (this file)
|
||||
|
||||
If that does not help, cd to the calc source directory and try:
|
||||
|
||||
make check
|
||||
make check
|
||||
|
||||
Look at the end of the output, it should say something like:
|
||||
|
||||
@@ -15,71 +15,161 @@ 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.
|
||||
Look for the latest release on GitHub:
|
||||
|
||||
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 changges out and see if things get
|
||||
better.
|
||||
|
||||
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
|
||||
|
||||
The calc web site is located at:
|
||||
|
||||
http://www.isthe.com/chongo/tech/comp/calc/index.html
|
||||
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.
|
||||
|
||||
=-=
|
||||
|
||||
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. You can send bug
|
||||
and bug fixes reports to:
|
||||
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:
|
||||
|
||||
calc-bugs at asthe dot com
|
||||
https://github.com/lcn2/calc/pulls
|
||||
|
||||
[[ NOTE: Replace 'at' with @, 'dot' is with . and remove the spaces ]]
|
||||
[[ NOTE: The EMail address uses 'asthe', the web site URL uses 'isthe' ]]
|
||||
=-=
|
||||
|
||||
Your subject must contain the words:
|
||||
If you just want to send us a bug report, we recommend
|
||||
doing so via the GitHub issue process:
|
||||
|
||||
calc bug report
|
||||
https://github.com/lcn2/calc/issues
|
||||
|
||||
You may have additional words in your subject line.
|
||||
If you see an existing issue that matches your problem, look
|
||||
over the notes and if needed, add your own observation,
|
||||
even if you just add to an existing issue:
|
||||
|
||||
When you send your report, please include the following information:
|
||||
I have this issue too
|
||||
|
||||
* a description of the problem
|
||||
* the version of calc you are using (if you cannot get calc
|
||||
to run, then send us the 4 #define lines from version.c)
|
||||
* if you modified calc from an official patch, send me the mods you made
|
||||
* the type of system you were using
|
||||
* the type of compiler you were using
|
||||
* any compiler warnings or errors that you saw
|
||||
* cd to the calc source directory, and type:
|
||||
If you don't see your issue addressed, then on the above
|
||||
GitHub web page, click on this button:
|
||||
|
||||
make debug > debug.out 2>&1 (sh, ksh, bash users)
|
||||
make debug >& debug.out (csh, tcsh users)
|
||||
((New Issue))
|
||||
|
||||
and send the contents of the 'debug.out' file.
|
||||
=-=
|
||||
|
||||
Stack traces from core dumps are useful to send as well.
|
||||
If you prefer to not use GitHub, then you
|
||||
may send bug and bug fixes reports to:
|
||||
|
||||
Fell free to use the above address to send in big fixes (in the form
|
||||
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:
|
||||
|
||||
* 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:
|
||||
|
||||
#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
|
||||
|
||||
* Type and version of the operating system
|
||||
|
||||
* Type and version of compiler
|
||||
|
||||
* Send us all compiler warnings or errors you find
|
||||
|
||||
* 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:
|
||||
|
||||
make debug > debug.out 2>&1
|
||||
|
||||
Fell free to use the above address to send in bug fixes (in the form
|
||||
of a context diff patch).
|
||||
|
||||
=-=
|
||||
|
||||
Known bugs:
|
||||
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. 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.
|
||||
Email your bug reports and hopefully patches to fix them.
|
||||
|
||||
=-=
|
||||
|
||||
mis-features in calc:
|
||||
|
||||
Some problems are not bugs but rarther mis-features / things that could
|
||||
Some problems are not bugs but rather mis-features / things that could
|
||||
work better. The following is a list of mis-features that should be
|
||||
addressed and improved someday.
|
||||
|
||||
* When statement is of the form { ... }, the leading { MUST BE ON
|
||||
THE SAME LINE as the if, for, while or do keyword.
|
||||
|
||||
This works as expected:
|
||||
|
||||
if (expr) {
|
||||
...
|
||||
}
|
||||
|
||||
However this WILL NOT WORK AS EXPECTED:
|
||||
|
||||
if (expr)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
This needs to be changed. See also "help statement", "help unexpected",
|
||||
and "help todo".
|
||||
|
||||
* The chi.cal resource file does not work well with odd degrees
|
||||
of freedom. Can someone improve this algorithm?
|
||||
|
||||
@@ -104,28 +194,7 @@ mis-features in calc:
|
||||
|
||||
=-=
|
||||
|
||||
Problems with old systems that have known work-a-rounds:
|
||||
|
||||
* There is a bug in gcc-2.95 that causes calc, when compiled with -O2,
|
||||
to fail the regression test. The work-a-round is to compile with -O
|
||||
or to use gcc-2.96 or later.
|
||||
|
||||
* There are problems compiling calc on the sparcv9 under 64 bit
|
||||
Solaris. On that platform, gcc-2.96 is able to compile calc, but
|
||||
calc dumps core very early on in startup. It is said that sparcv9
|
||||
support in gcc-2.96 is very unofficial and thus there is no
|
||||
work-a-round for gcc-2-96.
|
||||
|
||||
There is a work-a-round for this architecture us one is using the
|
||||
Solaris CC on the sparcv9. It has been reported that setting the
|
||||
following Makefile variables will produce a working version of
|
||||
calc on the sparcv9 under 64 bit Solaris:
|
||||
|
||||
LCC="cc -xarch=v9"
|
||||
CCWARN="-DFORCE_STDC -w"
|
||||
DEBUG="-fast -xarch=v9"
|
||||
|
||||
## Copyright (C) 1999-2006 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
|
||||
@@ -139,11 +208,7 @@ Problems with old systems that have known work-a-rounds:
|
||||
## 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.
|
||||
##
|
||||
## @(#) $Revision: 29.25 $
|
||||
## @(#) $Id: BUGS,v 29.25 2006/08/20 17:51:25 chongo Exp $
|
||||
## @(#) $Source: /usr/local/src/cmd/calc/RCS/BUGS,v $
|
||||
## 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
|
||||
|
128
CODE_OF_CONDUCT.md
Normal file
128
CODE_OF_CONDUCT.md
Normal 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.
|
100
CONTRIB-CODE
Normal file
100
CONTRIB-CODE
Normal file
@@ -0,0 +1,100 @@
|
||||
Calc is open source. Contributions of code are welcome.
|
||||
|
||||
We welcome and encourage you to send us:
|
||||
|
||||
* 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. (* */* :) )
|
||||
|
||||
In order to consider integrating your code, we need:
|
||||
|
||||
* 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
|
||||
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:
|
||||
|
||||
https://github.com/lcn2/calc/pulls
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
=-=
|
||||
|
||||
See also the calc wishlist by running the calc command:
|
||||
|
||||
; help wishlist
|
||||
|
||||
=-=
|
||||
|
||||
## 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
|
||||
## 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: 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/
|
7
CONTRIBUTING.md
Normal file
7
CONTRIBUTING.md
Normal 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.
|
75
COPYING
75
COPYING
@@ -6,17 +6,13 @@ This file is Copyrighted
|
||||
|
||||
This file is covered under the following Copyright:
|
||||
|
||||
Copyright (C) 1999 Landon Curt Noll
|
||||
Copyright (C) 1999-2021 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.
|
||||
|
||||
# @(#) $Revision: 29.8 $
|
||||
# @(#) $Id: COPYING,v 29.8 2006/05/01 19:16:57 chongo Exp $
|
||||
# @(#) $Source: /usr/local/src/cmd/calc/RCS/COPYING,v $
|
||||
|
||||
=-=
|
||||
-=-
|
||||
|
||||
Calc is covered by the GNU Lesser General Public License
|
||||
--------------------------------------------------------
|
||||
@@ -45,56 +41,14 @@ Calc is covered by the GNU Lesser General Public License
|
||||
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:
|
||||
Public License with calc; if not, write to the following address:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place
|
||||
Suite 330
|
||||
Boston, MA 02111-1307
|
||||
51 Franklin Street
|
||||
Fifth Floor
|
||||
Boston, MA 02110-1301
|
||||
USA
|
||||
|
||||
The contact addresses for calc is as follows:
|
||||
|
||||
Web: http://www.isthe.com/chongo/tech/comp/calc/email.html
|
||||
|
||||
To join the low volume calc mailing list. Send a EMail message to:
|
||||
|
||||
calc-tester-request at asthe dot com
|
||||
|
||||
Your subject must contain the words:
|
||||
|
||||
calc mailing list subscription
|
||||
|
||||
You may have additional words in your subject line.
|
||||
|
||||
Your message body (not the subject) should consist of:
|
||||
|
||||
subscribe calc-tester address
|
||||
end
|
||||
name your_full_name
|
||||
|
||||
where ``address'' is your EMail address and ``your_full_name'' is
|
||||
your full name.
|
||||
|
||||
Feel free to follow the name line with additional EMail text as desired.
|
||||
|
||||
=-=
|
||||
|
||||
Calc bug reports and calc bug fixes should be sent to:
|
||||
|
||||
calc-bugs at asthe dot com
|
||||
|
||||
[[ NOTE: Replace 'at' with @, 'dot' is with . and remove the spaces ]]
|
||||
[[ NOTE: The EMail address uses 'asthe' and the web site URL uses 'isthe' ]]
|
||||
|
||||
Your subject must contain the words:
|
||||
|
||||
calc bug report
|
||||
|
||||
You may have additional words in your subject line.
|
||||
|
||||
=-=
|
||||
|
||||
Calc's relationship to the GNU Lesser General Public License
|
||||
------------------------------------------------------------
|
||||
|
||||
@@ -149,7 +103,7 @@ Calc's relationship to the GNU Lesser General Public License
|
||||
except for the exception files explicitly listed in the ``Calc
|
||||
copyrights and exception files'' section below.
|
||||
|
||||
=-=
|
||||
-=-
|
||||
|
||||
Calc copyrights and exception files
|
||||
-----------------------------------
|
||||
@@ -165,12 +119,12 @@ Calc copyrights and exception files
|
||||
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
|
||||
|
||||
These files are not covered under one of the Copyrights listed above:
|
||||
|
||||
shs1.c shs1.h shs.c shs.h
|
||||
md5.c md5.h COPYING COPYING-LGPL
|
||||
cal/qtime.cal cal/screen.cal
|
||||
sha1.c sha1.h COPYING
|
||||
COPYING-LGPL cal/qtime.cal 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
|
||||
@@ -182,15 +136,14 @@ 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
|
||||
exception files have non-LGPL Copyrights. Other files are under a
|
||||
LGPL Copyright but have different authors.
|
||||
Some of these exception files are in the public domain. Other files
|
||||
are under the LGPL but have different authors that those listed above.
|
||||
|
||||
In all cases one may use and distribute these exception files freely.
|
||||
And because one may freely distribute the LGPL covered files, the
|
||||
entire calc source may be freely used and distributed.
|
||||
|
||||
=-=
|
||||
-=-
|
||||
|
||||
General Copyleft and License info
|
||||
---------------------------------
|
||||
@@ -204,7 +157,7 @@ General Copyleft and License info
|
||||
http://www.gnu.org/copyleft/lesser.html
|
||||
http://www.gnu.org/copyleft/lesser.txt
|
||||
|
||||
=-=
|
||||
-=-
|
||||
|
||||
Why calc did not use the GNU General Public License
|
||||
---------------------------------------------------
|
||||
|
23
COPYING-LGPL
23
COPYING-LGPL
@@ -1,8 +1,8 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
@@ -112,7 +112,7 @@ modification follow. Pay close attention to the difference between a
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
@@ -146,7 +146,7 @@ such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
@@ -432,7 +432,7 @@ decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
@@ -455,7 +455,7 @@ FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
@@ -476,7 +476,7 @@ convey the exclusion of warranty; and each file should have at least the
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@@ -485,7 +485,8 @@ convey the exclusion of warranty; and each file should have at least the
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
@@ -500,5 +501,3 @@ necessary. Here is a sample; alter the names:
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
||||
|
423
HOWTO.INSTALL
423
HOWTO.INSTALL
@@ -1,10 +1,23 @@
|
||||
Installing calc from the gziped tarball in 4 easy steps:
|
||||
|
||||
0) If your platform supports i686 RPMs, you may want to go to:
|
||||
IMPORTANT: Please see the section at the bottom of this file for
|
||||
some important information on Makefiles used in calc.
|
||||
|
||||
http://www.isthe.com/chongo/src/calc/
|
||||
###################################################################
|
||||
# IMPORTANT: DO NOT use make in parallel mode!!! #
|
||||
###################################################################
|
||||
# Unfortunately due to the complex dependency issues between #
|
||||
# Makefile, Makefile.ship and custom/Makefile, parallel make #
|
||||
# is NOT recommended. Sorry (tm Canada) :) #
|
||||
###################################################################
|
||||
|
||||
and use these RPMs:
|
||||
Installing calc from the bzip2-ed tarball: 4 easy steps:
|
||||
|
||||
(0) If your platform supports i686 RPMs, you may want to go to:
|
||||
|
||||
https://github.com/lcn2/calc/releases
|
||||
|
||||
Open up the 'Assets' tag below a given release and
|
||||
download these RPMs:
|
||||
|
||||
* calc*.i686.rpm
|
||||
- all that is needed if you just want to use calc
|
||||
@@ -13,29 +26,162 @@ Installing calc from the gziped tarball in 4 easy steps:
|
||||
- calc *.h header and *.a lib files for use in other programs
|
||||
|
||||
* calc.*.src.rpm
|
||||
- calc source in RPM package form
|
||||
- calc source via a SRPM package
|
||||
|
||||
The following 4 steps apply to calc source tree that comes from either:
|
||||
Alternately to the above github link, you might try looking at
|
||||
the RPMs under:
|
||||
|
||||
gunzip -c calc-*.tar.gz | tar -xvf -
|
||||
http://www.isthe.com/chongo/src/calc/
|
||||
|
||||
or from:
|
||||
=-=
|
||||
|
||||
rpm -ivh calc-*.src.rpm
|
||||
cd /var/tmp
|
||||
gunzip -c /usr/src/redhat/SOURCES/calc-*.tar.gz | tar -xvf -
|
||||
The following 4 steps apply to calc source tree that comes from either:
|
||||
|
||||
1) Look at the makefile, and adjust it to suit your needs.
|
||||
bunzip2 -c calc-*.tar.bz2 | tar -xvf -
|
||||
|
||||
or from:
|
||||
|
||||
rpm -ivh calc-*.src.rpm
|
||||
cd /var/tmp
|
||||
bunzip2 -c /usr/src/redhat/SOURCES/calc-*.tar.bz2 | tar -xvf -
|
||||
|
||||
4 steps:
|
||||
|
||||
(1) Look at the makefile, and adjust it to suit your needs.
|
||||
|
||||
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.
|
||||
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
! By default, calc assumes you have the readline package installed !
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
! macOS does not have readline, so mac users need to make a choice !
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
The readline package (-lreadline, -lhistory, -lncurses) used by and
|
||||
linked into calc by default. If your system does NOT have those
|
||||
libaraies, then you have two options:
|
||||
|
||||
(1-with readline) Install the readline package <- Recommended
|
||||
|
||||
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/
|
||||
|
||||
(1-w/o readline) Compile calc without readline (not recommended)
|
||||
|
||||
Why do we not recommend (1b)? 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 change your calc Makefile with this patch:
|
||||
|
||||
--- Makefile.old 2021-12-29 14:57:56.000000000 -0800
|
||||
+++ Makefile 2021-12-29 14:59:13.000000000 -0800
|
||||
@@ -1140,14 +1140,14 @@
|
||||
#
|
||||
# If in doubt, set USE_READLINE, READLINE_LIB and READLINE_INCLUDE to nothing.
|
||||
#
|
||||
-#USE_READLINE=
|
||||
-USE_READLINE= -DUSE_READLINE
|
||||
+USE_READLINE=
|
||||
+#USE_READLINE= -DUSE_READLINE
|
||||
#
|
||||
-#READLINE_LIB=
|
||||
-#READLINE_EXTRAS=
|
||||
+READLINE_LIB=
|
||||
+READLINE_EXTRAS=
|
||||
#
|
||||
-READLINE_LIB= -lreadline
|
||||
-READLINE_EXTRAS= -lhistory -lncurses
|
||||
+#READLINE_LIB= -lreadline
|
||||
+#READLINE_EXTRAS= -lhistory -lncurses
|
||||
#
|
||||
#READLINE_LIB= -L/usr/gnu/lib -lreadline
|
||||
#READLINE_EXTRAS= -lhistory -lncurses
|
||||
@@ -1181,8 +1181,8 @@
|
||||
# # and using the readline, history, and ncurses libraries.
|
||||
# #
|
||||
ifneq ($(HOMEBREW_PREFIX),)
|
||||
-READLINE_LIB:= -L${HOMEBREW_PREFIX}/opt/readline/lib -lreadline
|
||||
-READLINE_INCLUDE:= -I${HOMEBREW_PREFIX}/opt/readline/include
|
||||
+#READLINE_LIB:= -L${HOMEBREW_PREFIX}/opt/readline/lib -lreadline
|
||||
+#READLINE_INCLUDE:= -I${HOMEBREW_PREFIX}/opt/readline/include
|
||||
endif
|
||||
#
|
||||
#endif /* end of skip for non-Gnu makefiles */
|
||||
|
||||
If your target system does not have a modern Makefile
|
||||
(such as gmake), then you will need to change your
|
||||
Makefile.simple with this patch:
|
||||
|
||||
--- Makefile.simple.orig 2021-12-29 15:00:53.000000000 -0800
|
||||
+++ Makefile.simple 2021-12-29 15:01:00.000000000 -0800
|
||||
@@ -1005,14 +1005,14 @@
|
||||
#
|
||||
# If in doubt, set USE_READLINE, READLINE_LIB and READLINE_INCLUDE to nothing.
|
||||
#
|
||||
-#USE_READLINE=
|
||||
-USE_READLINE= -DUSE_READLINE
|
||||
+USE_READLINE=
|
||||
+#USE_READLINE= -DUSE_READLINE
|
||||
#
|
||||
-#READLINE_LIB=
|
||||
-#READLINE_EXTRAS=
|
||||
+READLINE_LIB=
|
||||
+READLINE_EXTRAS=
|
||||
#
|
||||
-READLINE_LIB= -lreadline
|
||||
-READLINE_EXTRAS= -lhistory -lncurses
|
||||
+#READLINE_LIB= -lreadline
|
||||
+#READLINE_EXTRAS= -lhistory -lncurses
|
||||
#
|
||||
#READLINE_LIB= -L/usr/gnu/lib -lreadline
|
||||
#READLINE_EXTRAS= -lhistory -lncurses
|
||||
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
! By default, calc assumes you are using a modern gnu-like make tool !
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
If your target system does not have a modern 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.
|
||||
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
! If you are building under Windoz or a Windoz-like environment !
|
||||
! (such as Cygwin or DJGPP), read the README.WINDOWS file. !
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
If you are using a modern make (such as gmake), you may override
|
||||
any values set in the Makefile by adding them to Makefile.local
|
||||
using the := directive. For example:
|
||||
|
||||
HAVE_STRING_H:= YES
|
||||
HAVE_TIMES_H:= YES
|
||||
SED:= /usr/local/bin/nsed
|
||||
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
! If you are building under Windows or a Windows-like environment !
|
||||
! (such as Cygwin or DJGPP), read the README.WINDOWS file. !
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
You should determine if these Makefile variables are reasonable:
|
||||
|
||||
@@ -43,7 +189,7 @@ Installing calc from the gziped tarball in 4 easy steps:
|
||||
BINDIR Where to install calc binary files.
|
||||
LIBDIR Where to install calc link library (*.a) files.
|
||||
CALC_SHAREDIR Where to install calc help, .cal, startup, and
|
||||
config files.
|
||||
config files.
|
||||
|
||||
You may want to change the default installation locations for
|
||||
these values, which are based on the 4 values listed above:
|
||||
@@ -52,25 +198,25 @@ Installing calc from the gziped tarball in 4 easy steps:
|
||||
CALC_INCDIR where the calc include files are installed
|
||||
CUSTOMCALDIR where custom *.cal files are installed
|
||||
CUSTOMHELPDIR where custom help files are installed
|
||||
CUSTOMINCPDIR where custom .h 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
|
||||
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
|
||||
BINDIR= /usr/bin
|
||||
LIBDIR= /usr/lib
|
||||
CALC_SHAREDIR= /usr/share/calc
|
||||
|
||||
and if:
|
||||
|
||||
T= /var/tmp/testing
|
||||
T= /var/tmp/testing
|
||||
|
||||
Then the installation locations will be:
|
||||
|
||||
@@ -79,10 +225,10 @@ Installing calc from the gziped tarball in 4 easy steps:
|
||||
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 ${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.
|
||||
|
||||
Look for the section that starts:
|
||||
|
||||
@@ -96,7 +242,7 @@ Installing calc from the gziped tarball in 4 easy steps:
|
||||
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 Makrfile variables from their defaults:
|
||||
You may want to change these Makefile variables from their defaults:
|
||||
|
||||
RANLIB
|
||||
|
||||
@@ -124,7 +270,21 @@ Installing calc from the gziped tarball in 4 easy steps:
|
||||
|
||||
Adjust other Makefile variables as needed.
|
||||
|
||||
2) build calc:
|
||||
(2) build calc:
|
||||
|
||||
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.
|
||||
|
||||
If your target system does not have GNU Make (or equivalent), 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
|
||||
|
||||
make all
|
||||
|
||||
@@ -132,21 +292,204 @@ Installing calc from the gziped tarball in 4 easy steps:
|
||||
you may find. See the BUGS file if you find any compiler
|
||||
warning or errors.
|
||||
|
||||
3) test calc:
|
||||
NOTE: You can force calc to build with only static libs:
|
||||
|
||||
make check
|
||||
make clobber
|
||||
make calc-static-only BLD_TYPE=calc-static-only
|
||||
|
||||
==> If you run into problems, read the BUGS file and follow
|
||||
the instructions found in there.
|
||||
or force calc to build with only dynamic libs:
|
||||
|
||||
4) install calc:
|
||||
make clobber
|
||||
make calc-dynamic-only BLD_TYPE=calc-dynamic-only
|
||||
|
||||
make install
|
||||
(3) test calc:
|
||||
|
||||
We suggest that you might want to read the README file and look at
|
||||
the calc help subsystem. See the README file for details.
|
||||
make check
|
||||
|
||||
## Copyright (C) 1999 Landon Curt Noll
|
||||
NOTE: For a quiet check which only prints if something goes wrong:
|
||||
|
||||
make chk
|
||||
|
||||
(4) install calc:
|
||||
|
||||
make install
|
||||
|
||||
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:
|
||||
|
||||
How to tell the origin of of a Makefile:
|
||||
|
||||
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 sh may be a much better alternative
|
||||
shell for this Makefile to use:
|
||||
|
||||
SHELL= /bin/sh
|
||||
|
||||
Makefile.local
|
||||
|
||||
# SRC: Makefile.local - tweaks to the top level Makefile
|
||||
|
||||
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.
|
||||
|
||||
If the Makefile is not suitable for you (say because you fetch it
|
||||
from the top of the master branch between releases), then you may
|
||||
wish to remove all non-comment lines. I.e., lines that do not start
|
||||
with the # character.
|
||||
|
||||
This Makefile.local 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 the calc GitHub repo, Makefile is the calc build environment
|
||||
and Makefile.ship is the top level Makefile:
|
||||
|
||||
https://github.com/lcn2/calc
|
||||
|
||||
Makefile
|
||||
|
||||
# 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 */
|
||||
|
||||
Makefile.simple
|
||||
|
||||
# SRC: Makefile.simple - non-GNU version
|
||||
|
||||
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
|
||||
|
||||
# SRC: Makefile via make -f Makefile custom/Makefile
|
||||
|
||||
This is the custom directory Makefile.
|
||||
|
||||
custom/Makefile.simple
|
||||
|
||||
# SRC: custom/Makefile.simple - non-GNU version
|
||||
|
||||
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
|
||||
##
|
||||
## 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
|
||||
@@ -160,11 +503,7 @@ the calc help subsystem. See the README file for 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.
|
||||
##
|
||||
## @(#) $Revision: 29.7 $
|
||||
## @(#) $Id: HOWTO.INSTALL,v 29.7 2003/04/15 03:38:34 chongo Exp $
|
||||
## @(#) $Source: /usr/local/src/cmd/calc/RCS/HOWTO.INSTALL,v $
|
||||
## 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
|
||||
|
263
LIBRARY
263
LIBRARY
@@ -58,13 +58,18 @@ External programs most likely want to use the installed calc header
|
||||
files under ${INCDIRCALC}. External programs most likely NOT want
|
||||
to define CALC_SRC.
|
||||
|
||||
You need to include the following file to get the symbols and variables
|
||||
related to error handling:
|
||||
|
||||
lib_calc.h
|
||||
|
||||
External programs may want to compile with:
|
||||
|
||||
-L${LIBDIR} -lcalc
|
||||
-I${INCDIR} -L${LIBDIR} -lcalc
|
||||
|
||||
If custom functions are also used, they may want to compile with:
|
||||
|
||||
-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:
|
||||
@@ -73,71 +78,215 @@ feeling pedantic you may want to force CALC_SRC to be undefined:
|
||||
|
||||
as well.
|
||||
|
||||
--------------
|
||||
ERROR HANDLING
|
||||
--------------
|
||||
-------------------
|
||||
MATH ERROR HANDLING
|
||||
-------------------
|
||||
|
||||
Your program MUST provide a function called math_error. This is called by
|
||||
the math routines on an error condition, such as malloc failures or a
|
||||
division by zero. The routine is called in the manner of printf, with a
|
||||
format string and optional arguments. (However, none of the low level math
|
||||
routines currently uses formatting, so if you are lazy you can simply use
|
||||
the first argument as a simple error string.) For example, one of the
|
||||
error calls you might expect to receive is:
|
||||
The math_error() function is called by the math routines on an error
|
||||
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:
|
||||
|
||||
math_error("Division by zero");
|
||||
void math_error(char *fmt, ...);
|
||||
|
||||
Your program can handle errors in basically one of two ways. Firstly, it
|
||||
can simply print the error message and then exit. Secondly, you can make
|
||||
use of setjmp and longjmp in your program. Use setjmp at some appropriate
|
||||
level in your program, and use longjmp in the math_error routine to return
|
||||
to that level and so recover from the error. This is what the calc program
|
||||
does.
|
||||
Your program must handle math errors in one of three ways:
|
||||
|
||||
For convenience, the link library libcalc.a contains a math_error routine.
|
||||
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.
|
||||
1) Print the error message and then exit
|
||||
|
||||
External programs that wish to use this math_error may want to compile with:
|
||||
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.
|
||||
|
||||
-I${LIBDIR} -L${LIBDIR} -lcalc
|
||||
2) Use setjmp and longjmp in your program
|
||||
|
||||
If one sets up calc_jmp_buf, and then sets calc_jmp to non-zero then
|
||||
this routine will longjmp back (with the value of calc_jmp) instead.
|
||||
In addition, the last calc error message will be found in calc_error;
|
||||
this error is not printed to stderr. The calc error message will
|
||||
not have a trailing newline.
|
||||
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.
|
||||
|
||||
For example:
|
||||
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.
|
||||
|
||||
#include <setjmp.h>
|
||||
For example:
|
||||
|
||||
extern jmp_buf calc_jmp_buf;
|
||||
extern int calc_jmp;
|
||||
extern char *calc_error;
|
||||
int error;
|
||||
#include <setjmp.h>
|
||||
#include "lib_calc.h"
|
||||
|
||||
...
|
||||
int error;
|
||||
|
||||
if ((error = setjmp(calc_jmp_buf)) != 0) {
|
||||
...
|
||||
|
||||
/* reinitialize calc after a longjmp */
|
||||
reinitialize();
|
||||
if ((error = setjmp(calc_matherr_jmpbuf)) != 0) {
|
||||
|
||||
/* report the error */
|
||||
printf("Ouch: %s\n", calc_err_msg);
|
||||
|
||||
/* 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.
|
||||
|
||||
3) Supply your own math_error function:
|
||||
|
||||
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.
|
||||
|
||||
External programs can obtain the appropriate calc symbols by compiling with:
|
||||
|
||||
-I${INCDIR} -L${LIBDIR} -lcalc
|
||||
|
||||
-------------------------
|
||||
PARSE/SCAN ERROR HANDLING
|
||||
-------------------------
|
||||
|
||||
The scanerror() function is called when calc encounters a parse/scan
|
||||
error. For example, scanerror() is called when calc is given code
|
||||
with a syntax error.
|
||||
|
||||
The variable, calc_print_scanerr_msg, controls if calc prints to stderr,
|
||||
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"
|
||||
|
||||
/* 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];
|
||||
|
||||
The value of calc_print_scanerr_msg does not change the use
|
||||
of the calc_err_msg[] buffer. Messages are stored in that
|
||||
buffer regardless of the calc_print_scanerr_msg value.
|
||||
|
||||
The calc_print_scanerr_msg and the calc_err_msg[] buffer are declared
|
||||
lib_calc.h include file. The initialized storage for these variables
|
||||
comes from the calc library. The MAXERROR symbol is also declared in
|
||||
the lib_calc.h include file.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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:
|
||||
|
||||
#include <setjmp.h>
|
||||
#include "lib_calc.h"
|
||||
|
||||
int scan_error;
|
||||
|
||||
...
|
||||
|
||||
/* delay the printing of the parse/scan error */
|
||||
calc_use_scanerr_jmpbuf = 0; /* this is optional */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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.
|
||||
|
||||
External programs can obtain the appropriate calc symbols by compiling with:
|
||||
|
||||
-I${INCDIR} -L${LIBDIR} -lcalc
|
||||
|
||||
---------------------------
|
||||
PARSE/SCAN WARNING HANDLING
|
||||
---------------------------
|
||||
|
||||
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, ...);
|
||||
|
||||
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"
|
||||
|
||||
/* 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];
|
||||
|
||||
The value of calc_print_scanwarn_msg does not change the use
|
||||
of the calc_warn_msg[] buffer. Messages are stored in that
|
||||
buffer regardless of the calc_print_scanwarn_msg value.
|
||||
|
||||
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.
|
||||
|
||||
2) Supply your own warning function:
|
||||
|
||||
void warning(char *fmt, ...);
|
||||
|
||||
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
|
||||
|
||||
/* report the error */
|
||||
printf("Ouch: %s\n", calc_error);
|
||||
}
|
||||
calc_jmp = 1;
|
||||
|
||||
---------------
|
||||
OUTPUT ROUTINES
|
||||
---------------
|
||||
|
||||
The output from the routines in the link library normally goes to stdout. You
|
||||
can divert that output to either another FILE handle, or else to a string.
|
||||
Read the routines in zio.c to see what is available. Diversions can be
|
||||
nested.
|
||||
The output from the routines in the link library normally goes to stdout.
|
||||
You can divert that output to either another FILE handle, or else
|
||||
to a string. Read the routines in zio.c to see what is available.
|
||||
Diversions can be nested.
|
||||
|
||||
You use math_setfp to divert output to another FILE handle. Calling
|
||||
math_setfp with stdout restores output to stdout.
|
||||
@@ -171,10 +320,10 @@ 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,
|
||||
@@ -466,14 +615,14 @@ 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 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
|
||||
@@ -487,11 +636,7 @@ need call libcalc_call_me_last() only once.
|
||||
## 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.
|
||||
##
|
||||
## @(#) $Revision: 29.5 $
|
||||
## @(#) $Id: LIBRARY,v 29.5 2001/06/08 22:57:35 chongo Exp $
|
||||
## @(#) $Source: /usr/local/src/cmd/calc/RCS/LIBRARY,v $
|
||||
## 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
|
||||
|
39
Makefile.local
Normal file
39
Makefile.local
Normal file
@@ -0,0 +1,39 @@
|
||||
#
|
||||
# Makefile.local - local Makefile variables
|
||||
#
|
||||
# This file is included by Makefile after the last Makefile is set and
|
||||
# before the first make rule. This makes this file suitable to override
|
||||
# Makefile variables.
|
||||
#
|
||||
# To replace a Makefile variable, use := symbols. For example:
|
||||
#
|
||||
# CCWERR:= -Werror
|
||||
|
||||
###################################################################
|
||||
# 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. #
|
||||
###################################################################
|
||||
|
||||
# You can append to an existing Makefile variable using '+=' symbols.
|
||||
# For example:
|
||||
#
|
||||
# CFLAGS+= -Ofast
|
||||
|
||||
# For example, a AddressSanitizer. You do NOT want to do this by
|
||||
# by default! Do this only if you are debugging with libasan:
|
||||
#
|
||||
# For Linux gcc version 4.8.5 with libasan-4.8.5-4 you might try:
|
||||
#
|
||||
# CDEBUG:= -O0 -g
|
||||
# CFLAGS+= -fsanitize=address -fno-omit-frame-pointer
|
||||
# LDFLAGS+= -fsanitize=address -fno-omit-frame-pointer
|
||||
# CALC_ENV+= ASAN_OPTIONS=detect_stack_use_after_return=1
|
||||
#
|
||||
# For macOS 12.1 with clang version 13.0.0 (clang-1300.0.29.30) you might try:
|
||||
#
|
||||
# CDEBUG:= -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
|
6588
Makefile.simple
Normal file
6588
Makefile.simple
Normal file
File diff suppressed because it is too large
Load Diff
54
QUESTIONS
Normal file
54
QUESTIONS
Normal file
@@ -0,0 +1,54 @@
|
||||
If you have a simple general question about calc, send Email to:
|
||||
|
||||
calc-quest-mail at asthe dot com
|
||||
|
||||
NOTE: Remove spaces and replace 'at' with @, and 'dot' with .
|
||||
|
||||
PLEASE put following the SPECIAL PHRASE somewhere in your Email Subject line:
|
||||
|
||||
calc question
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
about calc.
|
||||
|
||||
Please be patient as we cannot always respond to Email messages quickly.
|
||||
|
||||
=-=
|
||||
|
||||
## 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/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/
|
@@ -32,30 +32,30 @@ something that you type in.
|
||||
|
||||
For list of help topics:
|
||||
|
||||
> help
|
||||
; help
|
||||
|
||||
For overview of calc overview:
|
||||
|
||||
> help intro
|
||||
> help overview
|
||||
> help command
|
||||
> help define
|
||||
> help statement
|
||||
> help variable
|
||||
> help usage
|
||||
; help intro
|
||||
; help overview
|
||||
; help command
|
||||
; help define
|
||||
; help statement
|
||||
; help variable
|
||||
; help usage
|
||||
|
||||
For list of builtin functions:
|
||||
|
||||
> help builtin
|
||||
; help builtin
|
||||
|
||||
C programmers should note some unexpected differences in the calc syntax:
|
||||
|
||||
> help unexpected
|
||||
; help unexpected
|
||||
|
||||
Calc is shipped with a standard collection of calc resource files.
|
||||
For a list of calc standard resource files see:
|
||||
|
||||
> help resource
|
||||
; help resource
|
||||
|
||||
=-=
|
||||
|
||||
@@ -71,54 +71,33 @@ or run:
|
||||
|
||||
for a wish/todo list. Code contributions are welcome.
|
||||
|
||||
=-=
|
||||
-=-
|
||||
|
||||
To join the calc-tester mailing list. Send an EMail message to:
|
||||
If you you notice something wrong, strange or broken, see the file:
|
||||
|
||||
calc-tester-request at asthe dot com
|
||||
BUGS
|
||||
|
||||
[[ NOTE: Replace 'at' with @, 'dot' is with . and remove the spaces ]]
|
||||
[[ NOTE: The EMail address uses 'asthe' and the web site URL uses 'isthe' ]]
|
||||
or run:
|
||||
|
||||
Your subject must contain the words:
|
||||
calc help bugs
|
||||
|
||||
calc mailing list subscription
|
||||
for information about how to report a bug.
|
||||
|
||||
You may have additional words in your subject line.
|
||||
-=-
|
||||
|
||||
Your message body (not the subject) should consist of:
|
||||
If you have a general question about calc, see the file:
|
||||
|
||||
subscribe calc-tester address
|
||||
end
|
||||
name your_full_name
|
||||
QUESTIONS
|
||||
|
||||
where ``address'' is your EMail address and ``your_full_name'' is
|
||||
your full name.
|
||||
or run:
|
||||
|
||||
Feel free to follow the name line with additional EMail text as desired.
|
||||
calc help questions
|
||||
|
||||
=-=
|
||||
for information about how to ask a question.
|
||||
|
||||
Send Calc bug and bug fixes to:
|
||||
-=-
|
||||
|
||||
calc-bugs at asthe dot com
|
||||
|
||||
[[ NOTE: Replace 'at' with @, 'dot' is with . and remove the spaces ]]
|
||||
[[ NOTE: The EMail address uses 'asthe' and the web site URL uses 'isthe' ]]
|
||||
|
||||
but see the BUGS file first.
|
||||
|
||||
Your subject must contain the words:
|
||||
|
||||
calc bug report
|
||||
|
||||
You may have additional words in your subject line.
|
||||
|
||||
The calc web site is located at:
|
||||
|
||||
http://www.isthe.com/chongo/tech/comp/calc/
|
||||
|
||||
## Copyright (C) 1999 Landon Curt Noll
|
||||
## Copyright (C) 1999,2014,2017,2021 Landon Curt Noll
|
||||
##
|
||||
## Calc is open software; you can redistribute it and/or modify it under
|
||||
## the terms of the version 2.1 of the GNU Lesser General Public License
|
||||
@@ -132,11 +111,7 @@ The calc web site is located at:
|
||||
## 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.
|
||||
##
|
||||
## @(#) $Revision: 29.3 $
|
||||
## @(#) $Id: README,v 29.3 2001/06/01 11:26:53 chongo Exp $
|
||||
## @(#) $Source: /usr/local/src/cmd/calc/RCS/README,v $
|
||||
## 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
|
117
README.RELEASE
Normal file
117
README.RELEASE
Normal file
@@ -0,0 +1,117 @@
|
||||
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.
|
||||
|
||||
There are 3 classes of changes to the calc source tree:
|
||||
|
||||
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.
|
||||
|
||||
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 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/
|
207
README.WINDOWS
207
README.WINDOWS
@@ -1,14 +1,122 @@
|
||||
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.
|
||||
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.
|
||||
|
||||
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 calc under Windows 11 =-=
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
|
||||
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.
|
||||
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
=-= 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.
|
||||
|
||||
We were told:
|
||||
|
||||
"The Windows Subsystem for Linux (WSL) is a new Windows 10 feature that
|
||||
enables you to run native Linux command-line tools directly on Windows"
|
||||
|
||||
https://docs.microsoft.com/cs-cz/windows/wsl/about
|
||||
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
=-= compiling with Cygwin =-=
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
|
||||
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 =-=
|
||||
@@ -54,9 +162,11 @@ recommends the following settings:
|
||||
CATDIR= /dev/env/DJDIR/man/cat1
|
||||
NROFF= groff
|
||||
CALCPATH= .;./cal;~/.cal;${CALC_SHAREDIR};${CUSTOMCALDIR}
|
||||
CALCRC= ${CALC_SHAREDIR}/startup;~/.calcrc;./.calcinit
|
||||
CALCRC= ./.calcinit;~/.calcrc;${CALC_SHAREDIR}/startup
|
||||
CALCPAGER= less.exe -ci
|
||||
DEBUG= -O2 -gstabs+
|
||||
DEBUG= -O2 -gstabs+ -D_WIN32
|
||||
HAVE_ENVIRON=-DHAVE_NO_ENVIRON
|
||||
HAVE_ARC4RANDOM=-DHAVE_NO_ARC4RANDOM
|
||||
|
||||
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.
|
||||
@@ -68,81 +178,8 @@ Look for Makefile comments of the form:
|
||||
Follow those recommendations. In cases where they conflict with
|
||||
the above Makefile list, follow the recommendation in the Makefile.
|
||||
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
=-= 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 was performed by Thomas Jones-Low
|
||||
(tjoneslo at softstart dot com). He said:
|
||||
|
||||
I had previous stated to this group that I have successfully managed
|
||||
to port a version of Calc to Windows, and promised some point to
|
||||
post what was required, so here it is.
|
||||
|
||||
One obvious manner of doing this port is to get the latest version
|
||||
of the Cygwin project (http://sources.redhat.com/cygwin/) with the
|
||||
GCC compiler and Un*x tools for Windows and recompile.
|
||||
|
||||
I built my working version using Calc ... I am using Visual C++
|
||||
version 7.0, which is an older version of the Microsoft development
|
||||
tools. The make file provided with Calc is not compatible with
|
||||
NMAKE, so I used the Visual Studio tools to generate another one
|
||||
(not included). Calc is built in two parts, calc.dll, which is the
|
||||
library, and calc.exe which is the command line interface.
|
||||
|
||||
He 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.
|
||||
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
=-=-= calc maintenance folk =-=-=
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
|
||||
People who maintain calc need to keep in mind the following:
|
||||
|
||||
The following was added to opcodes.h, config.h, zmath.h and value.h:
|
||||
|
||||
#if defined(_WIN32)
|
||||
#ifdef _EXPORTING
|
||||
#define DLL __declspec(dllexport)
|
||||
#else
|
||||
#define DLL __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
#else /* Windoz free systems */
|
||||
|
||||
#define DLL
|
||||
|
||||
#endif /* Windoz free systems */
|
||||
|
||||
Then DLL was added in front of all the exported functions. For example:
|
||||
|
||||
extern int configtype(char*);
|
||||
|
||||
was changed to:
|
||||
|
||||
DLL extern int configtype(char*);
|
||||
|
||||
|
||||
## Copyright (C) 2002 Landon Curt Noll and Thomas Jones-Low
|
||||
## Copyright (C) 2002-2009,2021 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
|
||||
@@ -156,11 +193,7 @@ was changed to:
|
||||
## 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.
|
||||
##
|
||||
## @(#) $Revision: 29.12 $
|
||||
## @(#) $Id: README.WINDOWS,v 29.12 2004/07/28 12:52:01 chongo Exp $
|
||||
## @(#) $Source: /usr/local/src/cmd/calc/RCS/README.WINDOWS,v $
|
||||
## 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
|
||||
|
263
README.md
Normal file
263
README.md
Normal file
@@ -0,0 +1,263 @@
|
||||
# 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
|
||||
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.
|
||||
In the simplest case, commands are simply expressions which are
|
||||
evaluated. For example, the following line can be input:
|
||||
|
||||
```sh
|
||||
3 * (4 + 1)
|
||||
```
|
||||
|
||||
and the calculator will print:
|
||||
|
||||
```sh
|
||||
15
|
||||
```
|
||||
|
||||
Calc has the usual collection of arithmetic operators +, -, /, * as
|
||||
well as ^ (exponentiation), % (modulus) and // (integer divide).
|
||||
For example:
|
||||
|
||||
```sh
|
||||
3 * 19^43 - 1
|
||||
```
|
||||
|
||||
will produce:
|
||||
|
||||
```sh
|
||||
29075426613099201338473141505176993450849249622191102976
|
||||
```
|
||||
|
||||
Notice that calc values can be very large. For example:
|
||||
|
||||
```sh
|
||||
2^23209-1
|
||||
```
|
||||
|
||||
will print:
|
||||
|
||||
```sh
|
||||
402874115778988778181873329071 ... many digits ... 3779264511
|
||||
```
|
||||
|
||||
The special '.' symbol (called dot), represents the result of the
|
||||
last command expression, if any. This is of great use when a series
|
||||
of partial results are calculated, or when the output mode is changed
|
||||
and the last result needs to be redisplayed. For example, the above
|
||||
result can be modified by typing:
|
||||
|
||||
```sh
|
||||
. % (2^127-1)
|
||||
```
|
||||
|
||||
and the calculator will print:
|
||||
|
||||
```sh
|
||||
47385033654019111249345128555354223304
|
||||
```
|
||||
|
||||
For more complex calculations, variables can be used to save the
|
||||
intermediate results. For example, the result of adding 7 to the
|
||||
previous result can be saved by typing:
|
||||
|
||||
```sh
|
||||
curds = 15
|
||||
whey = 7 + 2*curds
|
||||
```
|
||||
|
||||
Functions can be used in expressions. There are a great number of
|
||||
pre-defined functions. For example, the following will calculate
|
||||
the factorial of the value of 'whey':
|
||||
|
||||
```sh
|
||||
fact(whey)
|
||||
```
|
||||
|
||||
and the calculator prints:
|
||||
|
||||
```sh
|
||||
13763753091226345046315979581580902400000000
|
||||
```
|
||||
|
||||
The calculator also knows about complex numbers, so that typing:
|
||||
|
||||
```sh
|
||||
(2+3i) * (4-3i)
|
||||
cos(.)
|
||||
```
|
||||
|
||||
will print:
|
||||
|
||||
```sh
|
||||
17+6i
|
||||
-55.50474777265624667147+193.9265235748927986537i
|
||||
```
|
||||
|
||||
The calculator can calculate transcendental functions, and accept and
|
||||
display numbers in real or exponential format. For example, typing:
|
||||
|
||||
```sh
|
||||
config("display", 70),
|
||||
epsilon(1e-70),
|
||||
sin(1)
|
||||
```
|
||||
|
||||
prints:
|
||||
|
||||
```sh
|
||||
0.8414709848078965066525023216302989996225630607983710656727517099919104
|
||||
```
|
||||
|
||||
Calc can output values in terms of fractions, octal or hexadecimal.
|
||||
For example:
|
||||
|
||||
```sh
|
||||
config("mode", "fraction"),
|
||||
(17/19)^23
|
||||
print
|
||||
base(16),
|
||||
(19/17)^29
|
||||
print
|
||||
log(79.3i)
|
||||
```
|
||||
|
||||
will print:
|
||||
|
||||
```sh
|
||||
19967568900859523802559065713/257829627945307727248226067259
|
||||
|
||||
0x9201e65bdbb801eaf403f657efcf863/0x5cd2e2a01291ffd73bee6aa7dcf7d1
|
||||
|
||||
0x17b5164ac24ee836bf/0xc7b7a8e3ef5fcf752+0x883eaf5adadd26be3/0xc7b7a8e3ef5fcf752i
|
||||
```
|
||||
|
||||
All numbers are represented as fractions with arbitrarily large
|
||||
numerators and denominators which are always reduced to lowest terms.
|
||||
Real or exponential format numbers can be input and are converted
|
||||
to the equivalent fraction. Hex, binary, or octal numbers can be
|
||||
input by using numbers with leading '0x', '0b' or '0' characters.
|
||||
Complex numbers can be input using a trailing 'i', as in '2+3i'.
|
||||
Strings and characters are input by using single or double quotes.
|
||||
|
||||
Commands are statements in a C-like language, where each input
|
||||
line is treated as the body of a procedure. Thus the command
|
||||
line can contain variable declarations, expressions, labels,
|
||||
conditional tests, and loops. Assignments to any variable name
|
||||
will automatically define that name as a global variable. The
|
||||
other important thing to know is that all non-assignment expressions
|
||||
which are evaluated are automatically printed. Thus, you can evaluate
|
||||
an expression's value by simply typing it in.
|
||||
|
||||
Many useful built-in mathematical functions are available. Use the:
|
||||
|
||||
```sh
|
||||
help builtin
|
||||
```
|
||||
|
||||
command to list them.
|
||||
|
||||
You can also define your own functions by using the 'define' keyword,
|
||||
followed by a function declaration very similar to C.
|
||||
|
||||
```sh
|
||||
define f2(n)
|
||||
{
|
||||
local ans;
|
||||
|
||||
ans = 1;
|
||||
while (n > 1)
|
||||
ans *= (n -= 2);
|
||||
return ans;
|
||||
}
|
||||
```
|
||||
|
||||
Thus the input:
|
||||
|
||||
```sh
|
||||
f2(79)
|
||||
```
|
||||
|
||||
will produce:
|
||||
|
||||
```sh
|
||||
1009847364737869270905302433221592504062302663202724609375
|
||||
```
|
||||
|
||||
Functions which only need to return a simple expression can be defined
|
||||
using an equals sign, as in the example:
|
||||
|
||||
```sh
|
||||
define sc(a,b) = a^3 + b^3
|
||||
```
|
||||
|
||||
Thus the input:
|
||||
|
||||
```sh
|
||||
sc(31, 61)
|
||||
```
|
||||
|
||||
will produce:
|
||||
|
||||
```sh
|
||||
256772
|
||||
```
|
||||
|
||||
Variables in functions can be defined as either 'global', 'local',
|
||||
or 'static'. Global variables are common to all functions and the
|
||||
command line, whereas local variables are unique to each function
|
||||
level, and are destroyed when the function returns. Static variables
|
||||
are scoped within single input files, or within functions, and are
|
||||
never destroyed. Variables are not typed at definition time, but
|
||||
dynamically change as they are used.
|
||||
|
||||
For more information about the calc language and features, try:
|
||||
|
||||
```sh
|
||||
help overview
|
||||
```
|
||||
|
||||
Calc has a help command that will produce information about
|
||||
every builtin function, command as well as a number of other
|
||||
aspects of calc usage. Try the command:
|
||||
|
||||
```sh
|
||||
help help
|
||||
```
|
||||
|
||||
for and overview of the help system. The command:
|
||||
|
||||
```sh
|
||||
help builtin
|
||||
```
|
||||
|
||||
provides information on built-in mathematical functions, whereas:
|
||||
|
||||
```sh
|
||||
help asinh
|
||||
```
|
||||
|
||||
will provides information a specific function. The following
|
||||
help files:
|
||||
|
||||
```sh
|
||||
help command
|
||||
help define
|
||||
help operator
|
||||
help statement
|
||||
help variable
|
||||
```
|
||||
|
||||
provide a good overview of the calc language. If you are familiar
|
||||
with C, you should also try:
|
||||
|
||||
```sh
|
||||
help unexpected
|
||||
```
|
||||
|
||||
It contains information about differences between C and calc
|
||||
that may surprise C programmers.
|
19
SECURITY.md
Normal file
19
SECURITY.md
Normal 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.
|
55
addop.c
55
addop.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* addop - add opcodes to a function being compiled
|
||||
*
|
||||
* Copyright (C) 1999-2006 David I. Bell and Ernest Bowen
|
||||
* Copyright (C) 1999-2007,2021,2022 David I. Bell and Ernest Bowen
|
||||
*
|
||||
* Primary author: David I. Bell
|
||||
*
|
||||
@@ -17,11 +17,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.13 $
|
||||
* @(#) $Id: addop.c,v 29.13 2006/06/20 10:28:06 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/RCS/addop.c,v $
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Under source code control: 1990/02/15 01:48:10
|
||||
* File existed as early as: before 1990
|
||||
@@ -32,29 +28,34 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include "calc.h"
|
||||
#include "alloc.h"
|
||||
#include "opcodes.h"
|
||||
#include "string.h"
|
||||
#include "str.h"
|
||||
#include "func.h"
|
||||
#include "token.h"
|
||||
#include "label.h"
|
||||
#include "symbol.h"
|
||||
|
||||
|
||||
#include "attribute.h"
|
||||
#include "banned.h" /* include after system header <> includes */
|
||||
|
||||
|
||||
#define FUNCALLOCSIZE 20 /* reallocate size for functions */
|
||||
#define OPCODEALLOCSIZE 100 /* reallocate size for opcodes in functions */
|
||||
|
||||
|
||||
static unsigned long maxopcodes;/* number of opcodes available */
|
||||
static long newindex; /* index of new function */
|
||||
static char *newname; /* name of new function */
|
||||
static long oldop; /* previous opcode */
|
||||
static long oldoldop; /* opcode before previous opcode */
|
||||
static long debugline; /* line number of latest debug opcode */
|
||||
static long funccount; /* number of functions */
|
||||
static long funcavail; /* available number of functions */
|
||||
static FUNC *functemplate; /* function definition template */
|
||||
static FUNC **functions; /* table of functions */
|
||||
static STRINGHEAD funcnames; /* function names */
|
||||
STATIC unsigned long maxopcodes;/* number of opcodes available */
|
||||
STATIC long newindex; /* index of new function */
|
||||
STATIC char *newname; /* name of new function */
|
||||
STATIC long oldop; /* previous opcode */
|
||||
STATIC long oldoldop; /* opcode before previous opcode */
|
||||
STATIC long debugline; /* line number of latest debug opcode */
|
||||
STATIC long funccount; /* number of functions */
|
||||
STATIC long funcavail; /* available number of functions */
|
||||
STATIC FUNC *functemplate; /* function definition template */
|
||||
STATIC FUNC **functions; /* table of functions */
|
||||
STATIC STRINGHEAD funcnames; /* function names */
|
||||
|
||||
|
||||
/*
|
||||
@@ -68,12 +69,12 @@ initfunctions(void)
|
||||
functemplate = (FUNC *) malloc(funcsize(maxopcodes));
|
||||
if (functemplate == NULL) {
|
||||
math_error("Cannot allocate function template");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
functions = (FUNC **) malloc(sizeof(FUNC *) * FUNCALLOCSIZE);
|
||||
if (functions == NULL) {
|
||||
math_error("Cannot allocate function table");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
funccount = 0;
|
||||
funcavail = FUNCALLOCSIZE;
|
||||
@@ -155,7 +156,7 @@ beginfunc(char *name, BOOL newflag)
|
||||
fp = (FUNC *) malloc(funcsize(maxopcodes));
|
||||
if (fp == NULL) {
|
||||
math_error("Cannot allocate temporary function");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
}
|
||||
fp->f_next = NULL;
|
||||
@@ -203,7 +204,7 @@ endfunc(void)
|
||||
fp = (FUNC *) malloc(size);
|
||||
if (fp == NULL) {
|
||||
math_error("Cannot commit function");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
memcpy((char *) fp, (char *) curfunc, size);
|
||||
if (curfunc != functemplate)
|
||||
@@ -257,13 +258,13 @@ adduserfunc(char *name)
|
||||
sizeof(FUNC *) * (funcavail + FUNCALLOCSIZE));
|
||||
if (functions == NULL) {
|
||||
math_error("Failed to reallocate function table");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
funcavail += FUNCALLOCSIZE;
|
||||
}
|
||||
if (addstr(&funcnames, name) == NULL) {
|
||||
math_error("Cannot save function name");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
index = funccount++;
|
||||
functions[index] = NULL;
|
||||
@@ -316,7 +317,7 @@ freefunc(FUNC *fp)
|
||||
}
|
||||
if (index == funccount) {
|
||||
math_error("Bad call to freefunc!!!");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
}
|
||||
if (newname[0] != '*' && (conf->traceflags & TRACE_FNCODES)) {
|
||||
@@ -386,7 +387,7 @@ findfunc(long index)
|
||||
{
|
||||
if (index >= funccount) {
|
||||
math_error("Undefined function");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
return functions[index];
|
||||
}
|
||||
@@ -438,7 +439,7 @@ addop(long op)
|
||||
fp = (FUNC *) malloc(funcsize(maxopcodes));
|
||||
if (fp == NULL) {
|
||||
math_error("cannot malloc function");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
memcpy((char *) fp, (char *) curfunc,
|
||||
funcsize(curfunc->f_opcodecount));
|
||||
|
12
align32.c
12
align32.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* align32 - determine if 32 bit accesses must be aligned
|
||||
*
|
||||
* Copyright (C) 1999 Landon Curt Noll
|
||||
* Copyright (C) 1999,2021 Landon Curt Noll
|
||||
*
|
||||
* Calc is open software; you can redistribute it and/or modify it under
|
||||
* the terms of the version 2.1 of the GNU Lesser General Public License
|
||||
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: align32.c,v 29.2 2000/06/07 14:02:13 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/RCS/align32.c,v $
|
||||
* 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
|
||||
@@ -38,6 +34,10 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "banned.h" /* include after system header <> includes */
|
||||
|
||||
|
||||
static void buserr(void); /* catch alignment errors */
|
||||
|
||||
|
||||
|
69
alloc.h
69
alloc.h
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* alloc - storage allocation and storage debug macros
|
||||
*
|
||||
* Copyright (C) 1999 David I. Bell
|
||||
* Copyright (C) 1999-2007,2014 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
|
||||
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.4 $
|
||||
* @(#) $Id: alloc.h,v 29.4 2001/06/08 21:00:58 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/RCS/alloc.h,v $
|
||||
* 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
|
||||
@@ -28,59 +24,45 @@
|
||||
*/
|
||||
|
||||
|
||||
#if !defined(__ALLOC_H__)
|
||||
#define __ALLOC_H__
|
||||
#if !defined(INCLUDE_ALLOC_H)
|
||||
#define INCLUDE_ALLOC_H
|
||||
|
||||
|
||||
#if defined(CALC_SRC) /* if we are building from the calc source tree */
|
||||
# include "have_malloc.h"
|
||||
# include "have_newstr.h"
|
||||
# include "have_string.h"
|
||||
# include "have_memmv.h"
|
||||
#else
|
||||
# include <calc/have_malloc.h>
|
||||
# include <calc/have_newstr.h>
|
||||
# include <calc/have_string.h>
|
||||
# include <calc/have_memmv.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MALLOC_H
|
||||
# include <malloc.h>
|
||||
#else
|
||||
#if defined(FORCE_STDC) || (defined(__STDC__) && __STDC__ != 0) || defined(__cplusplus)
|
||||
extern void *malloc();
|
||||
extern void *realloc();
|
||||
extern void free();
|
||||
# else
|
||||
extern char *malloc();
|
||||
extern char *realloc();
|
||||
extern void free();
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
|
||||
#else
|
||||
#include <stdio.h>
|
||||
|
||||
# if defined(HAVE_NEWSTR)
|
||||
extern void *memcpy();
|
||||
extern void *memset();
|
||||
#if defined(FORCE_STDC) || (defined(__STDC__) && __STDC__ != 0) || defined(__cplusplus)
|
||||
extern size_t strlen();
|
||||
E_FUNC void *memcpy();
|
||||
E_FUNC void *memset();
|
||||
#if defined(FORCE_STDC) || \
|
||||
(defined(__STDC__) && __STDC__ != 0) || defined(__cplusplus)
|
||||
E_FUNC size_t strlen();
|
||||
# else
|
||||
extern long strlen();
|
||||
E_FUNC long strlen();
|
||||
# endif
|
||||
# else /* HAVE_NEWSTR */
|
||||
extern void bcopy();
|
||||
extern void bfill();
|
||||
extern char *index();
|
||||
E_FUNC void bcopy();
|
||||
E_FUNC void bfill();
|
||||
E_FUNC char *index();
|
||||
# endif /* HAVE_NEWSTR */
|
||||
extern char *strchr();
|
||||
extern char *strcpy();
|
||||
extern char *strncpy();
|
||||
extern char *strcat();
|
||||
extern int strcmp();
|
||||
E_FUNC char *strchr();
|
||||
E_FUNC char *strcpy();
|
||||
E_FUNC char *strncpy();
|
||||
E_FUNC char *strcat();
|
||||
E_FUNC int strcmp();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -94,13 +76,14 @@ extern int strcmp();
|
||||
#endif /* HAVE_NEWSTR */
|
||||
|
||||
#if !defined(HAVE_MEMMOVE)
|
||||
# undef CALC_SIZE_T
|
||||
#if defined(FORCE_STDC) || (defined(__STDC__) && __STDC__ != 0) || defined(__cplusplus)
|
||||
# define CALC_SIZE_T size_t
|
||||
# undef MEMMOVE_SIZE_T
|
||||
#if defined(FORCE_STDC) || \
|
||||
(defined(__STDC__) && __STDC__ != 0) || defined(__cplusplus)
|
||||
# define MEMMOVE_SIZE_T size_t
|
||||
# else
|
||||
# define CALC_SIZE_T long
|
||||
# define MEMMOVE_SIZE_T long
|
||||
# endif
|
||||
extern void *memmove(void *s1, const void *s2, CALC_SIZE_T n);
|
||||
E_FUNC void *memmove(void *s1, CONST void *s2, MEMMOVE_SIZE_T n);
|
||||
#endif
|
||||
|
||||
#endif /* !__ALLOC_H__ */
|
||||
#endif /* !INCLUDE_ALLOC_H */
|
||||
|
58
assocfunc.c
58
assocfunc.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* assocfunc - association table routines
|
||||
*
|
||||
* Copyright (C) 1999 David I. Bell
|
||||
* Copyright (C) 1999-2007,2021,2022 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
|
||||
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: assocfunc.c,v 29.2 2000/06/07 14:02:13 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/RCS/assocfunc.c,v $
|
||||
* 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
|
||||
@@ -40,16 +36,20 @@
|
||||
#include "value.h"
|
||||
|
||||
|
||||
#include "attribute.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)))
|
||||
|
||||
|
||||
static ASSOCELEM *elemindex(ASSOC *ap, long index);
|
||||
static BOOL compareindices(VALUE *v1, VALUE *v2, long dim);
|
||||
static void resize(ASSOC *ap, long newsize);
|
||||
static void assoc_elemfree(ASSOCELEM *ep);
|
||||
S_FUNC ASSOCELEM *elemindex(ASSOC *ap, long index);
|
||||
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);
|
||||
|
||||
|
||||
/*
|
||||
@@ -69,13 +69,13 @@ associndex(ASSOC *ap, BOOL create, long dim, VALUE *indices)
|
||||
{
|
||||
ASSOCELEM **listhead;
|
||||
ASSOCELEM *ep;
|
||||
static VALUE val;
|
||||
STATIC VALUE val;
|
||||
QCKHASH hash;
|
||||
int i;
|
||||
|
||||
if (dim < 0) {
|
||||
math_error("Negative dimension for indexing association");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -83,7 +83,7 @@ associndex(ASSOC *ap, BOOL create, long dim, VALUE *indices)
|
||||
* so that we can first select the correct hash chain, and
|
||||
* also so we can quickly compare each element for a match.
|
||||
*/
|
||||
hash = FNV1_32_BASIS;
|
||||
hash = QUICKHASH_BASIS;
|
||||
for (i = 0; i < dim; i++)
|
||||
hash = hashvalue(&indices[i], hash);
|
||||
|
||||
@@ -113,7 +113,7 @@ associndex(ASSOC *ap, BOOL create, long dim, VALUE *indices)
|
||||
ep = (ASSOCELEM *) malloc(ELEMSIZE(dim));
|
||||
if (ep == NULL) {
|
||||
math_error("Cannot allocate association element");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
ep->e_dim = dim;
|
||||
ep->e_hash = hash;
|
||||
@@ -143,13 +143,13 @@ assocsearch(ASSOC *ap, VALUE *vp, long i, long j, ZVALUE *index)
|
||||
|
||||
if (i < 0 || j > ap->a_count) {
|
||||
math_error("This should not happen in assocsearch");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
while (i < j) {
|
||||
ep = elemindex(ap, i);
|
||||
if (ep == NULL) {
|
||||
math_error("This should not happen in assocsearch");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
if (acceptvalue(&ep->e_value, vp)) {
|
||||
utoz(i, index);
|
||||
@@ -173,14 +173,14 @@ assocrsearch(ASSOC *ap, VALUE *vp, long i, long j, ZVALUE *index)
|
||||
|
||||
if (i < 0 || j > ap->a_count) {
|
||||
math_error("This should not happen in assocsearch");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
j--;
|
||||
while (j >= i) {
|
||||
ep = elemindex(ap, j);
|
||||
if (ep == NULL) {
|
||||
math_error("This should not happen in assocsearch");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
if (acceptvalue(&ep->e_value, vp)) {
|
||||
utoz(j, index);
|
||||
@@ -200,7 +200,7 @@ assocrsearch(ASSOC *ap, VALUE *vp, long i, long j, ZVALUE *index)
|
||||
* ap association to index into
|
||||
* index index of desired element
|
||||
*/
|
||||
static ASSOCELEM *
|
||||
S_FUNC ASSOCELEM *
|
||||
elemindex(ASSOC *ap, long index)
|
||||
{
|
||||
ASSOCELEM *ep;
|
||||
@@ -332,15 +332,17 @@ assoccopy(ASSOC *oldap)
|
||||
oldep = oldep->e_next) {
|
||||
ep = (ASSOCELEM *) malloc(ELEMSIZE(oldep->e_dim));
|
||||
if (ep == NULL) {
|
||||
math_error("Cannot allocate association element");
|
||||
/*NOTREACHED*/
|
||||
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_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;
|
||||
@@ -356,7 +358,7 @@ assoccopy(ASSOC *oldap)
|
||||
* This is only actually done if the growth from the previous size is
|
||||
* enough to make this worthwhile.
|
||||
*/
|
||||
static void
|
||||
S_FUNC void
|
||||
resize(ASSOC *ap, long newsize)
|
||||
{
|
||||
ASSOCELEM **oldtable;
|
||||
@@ -373,7 +375,7 @@ resize(ASSOC *ap, long newsize)
|
||||
newtable = (ASSOCELEM **) malloc(sizeof(ASSOCELEM *) * newsize);
|
||||
if (newtable == NULL) {
|
||||
math_error("No memory to grow association");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
for (i = 0; i < newsize; i++)
|
||||
newtable[i] = NULL;
|
||||
@@ -400,7 +402,7 @@ resize(ASSOC *ap, long newsize)
|
||||
/*
|
||||
* Free an association element, along with any contained values.
|
||||
*/
|
||||
static void
|
||||
S_FUNC void
|
||||
assoc_elemfree(ASSOCELEM *ep)
|
||||
{
|
||||
int i;
|
||||
@@ -429,7 +431,7 @@ assocalloc(long initsize)
|
||||
ap = (ASSOC *) malloc(sizeof(ASSOC));
|
||||
if (ap == NULL) {
|
||||
math_error("No memory for association");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
ap->a_count = 0;
|
||||
ap->a_size = initsize;
|
||||
@@ -437,7 +439,7 @@ assocalloc(long initsize)
|
||||
if (ap->a_table == NULL) {
|
||||
free((char *) ap);
|
||||
math_error("No memory for association");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
for (i = 0; i < initsize; i++)
|
||||
ap->a_table[i] = NULL;
|
||||
@@ -520,7 +522,7 @@ assocprint(ASSOC *ap, long max_print)
|
||||
* Compare two lists of index values to see if they are identical.
|
||||
* Returns TRUE if they are the same.
|
||||
*/
|
||||
static BOOL
|
||||
S_FUNC BOOL
|
||||
compareindices(VALUE *v1, VALUE *v2, long dim)
|
||||
{
|
||||
int i;
|
||||
|
69
attribute.h
Normal file
69
attribute.h
Normal 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 */
|
180
banned.h
Normal file
180
banned.h
Normal file
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* 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 during extremely long calculations.
|
||||
*
|
||||
* If UNBAN is NOT defined, then calling certain functions
|
||||
* will result in a syntax error.
|
||||
*
|
||||
* If we define UNBAN, then the effect of this file is disabled.
|
||||
*
|
||||
* The banned.h attempts to ban the use of certain dangerous functions
|
||||
* that, if improperly used, could compromise the computational integrity
|
||||
* if calculations.
|
||||
*
|
||||
* In the case of calc, we are motivated in part by the desire for calc
|
||||
* 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).
|
||||
*
|
||||
* While we do NOT encourage defining UNBAN, there may be
|
||||
* a system / compiler environment where re-defining a
|
||||
* function may lead to a fatal compiler complication.
|
||||
* If that happens, consider compiling as:
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* or the URL:
|
||||
*
|
||||
* http://www.isthe.com/chongo/tech/comp/calc/calc-bugrept.html
|
||||
*
|
||||
* for how to send us such a bug report.
|
||||
*
|
||||
* 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/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/
|
||||
*/
|
||||
|
||||
|
||||
#if !defined(PRE_HAVE_BAN_PRAGMA_H)
|
||||
#include "have_ban_pragma.h"
|
||||
#endif /* ! PRE_HAVE_BAN_PRAGMA_H */
|
||||
|
||||
|
||||
#if !defined(INCLUDE_BANNED_H)
|
||||
#define INCLUDE_BANNED_H
|
||||
|
||||
/*
|
||||
* If we define UNBAN, then the effect of this file is disabled.
|
||||
*/
|
||||
#if !defined(UNBAN)
|
||||
|
||||
/*
|
||||
* In the spirit of:
|
||||
*
|
||||
* 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 during extremely long
|
||||
* calculations.
|
||||
*
|
||||
* If UNBAN is NOT defined, then calling certain functions
|
||||
* 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
|
||||
* alternative function, we cannot simply replace one function
|
||||
* with another.
|
||||
*/
|
||||
|
||||
/*
|
||||
* If one is not careful, strcpy() can lead to buffer overflows.
|
||||
* Use strlcpy() instead.
|
||||
*/
|
||||
#if defined(HAVE_PRAGMA_GCC_POSION)
|
||||
#undef strcpy
|
||||
#pragma GCC poison strcpy
|
||||
#endif /* HAVE_PRAGMA_GCC_POSION */
|
||||
|
||||
/*
|
||||
* If one is not careful, strcat() can lead to buffer overflows.
|
||||
* Use strlcat() instead.
|
||||
*/
|
||||
#if defined(HAVE_PRAGMA_GCC_POSION)
|
||||
#undef strcat
|
||||
#pragma GCC poison strcat
|
||||
#endif /* HAVE_PRAGMA_GCC_POSION */
|
||||
|
||||
/*
|
||||
* If one is not careful, strncpy() can lead to buffer overflows.
|
||||
* Use memccpy() instead.
|
||||
*/
|
||||
#if defined(HAVE_PRAGMA_GCC_POSION)
|
||||
#undef strncpy
|
||||
#pragma GCC poison strncpy
|
||||
#endif /* HAVE_PRAGMA_GCC_POSION */
|
||||
|
||||
/*
|
||||
* If one is not careful, strncat() can lead to buffer overflows.
|
||||
* Use memccpy() instead.
|
||||
*/
|
||||
#if defined(HAVE_PRAGMA_GCC_POSION)
|
||||
#undef strncat
|
||||
#pragma GCC poison strncat
|
||||
#endif /* HAVE_PRAGMA_GCC_POSION */
|
||||
|
||||
/*
|
||||
* If one is not careful, sprintf() can lead to buffer overflows.
|
||||
* Use snprintf() instead.
|
||||
*/
|
||||
#if defined(HAVE_PRAGMA_GCC_POSION)
|
||||
#undef sprintf
|
||||
#pragma GCC poison sprintf
|
||||
#endif /* HAVE_PRAGMA_GCC_POSION */
|
||||
|
||||
/*
|
||||
* If one is not careful, vsprintf() can lead to buffer overflows.
|
||||
* Use vsnprintf() instead.
|
||||
*/
|
||||
#if defined(HAVE_PRAGMA_GCC_POSION)
|
||||
#undef vsprintf
|
||||
#pragma GCC poison vsprintf
|
||||
#endif /* HAVE_PRAGMA_GCC_POSION */
|
||||
|
||||
/*
|
||||
* XXX - As of 2021, functions such as:
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#endif /* !UNBAN */
|
||||
|
||||
#endif /* !INCLUDE_BANNED_H */
|
60
blkcpy.c
60
blkcpy.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* blkcpy - general values and related routines used by the calculator
|
||||
*
|
||||
* Copyright (C) 1999-2006 Landon Curt Noll and Ernest Bowen
|
||||
* Copyright (C) 1999-2007,2021,2022 Landon Curt Noll and Ernest Bowen
|
||||
*
|
||||
* Primary author: Landon Curt Noll
|
||||
*
|
||||
@@ -17,11 +17,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.9 $
|
||||
* @(#) $Id: blkcpy.c,v 29.9 2006/05/20 08:43:55 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/RCS/blkcpy.c,v $
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Under source code control: 1997/04/18 20:41:26
|
||||
* File existed as early as: 1997
|
||||
@@ -33,10 +29,15 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include "calc.h"
|
||||
#include "alloc.h"
|
||||
#include "value.h"
|
||||
#include "file.h"
|
||||
#include "blkcpy.h"
|
||||
#include "string.h"
|
||||
#include "str.h"
|
||||
|
||||
|
||||
#include "attribute.h"
|
||||
#include "banned.h" /* include after system header <> includes */
|
||||
|
||||
|
||||
/*
|
||||
@@ -298,7 +299,7 @@ copymat2mat(MATRIX *smat, long ssi, long num, MATRIX *dmat, long dsi)
|
||||
vtemp = (VALUE *) malloc(num * sizeof(VALUE));
|
||||
if (vtemp == NULL) {
|
||||
math_error("Out of memory for mat-to-mat copy");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
vp = smat->m_table + ssi;
|
||||
vq = vtemp;
|
||||
@@ -347,7 +348,7 @@ copyblk2mat(BLOCK *blk, long ssi, long num, MATRIX *dmat, long dsi)
|
||||
vtemp = (VALUE *) malloc(num * sizeof(VALUE));
|
||||
if (vtemp == NULL) {
|
||||
math_error("Out of memory for block-to-matrix copy");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
vp = vtemp;
|
||||
i = num;
|
||||
@@ -374,7 +375,8 @@ copyblk2mat(BLOCK *blk, long ssi, long num, MATRIX *dmat, long dsi)
|
||||
* copymat2blk - copy matrix to block
|
||||
*/
|
||||
int
|
||||
copymat2blk(MATRIX *smat, long ssi, long num, BLOCK *dblk, long dsi, BOOL noreloc)
|
||||
copymat2blk(MATRIX *smat, long ssi, long num, BLOCK *dblk, long dsi,
|
||||
BOOL noreloc)
|
||||
{
|
||||
long i;
|
||||
long newlen;
|
||||
@@ -403,7 +405,7 @@ copymat2blk(MATRIX *smat, long ssi, long num, BLOCK *dblk, long dsi, BOOL norelo
|
||||
newdata = (USB8*) realloc(dblk->data, newsize);
|
||||
if (newdata == NULL) {
|
||||
math_error("Out of memory for matrix-to-block copy");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
dblk->data = newdata;
|
||||
dblk->maxsize = newsize;
|
||||
@@ -446,7 +448,7 @@ copymat2list(MATRIX *smat, long ssi, long num, LIST *lp, long dsi)
|
||||
vtemp = (VALUE *) malloc(num * sizeof(VALUE));
|
||||
if (vtemp == NULL) {
|
||||
math_error("Out of memory for matrix-to-list copy");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
vp = smat->m_table + ssi;
|
||||
vq = vtemp;
|
||||
@@ -496,7 +498,7 @@ copylist2mat(LIST *lp, long ssi, long num, MATRIX *dmat, long dsi)
|
||||
vtemp = (VALUE *) malloc(num * sizeof(VALUE));
|
||||
if (vtemp == NULL) {
|
||||
math_error("Out of memory for list-to-matrix copy");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
ep = listelement(lp, (long) ssi);
|
||||
vp = vtemp;
|
||||
@@ -546,7 +548,7 @@ copylist2list(LIST *slp, long ssi, long num, LIST *dlp, long dsi)
|
||||
vtemp = (VALUE *) malloc(num * sizeof(VALUE));
|
||||
if (vtemp == NULL) {
|
||||
math_error("Out of memory for list-to-list copy");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
sep = listelement(slp, (long) ssi);
|
||||
vp = vtemp;
|
||||
@@ -661,7 +663,7 @@ copyfile2blk(FILEID id, long ssi, long num, BLOCK *dblk, long dsi, BOOL noreloc)
|
||||
newdata = (USB8*) realloc(dblk->data, newsize);
|
||||
if (newdata == NULL) {
|
||||
math_error("Out of memory for block-to-block copy");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
dblk->data = newdata;
|
||||
dblk->maxsize = newsize;
|
||||
@@ -720,7 +722,8 @@ copystr2file(STRING *str, long ssi, long num, FILEID id, long dsi)
|
||||
* copyblk2blk - copy block to block
|
||||
*/
|
||||
int
|
||||
copyblk2blk(BLOCK *sblk, long ssi, long num, BLOCK *dblk, long dsi, BOOL noreloc)
|
||||
copyblk2blk(BLOCK *sblk, long ssi, long num, BLOCK *dblk, long dsi,
|
||||
BOOL noreloc)
|
||||
{
|
||||
long newlen;
|
||||
long newsize;
|
||||
@@ -746,7 +749,7 @@ copyblk2blk(BLOCK *sblk, long ssi, long num, BLOCK *dblk, long dsi, BOOL noreloc
|
||||
newdata = (USB8*) realloc(dblk->data, newsize);
|
||||
if (newdata == NULL) {
|
||||
math_error("Out of memory for block-to-block copy");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
dblk->data = newdata;
|
||||
dblk->maxsize = newsize;
|
||||
@@ -762,7 +765,8 @@ copyblk2blk(BLOCK *sblk, long ssi, long num, BLOCK *dblk, long dsi, BOOL noreloc
|
||||
* copystr2blk - copy string to block
|
||||
*/
|
||||
int
|
||||
copystr2blk(STRING *str, long ssi, long num, BLOCK *dblk, long dsi, BOOL noreloc)
|
||||
copystr2blk(STRING *str, long ssi, long num, BLOCK *dblk, long dsi,
|
||||
BOOL noreloc)
|
||||
{
|
||||
long len;
|
||||
long newlen;
|
||||
@@ -789,7 +793,7 @@ copystr2blk(STRING *str, long ssi, long num, BLOCK *dblk, long dsi, BOOL noreloc
|
||||
newdata = (USB8*) realloc(dblk->data, newsize);
|
||||
if (newdata == NULL) {
|
||||
math_error("Out of memory for string-to-block copy");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
dblk->data = newdata;
|
||||
dblk->maxsize = newsize;
|
||||
@@ -910,7 +914,7 @@ copyostr2blk(char *str,long ssi,long num,BLOCK *dblk,long dsi,BOOL noreloc)
|
||||
newdata = (USB8*) realloc(dblk->data, newsize);
|
||||
if (newdata == NULL) {
|
||||
math_error("Out of memory for string-to-block copy");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
dblk->data = newdata;
|
||||
dblk->maxsize = newsize;
|
||||
@@ -935,14 +939,14 @@ copyostr2blk(char *str,long ssi,long num,BLOCK *dblk,long dsi,BOOL noreloc)
|
||||
* s1
|
||||
*/
|
||||
void *
|
||||
memmove(void *s1, const void *s2, CALC_SIZE_T n)
|
||||
memmove(void *s1, CONST void *s2, MEMMOVE_SIZE_T n)
|
||||
{
|
||||
/*
|
||||
* firewall
|
||||
*/
|
||||
if (s1 == NULL || s2 == NULL) {
|
||||
math_error("bogus memmove NULL ptr");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
if (n <= 0) {
|
||||
/* neg or 0 count does nothing */
|
||||
@@ -982,7 +986,8 @@ memmove(void *s1, const void *s2, CALC_SIZE_T n)
|
||||
* copynum2blk - copy number numerator to block
|
||||
*/
|
||||
int
|
||||
copynum2blk(NUMBER *snum, long ssi, long num, BLOCK *dblk, long dsi, BOOL noreloc)
|
||||
copynum2blk(NUMBER *snum, long ssi, long num, BLOCK *dblk, long dsi,
|
||||
BOOL noreloc)
|
||||
{
|
||||
size_t newlen;
|
||||
size_t newsize;
|
||||
@@ -1011,7 +1016,7 @@ copynum2blk(NUMBER *snum, long ssi, long num, BLOCK *dblk, long dsi, BOOL norelo
|
||||
newdata = (USB8*) realloc(dblk->data, newsize);
|
||||
if (newdata == NULL) {
|
||||
math_error("Out of memory for num-to-block copy");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
dblk->data = newdata;
|
||||
dblk->maxsize = newsize;
|
||||
@@ -1033,13 +1038,14 @@ copynum2blk(NUMBER *snum, long ssi, long num, BLOCK *dblk, long dsi, BOOL norelo
|
||||
* copyblk2num - copy block to number
|
||||
*/
|
||||
int
|
||||
copyblk2num(BLOCK *sblk, long ssi, long num, NUMBER *dnum, long dsi, NUMBER **res)
|
||||
copyblk2num(BLOCK *sblk, long ssi, long num, NUMBER *dnum, long dsi,
|
||||
NUMBER **res)
|
||||
{
|
||||
size_t newlen;
|
||||
NUMBER *ret; /* cloned and modified numerator */
|
||||
#if CALC_BYTE_ORDER == BIG_ENDIAN
|
||||
HALF *swapped; /* byte swapped input data */
|
||||
unsigned long halflen; /* length of the input ounded up to HALFs */
|
||||
unsigned long halflen; /* length of the input rounded up to HALFs */
|
||||
HALF *h; /* copy byteswap pointer */
|
||||
unsigned long i;
|
||||
#endif
|
||||
@@ -1081,7 +1087,7 @@ copyblk2num(BLOCK *sblk, long ssi, long num, NUMBER *dnum, long dsi, NUMBER **re
|
||||
swapped = (HALF *)malloc(halflen * sizeof(HALF));
|
||||
if (swapped == NULL) {
|
||||
math_error("Out of memory for block-to-num copy");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
/* ensure that any trailing octets will be zero filled */
|
||||
swapped[halflen-1] = 0;
|
||||
|
50
blkcpy.h
50
blkcpy.h
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* blkcpy - general values and related routines used by the calculator
|
||||
*
|
||||
* Copyright (C) 1999 Landon Curt Noll and Ernest Bowen
|
||||
* Copyright (C) 1999-2007,2014 Landon Curt Noll and Ernest Bowen
|
||||
*
|
||||
* Primary author: Landon Curt Noll
|
||||
*
|
||||
@@ -17,11 +17,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: blkcpy.h,v 29.2 2000/06/07 14:02:13 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/RCS/blkcpy.h,v $
|
||||
* 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
|
||||
@@ -30,33 +26,33 @@
|
||||
*/
|
||||
|
||||
|
||||
#if !defined(__BLKCPY_H__)
|
||||
#define __BLKCPY_H__
|
||||
#if !defined(INCLUDE_BLKCPY_H)
|
||||
#define INCLUDE_BLKCPY_H
|
||||
|
||||
/*
|
||||
* the main copy gateway function
|
||||
*/
|
||||
extern int copystod(VALUE *, long, long, VALUE *, long);
|
||||
E_FUNC int copystod(VALUE *, long, long, VALUE *, long);
|
||||
|
||||
/*
|
||||
* specific copy functions
|
||||
*/
|
||||
extern int copyblk2blk(BLOCK *, long, long, BLOCK *, long, BOOL);
|
||||
extern int copyblk2file(BLOCK *, long, long, FILEID, long);
|
||||
extern int copyblk2mat(BLOCK *, long, long, MATRIX *, long);
|
||||
extern int copyblk2num(BLOCK *, long, long, NUMBER *, long, NUMBER **);
|
||||
extern int copyblk2str(BLOCK *, long, long, STRING *, long);
|
||||
extern int copyfile2blk(FILEID, long, long, BLOCK *, long, BOOL);
|
||||
extern int copylist2list(LIST *, long, long, LIST *, long);
|
||||
extern int copylist2mat(LIST *, long, long, MATRIX *, long);
|
||||
extern int copymat2blk(MATRIX *, long, long, BLOCK *, long, BOOL);
|
||||
extern int copymat2list(MATRIX *, long, long, LIST *, long);
|
||||
extern int copymat2mat(MATRIX *, long, long, MATRIX *, long);
|
||||
extern int copynum2blk(NUMBER *, long, long, BLOCK *, long, BOOL);
|
||||
extern int copyostr2blk(char *, long, long, BLOCK *, long, BOOL);
|
||||
extern int copyostr2str(char *, long, long, STRING *, long);
|
||||
extern int copystr2blk(STRING *, long, long, BLOCK *, long, BOOL);
|
||||
extern int copystr2file(STRING *, long, long, FILEID, long);
|
||||
extern int copystr2str(STRING *, long, long, STRING *, long);
|
||||
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 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 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 copyostr2str(char *, long, long, STRING *, long);
|
||||
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);
|
||||
|
||||
#endif /* !__BLKCPY_H__ */
|
||||
#endif /* !INCLUDE_BLKCPY_H */
|
||||
|
72
block.c
72
block.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* block - fixed, dynamic, fifo and circular memory blocks
|
||||
*
|
||||
* Copyright (C) 1999 Landon Curt Noll and Ernest Bowen
|
||||
* Copyright (C) 1999-2007,2021,2022 Landon Curt Noll and Ernest Bowen
|
||||
*
|
||||
* Primary author: Landon Curt Noll
|
||||
*
|
||||
@@ -17,11 +17,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.3 $
|
||||
* @(#) $Id: block.c,v 29.3 2006/05/01 19:16:57 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/RCS/block.c,v $
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Under source code control: 1997/02/27 00:29:40
|
||||
* File existed as early as: 1997
|
||||
@@ -32,24 +28,34 @@
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "have_string.h"
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#include "alloc.h"
|
||||
#include "value.h"
|
||||
#include "zmath.h"
|
||||
#include "config.h"
|
||||
#include "block.h"
|
||||
#include "nametype.h"
|
||||
#include "string.h"
|
||||
#include "str.h"
|
||||
#include "calcerr.h"
|
||||
|
||||
|
||||
#include "attribute.h"
|
||||
#include "banned.h" /* include after system header <> includes */
|
||||
|
||||
|
||||
#define NBLOCKCHUNK 16
|
||||
|
||||
static long nblockcount = 0;
|
||||
static long maxnblockcount = 0;
|
||||
static STRINGHEAD nblocknames;
|
||||
static NBLOCK **nblocks;
|
||||
STATIC long nblockcount = 0;
|
||||
STATIC long maxnblockcount = 0;
|
||||
STATIC STRINGHEAD nblocknames;
|
||||
STATIC NBLOCK **nblocks;
|
||||
|
||||
|
||||
/* forward declarations */
|
||||
static void blkchk(BLOCK*);
|
||||
S_FUNC void blkchk(BLOCK*);
|
||||
|
||||
|
||||
/*
|
||||
@@ -82,7 +88,7 @@ blkalloc(int len, int chunk)
|
||||
nblk = (BLOCK *)malloc(sizeof(BLOCK));
|
||||
if (nblk == NULL) {
|
||||
math_error("cannot allocate block");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -93,7 +99,7 @@ blkalloc(int len, int chunk)
|
||||
nblk->data = (USB8*)malloc(nblk->maxsize);
|
||||
if (nblk->data == NULL) {
|
||||
math_error("cannot allocate block data storage");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
memset(nblk->data, 0, nblk->maxsize);
|
||||
nblk->datalen = len;
|
||||
@@ -151,10 +157,10 @@ blk_free(BLOCK *blk)
|
||||
* blk - the BLOCK to check
|
||||
*
|
||||
* returns:
|
||||
* if all is ok, otherwise math_error() is called and this
|
||||
* if all is OK, otherwise math_error() is called and this
|
||||
* function does not return
|
||||
*/
|
||||
static void
|
||||
S_FUNC void
|
||||
blkchk(BLOCK *blk)
|
||||
{
|
||||
|
||||
@@ -167,7 +173,7 @@ blkchk(BLOCK *blk)
|
||||
}
|
||||
if (blk == NULL) {
|
||||
math_error("internal: blk ptr is NULL");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -175,7 +181,7 @@ blkchk(BLOCK *blk)
|
||||
*/
|
||||
if (blk->data == NULL) {
|
||||
math_error("internal: blk->data ptr is NULL");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -183,7 +189,7 @@ blkchk(BLOCK *blk)
|
||||
*/
|
||||
if (blk->datalen < 0) {
|
||||
math_error("internal: blk->datalen < 0");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -191,7 +197,7 @@ blkchk(BLOCK *blk)
|
||||
*/
|
||||
if (blk->datalen < 0) {
|
||||
math_error("internal: blk->datalen < 0");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -254,7 +260,7 @@ blkrealloc(BLOCK *blk, int newlen, int newchunk)
|
||||
nblk = (USB8*)realloc(blk->data, newmax);
|
||||
if (nblk == NULL) {
|
||||
math_error("cannot reallocate block storage");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
|
||||
/* clear any new storage */
|
||||
@@ -295,7 +301,7 @@ blkrealloc(BLOCK *blk, int newlen, int newchunk)
|
||||
* Set the data length
|
||||
*
|
||||
* We also know that the new block is not empty since we have
|
||||
* already dealth with that case above.
|
||||
* already dealt with that case above.
|
||||
*
|
||||
* After this section of code, limit and datalen will be
|
||||
* correct in terms of the new type.
|
||||
@@ -362,7 +368,7 @@ blktrunc(BLOCK *blk)
|
||||
blk->data = (USB8*)malloc(1);
|
||||
if (blk->data == NULL) {
|
||||
math_error("cannot allocate truncated block storage");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
blk->data[0] = (USB8)0;
|
||||
if (conf->calc_debug & CALCDBG_BLOCK) {
|
||||
@@ -392,7 +398,7 @@ blk_copy(BLOCK *blk)
|
||||
nblk = (BLOCK *)malloc(sizeof(BLOCK));
|
||||
if (nblk == NULL) {
|
||||
math_error("blk_copy: cannot malloc BLOCK");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -406,7 +412,7 @@ blk_copy(BLOCK *blk)
|
||||
nblk->data = (USB8 *)malloc(blk->maxsize);
|
||||
if (nblk->data == NULL) {
|
||||
math_error("blk_copy: cannot duplicate block data");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
memcpy(nblk->data, blk->data, blk->maxsize);
|
||||
return nblk;
|
||||
@@ -534,7 +540,7 @@ reallocnblock(int id, int len, int chunk)
|
||||
/* Fire wall */
|
||||
if (id < 0 || id >= nblockcount) {
|
||||
math_error("Bad id in call to reallocnblock");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
|
||||
blk = nblocks[id]->blk;
|
||||
@@ -551,13 +557,13 @@ reallocnblock(int id, int len, int chunk)
|
||||
newdata = malloc(newsize);
|
||||
if (newdata == NULL) {
|
||||
math_error("Allocation failed");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
} else if (newsize != oldsize) {
|
||||
newdata = realloc(blk->data, newsize);
|
||||
if (newdata == NULL) {
|
||||
math_error("Reallocation failed");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
}
|
||||
memset(newdata + len, 0, newsize - len);
|
||||
@@ -588,7 +594,7 @@ createnblock(char *name, int len, int chunk)
|
||||
if (nblocks == NULL) {
|
||||
maxnblockcount = 0;
|
||||
math_error("unable to malloc new named blocks");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
} else {
|
||||
maxnblockcount += NBLOCKCHUNK;
|
||||
@@ -597,7 +603,7 @@ createnblock(char *name, int len, int chunk)
|
||||
if (nblocks == NULL) {
|
||||
maxnblockcount = 0;
|
||||
math_error("cannot malloc more named blocks");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -605,18 +611,18 @@ createnblock(char *name, int len, int chunk)
|
||||
initstr(&nblocknames);
|
||||
if (findstr(&nblocknames, name) >= 0) {
|
||||
math_error("Named block already exists!!!");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
newname = addstr(&nblocknames, name);
|
||||
if (newname == NULL) {
|
||||
math_error("Block name allocation failed");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
|
||||
res = (NBLOCK *) malloc(sizeof(NBLOCK));
|
||||
if (res == NULL) {
|
||||
math_error("Named block allocation failed");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
|
||||
nblocks[nblockcount] = res;
|
||||
|
56
block.h
56
block.h
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* block - fixed, dynamic, fifo and circular memory blocks
|
||||
*
|
||||
* Copyright (C) 1999 Landon Curt Noll and Ernest Bowen
|
||||
* Copyright (C) 1999-2007,2014,2021 Landon Curt Noll and Ernest Bowen
|
||||
*
|
||||
* Primary author: Landon Curt Noll
|
||||
*
|
||||
@@ -17,11 +17,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: block.h,v 29.2 2000/06/07 14:02:13 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/RCS/block.h,v $
|
||||
* 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
|
||||
@@ -31,8 +27,8 @@
|
||||
*/
|
||||
|
||||
|
||||
#if !defined(__BLOCK_H__)
|
||||
#define __BLOCK_H__
|
||||
#if !defined(INCLUDE_BLOCK_H)
|
||||
#define INCLUDE_BLOCK_H
|
||||
|
||||
|
||||
/*
|
||||
@@ -59,7 +55,7 @@
|
||||
* blkchunk defaults to BLK_CHUNKSIZE
|
||||
*
|
||||
* blkfree(x)
|
||||
* Reduce storage down to 0 octetes.
|
||||
* Reduce storage down to 0 octets.
|
||||
*
|
||||
* size(x)
|
||||
* The length of data stored in the block.
|
||||
@@ -92,7 +88,7 @@
|
||||
* blkmove(dest, src, length [, dest_offset [, src_offset]])
|
||||
* 0 <= length <= blksize(x)
|
||||
* offset's are restricted in value by block type
|
||||
* overlapping moves are handeled correctly
|
||||
* overlapping moves are handled correctly
|
||||
*
|
||||
* blkccpy(dest, src, stopval, length [, dest_offset [, src_offset]])
|
||||
* 0 <= length <= blksize(x)
|
||||
@@ -108,7 +104,7 @@
|
||||
* b = a*k for some integer k >= 1
|
||||
*
|
||||
* scatter(src, dest1, dest2 [, dest3 ] ...)
|
||||
* copy sucessive octets from src into dest1, dest2, ...
|
||||
* copy successive octets from src into dest1, dest2, ...
|
||||
* restarting with dest1 after end of list
|
||||
* stops at end of src
|
||||
*
|
||||
@@ -160,7 +156,7 @@ typedef struct nblock NBLOCK;
|
||||
/*
|
||||
* block debug
|
||||
*/
|
||||
extern int blk_debug; /* 0 => debug off */
|
||||
EXTERN int blk_debug; /* 0 => debug off */
|
||||
|
||||
|
||||
/*
|
||||
@@ -188,7 +184,7 @@ extern int blk_debug; /* 0 => debug off */
|
||||
/* length of data stored in a block */
|
||||
#define blklen(blk) ((blk)->datalen)
|
||||
|
||||
/* block footpint in memory */
|
||||
/* block footprint in memory */
|
||||
#define blksizeof(blk) ((blk)->maxsize)
|
||||
|
||||
/* block allocation chunk size */
|
||||
@@ -204,22 +200,22 @@ typedef USB8 OCTET;
|
||||
/*
|
||||
* external functions
|
||||
*/
|
||||
extern BLOCK *blkalloc(int, int);
|
||||
extern void blk_free(BLOCK*);
|
||||
extern BLOCK *blkrealloc(BLOCK*, int, int);
|
||||
extern void blktrunc(BLOCK*);
|
||||
extern BLOCK *blk_copy(BLOCK*);
|
||||
extern int blk_cmp(BLOCK*, BLOCK*);
|
||||
extern void blk_print(BLOCK*);
|
||||
extern void nblock_print(NBLOCK *);
|
||||
extern NBLOCK *createnblock(char *, int, int);
|
||||
extern NBLOCK *reallocnblock(int, int, int);
|
||||
extern int removenblock(int);
|
||||
extern int findnblockid(char *);
|
||||
extern NBLOCK *findnblock(int);
|
||||
extern BLOCK *copyrealloc(BLOCK*, int, int);
|
||||
extern int countnblocks(void);
|
||||
extern void shownblocks(void);
|
||||
E_FUNC BLOCK *blkalloc(int, int);
|
||||
E_FUNC void blk_free(BLOCK*);
|
||||
E_FUNC BLOCK *blkrealloc(BLOCK*, int, int);
|
||||
E_FUNC void blktrunc(BLOCK*);
|
||||
E_FUNC BLOCK *blk_copy(BLOCK*);
|
||||
E_FUNC int blk_cmp(BLOCK*, BLOCK*);
|
||||
E_FUNC void blk_print(BLOCK*);
|
||||
E_FUNC void nblock_print(NBLOCK *);
|
||||
E_FUNC NBLOCK *createnblock(char *, int, int);
|
||||
E_FUNC NBLOCK *reallocnblock(int, int, int);
|
||||
E_FUNC int removenblock(int);
|
||||
E_FUNC int findnblockid(char *);
|
||||
E_FUNC NBLOCK *findnblock(int);
|
||||
E_FUNC BLOCK *copyrealloc(BLOCK*, int, int);
|
||||
E_FUNC int countnblocks(void);
|
||||
E_FUNC void shownblocks(void);
|
||||
|
||||
|
||||
#endif /* !__BLOCK_H__ */
|
||||
#endif /* !INCLUDE_BLOCK_H */
|
||||
|
97
byteswap.c
97
byteswap.c
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* byteswap - byte swapping routines
|
||||
*
|
||||
* Copyright (C) 1999 Landon Curt Noll
|
||||
* Copyright (C) 1999,2021,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
|
||||
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: byteswap.c,v 29.2 2000/06/07 14:02:13 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/RCS/byteswap.c,v $
|
||||
* 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
|
||||
@@ -33,11 +29,15 @@
|
||||
#include "byteswap.h"
|
||||
|
||||
|
||||
#include "attribute.h"
|
||||
#include "banned.h" /* include after system header <> includes */
|
||||
|
||||
|
||||
/*
|
||||
* swap_b8_in_HALFs - swap 8 and if needed, 16 bits in an array of HALFs
|
||||
*
|
||||
* given:
|
||||
* dest - pointer to where the swapped src wil be put or
|
||||
* dest - pointer to where the swapped src will be put or
|
||||
* NULL to allocate the storage
|
||||
* src - pointer to a HALF array to swap
|
||||
* len - length of the src HALF array
|
||||
@@ -77,11 +77,11 @@ swap_b8_in_HALFs(HALF *dest, HALF *src, LEN len)
|
||||
* swap_b8_in_ZVALUE - swap 8 and if needed, 16 bits in a ZVALUE
|
||||
*
|
||||
* given:
|
||||
* dest - pointer to where the swapped src wil be put or
|
||||
* dest - pointer to where the swapped src will be put or
|
||||
* NULL to allocate the storage
|
||||
* src - pointer to a ZVALUE to swap
|
||||
* all - TRUE => swap every element, FALSE => swap only the
|
||||
* multiprecision storage
|
||||
* multi-precision storage
|
||||
*
|
||||
* returns:
|
||||
* pointer to where the swapped src has been put
|
||||
@@ -102,8 +102,9 @@ swap_b8_in_ZVALUE(ZVALUE *dest, ZVALUE *src, BOOL all)
|
||||
*/
|
||||
dest = malloc(sizeof(ZVALUE));
|
||||
if (dest == NULL) {
|
||||
math_error("swap_b8_in_ZVALUE: swap_b8_in_ZVALUE: Not enough memory");
|
||||
/*NOTREACHED*/
|
||||
math_error("swap_b8_in_ZVALUE: swap_b8_in_ZVALUE: "
|
||||
"Not enough memory");
|
||||
not_reached();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -126,8 +127,8 @@ swap_b8_in_ZVALUE(ZVALUE *dest, ZVALUE *src, BOOL all)
|
||||
* swap or copy the rest of the ZVALUE elements
|
||||
*/
|
||||
if (all) {
|
||||
dest->len = (LEN)SWAP_B8_IN_LEN(&dest->len, &src->len);
|
||||
dest->sign = (BOOL)SWAP_B8_IN_BOOL(&dest->sign, &src->sign);
|
||||
SWAP_B8_IN_LEN(&dest->len, &src->len);
|
||||
SWAP_B8_IN_BOOL(&dest->sign, &src->sign);
|
||||
} else {
|
||||
dest->len = src->len;
|
||||
dest->sign = src->sign;
|
||||
@@ -144,11 +145,11 @@ swap_b8_in_ZVALUE(ZVALUE *dest, ZVALUE *src, BOOL all)
|
||||
* swap_b8_in_NUMBER - swap 8 and if needed, 16 bits in a NUMBER
|
||||
*
|
||||
* given:
|
||||
* dest - pointer to where the swapped src wil be put or
|
||||
* dest - pointer to where the swapped src will be put or
|
||||
* NULL to allocate the storage
|
||||
* src - pointer to a NUMBER to swap
|
||||
* all - TRUE => swap every element, FALSE => swap only the
|
||||
* multiprecision storage
|
||||
* multi-precision storage
|
||||
*
|
||||
* returns:
|
||||
* pointer to where the swapped src has been put
|
||||
@@ -170,7 +171,7 @@ swap_b8_in_NUMBER(NUMBER *dest, NUMBER *src, BOOL all)
|
||||
dest = malloc(sizeof(NUMBER));
|
||||
if (dest == NULL) {
|
||||
math_error("swap_b8_in_NUMBER: Not enough memory");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -192,7 +193,7 @@ swap_b8_in_NUMBER(NUMBER *dest, NUMBER *src, BOOL all)
|
||||
* swap or copy the rest of the NUMBER elements
|
||||
*/
|
||||
if (all) {
|
||||
dest->links = (long)SWAP_B8_IN_LONG(&dest->links, &src->links);
|
||||
SWAP_B8_IN_LONG(&dest->links, &src->links);
|
||||
} else {
|
||||
dest->links = src->links;
|
||||
}
|
||||
@@ -208,11 +209,11 @@ swap_b8_in_NUMBER(NUMBER *dest, NUMBER *src, BOOL all)
|
||||
* swap_b8_in_COMPLEX - swap 8 and if needed, 16 bits in a COMPLEX
|
||||
*
|
||||
* given:
|
||||
* dest - pointer to where the swapped src wil be put or
|
||||
* dest - pointer to where the swapped src will be put or
|
||||
* NULL to allocate the storage
|
||||
* src - pointer to a COMPLEX to swap
|
||||
* all - TRUE => swap every element, FALSE => swap only the
|
||||
* multiprecision storage
|
||||
* multi-precision storage
|
||||
*
|
||||
* returns:
|
||||
* pointer to where the swapped src has been put
|
||||
@@ -234,7 +235,7 @@ swap_b8_in_COMPLEX(COMPLEX *dest, COMPLEX *src, BOOL all)
|
||||
dest = malloc(sizeof(COMPLEX));
|
||||
if (dest == NULL) {
|
||||
math_error("swap_b8_in_COMPLEX: Not enough memory");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -256,7 +257,7 @@ swap_b8_in_COMPLEX(COMPLEX *dest, COMPLEX *src, BOOL all)
|
||||
* swap or copy the rest of the NUMBER elements
|
||||
*/
|
||||
if (all) {
|
||||
dest->links = (long)SWAP_B8_IN_LONG(&dest->links, &src->links);
|
||||
SWAP_B8_IN_LONG(&dest->links, &src->links);
|
||||
} else {
|
||||
dest->links = src->links;
|
||||
}
|
||||
@@ -272,7 +273,7 @@ swap_b8_in_COMPLEX(COMPLEX *dest, COMPLEX *src, BOOL all)
|
||||
* swap_b16_in_HALFs - swap 16 bits in an array of HALFs
|
||||
*
|
||||
* given:
|
||||
* dest - pointer to where the swapped src wil be put or
|
||||
* dest - pointer to where the swapped src will be put or
|
||||
* NULL to allocate the storage
|
||||
* src - pointer to a HALF array to swap
|
||||
* len - length of the src HALF array
|
||||
@@ -312,11 +313,11 @@ swap_b16_in_HALFs(HALF *dest, HALF *src, LEN len)
|
||||
* swap_b16_in_ZVALUE - swap 16 bits in a ZVALUE
|
||||
*
|
||||
* given:
|
||||
* dest - pointer to where the swapped src wil be put or
|
||||
* dest - pointer to where the swapped src will be put or
|
||||
* NULL to allocate the storage
|
||||
* src - pointer to a ZVALUE to swap
|
||||
* all - TRUE => swap every element, FALSE => swap only the
|
||||
* multiprecision storage
|
||||
* multi-precision storage
|
||||
*
|
||||
* returns:
|
||||
* pointer to where the swapped src has been put
|
||||
@@ -338,7 +339,7 @@ swap_b16_in_ZVALUE(ZVALUE *dest, ZVALUE *src, BOOL all)
|
||||
dest = malloc(sizeof(ZVALUE));
|
||||
if (dest == NULL) {
|
||||
math_error("swap_b16_in_ZVALUE: Not enough memory");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -361,8 +362,8 @@ swap_b16_in_ZVALUE(ZVALUE *dest, ZVALUE *src, BOOL all)
|
||||
* swap or copy the rest of the ZVALUE elements
|
||||
*/
|
||||
if (all) {
|
||||
dest->len = (LEN)SWAP_B16_IN_LEN(&dest->len, &src->len);
|
||||
dest->sign = (BOOL)SWAP_B16_IN_BOOL(&dest->sign, &src->sign);
|
||||
SWAP_B16_IN_LEN(&dest->len, &src->len);
|
||||
SWAP_B16_IN_BOOL(&dest->sign, &src->sign);
|
||||
} else {
|
||||
dest->len = src->len;
|
||||
dest->sign = src->sign;
|
||||
@@ -379,11 +380,11 @@ swap_b16_in_ZVALUE(ZVALUE *dest, ZVALUE *src, BOOL all)
|
||||
* swap_b16_in_NUMBER - swap 16 bits in a NUMBER
|
||||
*
|
||||
* given:
|
||||
* dest - pointer to where the swapped src wil be put or
|
||||
* dest - pointer to where the swapped src will be put or
|
||||
* NULL to allocate the storage
|
||||
* src - pointer to a NUMBER to swap
|
||||
* all - TRUE => swap every element, FALSE => swap only the
|
||||
* multiprecision storage
|
||||
* multi-precision storage
|
||||
*
|
||||
* returns:
|
||||
* pointer to where the swapped src has been put
|
||||
@@ -405,7 +406,7 @@ swap_b16_in_NUMBER(NUMBER *dest, NUMBER *src, BOOL all)
|
||||
dest = malloc(sizeof(NUMBER));
|
||||
if (dest == NULL) {
|
||||
math_error("swap_b16_in_NUMBER: Not enough memory");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -427,7 +428,7 @@ swap_b16_in_NUMBER(NUMBER *dest, NUMBER *src, BOOL all)
|
||||
* swap or copy the rest of the NUMBER elements
|
||||
*/
|
||||
if (all) {
|
||||
dest->links = (long)SWAP_B16_IN_LONG(&dest->links, &src->links);
|
||||
SWAP_B16_IN_LONG(&dest->links, &src->links);
|
||||
} else {
|
||||
dest->links = src->links;
|
||||
}
|
||||
@@ -443,11 +444,11 @@ swap_b16_in_NUMBER(NUMBER *dest, NUMBER *src, BOOL all)
|
||||
* swap_b16_in_COMPLEX - swap 16 bits in a COMPLEX
|
||||
*
|
||||
* given:
|
||||
* dest - pointer to where the swapped src wil be put or
|
||||
* dest - pointer to where the swapped src will be put or
|
||||
* NULL to allocate the storage
|
||||
* src - pointer to a COMPLEX to swap
|
||||
* all - TRUE => swap every element, FALSE => swap only the
|
||||
* multiprecision storage
|
||||
* multi-precision storage
|
||||
*
|
||||
* returns:
|
||||
* pointer to where the swapped src has been put
|
||||
@@ -469,7 +470,7 @@ swap_b16_in_COMPLEX(COMPLEX *dest, COMPLEX *src, BOOL all)
|
||||
dest = malloc(sizeof(COMPLEX));
|
||||
if (dest == NULL) {
|
||||
math_error("swap_b16_in_COMPLEX: Not enough memory");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -491,7 +492,7 @@ swap_b16_in_COMPLEX(COMPLEX *dest, COMPLEX *src, BOOL all)
|
||||
* swap or copy the rest of the NUMBER elements
|
||||
*/
|
||||
if (all) {
|
||||
dest->links = (long)SWAP_B16_IN_LONG(&dest->links, &src->links);
|
||||
SWAP_B16_IN_LONG(&dest->links, &src->links);
|
||||
} else {
|
||||
dest->links = src->links;
|
||||
}
|
||||
@@ -507,11 +508,11 @@ swap_b16_in_COMPLEX(COMPLEX *dest, COMPLEX *src, BOOL all)
|
||||
* swap_HALF_in_ZVALUE - swap HALFs in a ZVALUE
|
||||
*
|
||||
* given:
|
||||
* dest - pointer to where the swapped src wil be put or
|
||||
* dest - pointer to where the swapped src will be put or
|
||||
* NULL to allocate the storage
|
||||
* src - pointer to a ZVALUE to swap
|
||||
* all - TRUE => swap every element, FALSE => swap only the
|
||||
* multiprecision storage
|
||||
* multi-precision storage
|
||||
*
|
||||
* returns:
|
||||
* pointer to where the swapped src has been put
|
||||
@@ -533,7 +534,7 @@ swap_HALF_in_ZVALUE(ZVALUE *dest, ZVALUE *src, BOOL all)
|
||||
dest = malloc(sizeof(ZVALUE));
|
||||
if (dest == NULL) {
|
||||
math_error("swap_HALF_in_ZVALUE: Not enough memory");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -557,8 +558,8 @@ swap_HALF_in_ZVALUE(ZVALUE *dest, ZVALUE *src, BOOL all)
|
||||
* swap or copy the rest of the ZVALUE elements
|
||||
*/
|
||||
if (all) {
|
||||
dest->len = (LEN)SWAP_HALF_IN_LEN(&dest->len, &src->len);
|
||||
dest->sign = (BOOL)SWAP_HALF_IN_BOOL(&dest->sign, &src->sign);
|
||||
SWAP_HALF_IN_LEN(&dest->len, &src->len);
|
||||
SWAP_HALF_IN_BOOL(&dest->sign, &src->sign);
|
||||
} else {
|
||||
dest->len = src->len;
|
||||
dest->sign = src->sign;
|
||||
@@ -575,11 +576,11 @@ swap_HALF_in_ZVALUE(ZVALUE *dest, ZVALUE *src, BOOL all)
|
||||
* swap_HALF_in_NUMBER - swap HALFs in a NUMBER
|
||||
*
|
||||
* given:
|
||||
* dest - pointer to where the swapped src wil be put or
|
||||
* dest - pointer to where the swapped src will be put or
|
||||
* NULL to allocate the storage
|
||||
* src - pointer to a NUMBER to swap
|
||||
* all - TRUE => swap every element, FALSE => swap only the
|
||||
* multiprecision storage
|
||||
* multi-precision storage
|
||||
*
|
||||
* returns:
|
||||
* pointer to where the swapped src has been put
|
||||
@@ -601,7 +602,7 @@ swap_HALF_in_NUMBER(NUMBER *dest, NUMBER *src, BOOL all)
|
||||
dest = malloc(sizeof(NUMBER));
|
||||
if (dest == NULL) {
|
||||
math_error("swap_HALF_in_NUMBER: Not enough memory");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -623,7 +624,7 @@ swap_HALF_in_NUMBER(NUMBER *dest, NUMBER *src, BOOL all)
|
||||
* swap or copy the rest of the NUMBER elements
|
||||
*/
|
||||
if (all) {
|
||||
dest->links = (long)SWAP_HALF_IN_LONG(&dest->links,&src->links);
|
||||
SWAP_HALF_IN_LONG(&dest->links, &src->links);
|
||||
} else {
|
||||
dest->links = src->links;
|
||||
}
|
||||
@@ -639,11 +640,11 @@ swap_HALF_in_NUMBER(NUMBER *dest, NUMBER *src, BOOL all)
|
||||
* swap_HALF_in_COMPLEX - swap HALFs in a COMPLEX
|
||||
*
|
||||
* given:
|
||||
* dest - pointer to where the swapped src wil be put or
|
||||
* dest - pointer to where the swapped src will be put or
|
||||
* NULL to allocate the storage
|
||||
* src - pointer to a COMPLEX to swap
|
||||
* all - TRUE => swap every element, FALSE => swap only the
|
||||
* multiprecision storage
|
||||
* multi-precision storage
|
||||
*
|
||||
* returns:
|
||||
* pointer to where the swapped src has been put
|
||||
@@ -665,7 +666,7 @@ swap_HALF_in_COMPLEX(COMPLEX *dest, COMPLEX *src, BOOL all)
|
||||
dest = malloc(sizeof(COMPLEX));
|
||||
if (dest == NULL) {
|
||||
math_error("swap_HALF_in_COMPLEX: Not enough memory");
|
||||
/*NOTREACHED*/
|
||||
not_reached();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -687,7 +688,7 @@ swap_HALF_in_COMPLEX(COMPLEX *dest, COMPLEX *src, BOOL all)
|
||||
* swap or copy the rest of the NUMBER elements
|
||||
*/
|
||||
if (all) {
|
||||
dest->links = (long)SWAP_HALF_IN_LONG(&dest->links,&src->links);
|
||||
SWAP_HALF_IN_LONG(&dest->links, &src->links);
|
||||
} else {
|
||||
dest->links = src->links;
|
||||
}
|
||||
|
32
byteswap.h
32
byteswap.h
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* byteswap - byte swapping macros
|
||||
*
|
||||
* Copyright (C) 1999 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
|
||||
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.4 $
|
||||
* @(#) $Id: byteswap.h,v 29.4 2001/06/08 21:00:58 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/RCS/byteswap.h,v $
|
||||
* 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
|
||||
@@ -29,8 +25,8 @@
|
||||
*/
|
||||
|
||||
|
||||
#if !defined(__BYTESWAP_H__)
|
||||
#define __BYTESWAP_H__
|
||||
#if !defined(INCLUDE_BYTESWAP_H)
|
||||
#define INCLUDE_BYTESWAP_H
|
||||
|
||||
|
||||
#if defined(CALC_SRC) /* if we are building from the calc source tree */
|
||||
@@ -43,7 +39,7 @@
|
||||
/*
|
||||
* SWAP_B8_IN_B16 - swap 8 bits in 16 bits
|
||||
*
|
||||
* dest - pointer to where the swapped src wil be put
|
||||
* 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.
|
||||
@@ -57,7 +53,7 @@
|
||||
/*
|
||||
* SWAP_B16_IN_B32 - swap 16 bits in 32 bits
|
||||
*
|
||||
* dest - pointer to where the swapped src wil be put
|
||||
* 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) ( \
|
||||
@@ -68,7 +64,7 @@
|
||||
/*
|
||||
* SWAP_B8_IN_B32 - swap 8 & 16 bits in 32 bits
|
||||
*
|
||||
* dest - pointer to where the swapped src wil be put
|
||||
* 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.
|
||||
@@ -86,7 +82,7 @@
|
||||
/*
|
||||
* SWAP_B32_IN_B64 - swap 32 bits in 64 bits
|
||||
*
|
||||
* dest - pointer to where the swapped src wil be put
|
||||
* 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) ( \
|
||||
@@ -97,7 +93,7 @@
|
||||
/*
|
||||
* SWAP_B16_IN_B64 - swap 16 & 32 bits in 64 bits
|
||||
*
|
||||
* dest - pointer to where the swapped src wil be put
|
||||
* 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) ( \
|
||||
@@ -110,7 +106,7 @@
|
||||
/*
|
||||
* SWAP_B8_IN_B64 - swap 16 & 32 bits in 64 bits
|
||||
*
|
||||
* dest - pointer to where the swapped src wil be put
|
||||
* 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.
|
||||
@@ -128,7 +124,7 @@
|
||||
/*
|
||||
* 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
|
||||
* 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) ( \
|
||||
@@ -139,7 +135,7 @@
|
||||
/*
|
||||
* 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
|
||||
* 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) ( \
|
||||
@@ -150,7 +146,7 @@
|
||||
/*
|
||||
* 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
|
||||
* 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.
|
||||
@@ -178,4 +174,4 @@
|
||||
#endif /* LONG_BITS == 64 */
|
||||
|
||||
|
||||
#endif /* !__BYTESWAP_H__ */
|
||||
#endif /* !INCLUDE_BYTESWAP_H */
|
||||
|
327
cal/Makefile
327
cal/Makefile
@@ -2,7 +2,15 @@
|
||||
#
|
||||
# cal - makefile for calc standard resource files
|
||||
#
|
||||
# Copyright (C) 1999 Landon Curt Noll
|
||||
# Copyright (C) 1999-2006,2017,2021,2022 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.
|
||||
#
|
||||
# Calc is open software; you can redistribute it and/or modify it under
|
||||
# the terms of the version 2.1 of the GNU Lesser General Public License
|
||||
@@ -16,11 +24,7 @@
|
||||
# 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.
|
||||
#
|
||||
# @(#) $Revision: 29.22 $
|
||||
# @(#) $Id: Makefile,v 29.22 2006/09/18 00:08:42 chongo Exp $
|
||||
# @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/Makefile,v $
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# Under source code control: 1991/07/21 05:00:54
|
||||
# File existed as early as: 1991
|
||||
@@ -31,16 +35,77 @@
|
||||
# calculator by David I. Bell with help/mods from others
|
||||
# Makefile by Landon Curt Noll
|
||||
|
||||
# required vars
|
||||
|
||||
# The shell used by this Makefile
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
MAKE_FILE = 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 sh may be a much better alternative
|
||||
# shell for this Makefile to use:
|
||||
#
|
||||
# SHELL= /bin/sh
|
||||
#
|
||||
SHELL= /bin/bash
|
||||
#SHELL= /bin/sh
|
||||
#if 0 /* start of skip for non-Gnu makefiles */
|
||||
ifeq ($(target),Darwin)
|
||||
SHELL:= /bin/zsh
|
||||
endif
|
||||
#endif /* end of skip for non-Gnu makefiles */
|
||||
|
||||
|
||||
####
|
||||
# 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
|
||||
|
||||
# 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.
|
||||
#
|
||||
# If in doubt, set MAKE_FILE to Makefile
|
||||
#
|
||||
MAKE_FILE= Makefile
|
||||
|
||||
# Where the system include (.h) files are kept
|
||||
#
|
||||
# For DJGPP, select:
|
||||
@@ -52,19 +117,19 @@ MAKE_FILE = Makefile
|
||||
# INCDIR= /usr/include
|
||||
#
|
||||
|
||||
#INCDIR= /usr/local/include
|
||||
#INCDIR= ${PREFIX}/include
|
||||
#INCDIR= /dev/env/DJDIR/include
|
||||
INCDIR= /usr/include
|
||||
|
||||
# where to install calc realted things
|
||||
# where to install calc related things
|
||||
#
|
||||
# ${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.
|
||||
# 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:
|
||||
#
|
||||
@@ -78,15 +143,15 @@ INCDIR= /usr/include
|
||||
# LIBDIR= /usr/lib
|
||||
# CALC_SHAREDIR= /usr/share/calc
|
||||
#
|
||||
#BINDIR= /usr/local/bin
|
||||
#BINDIR= ${PREFIX}/bin
|
||||
#BINDIR= /dev/env/DJDIR/bin
|
||||
BINDIR= /usr/bin
|
||||
|
||||
#LIBDIR= /usr/local/lib
|
||||
#LIBDIR= ${PREFIX}/lib
|
||||
#LIBDIR= /dev/env/DJDIR/lib
|
||||
LIBDIR= /usr/lib
|
||||
|
||||
#CALC_SHAREDIR= /usr/local/lib/calc
|
||||
#CALC_SHAREDIR= ${PREFIX}/lib/calc
|
||||
#CALC_SHAREDIR= /dev/env/DJDIR/share/calc
|
||||
CALC_SHAREDIR= /usr/share/calc
|
||||
|
||||
@@ -94,35 +159,26 @@ CALC_SHAREDIR= /usr/share/calc
|
||||
# ---------------------------------------------------------------
|
||||
# ${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
|
||||
# ${CUSTOMINCPDIR} where custom .h 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.
|
||||
# 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
|
||||
# CUSTOMCALDIR= ${CALC_SHAREDIR}/custom
|
||||
# CUSTOMHELPDIR= ${CALC_SHAREDIR}/custhelp
|
||||
# CUSTOMINCDIR= ${CALC_INCDIR}/custom
|
||||
# SCRIPTDIR= ${BINDIR}/cscript
|
||||
#
|
||||
HELPDIR= ${CALC_SHAREDIR}/help
|
||||
CALC_INCDIR= ${INCDIR}/calc
|
||||
CUSTOMCALDIR= ${CALC_SHAREDIR}/custom
|
||||
CUSTOMHELPDIR= ${CALC_SHAREDIR}/custhelp
|
||||
CUSTOMINCDIR= ${CALC_INCDIR}/custom
|
||||
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
|
||||
# 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:
|
||||
@@ -142,10 +198,10 @@ SCRIPTDIR= ${BINDIR}/cscript
|
||||
# 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 ${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=
|
||||
#
|
||||
@@ -153,31 +209,82 @@ T=
|
||||
|
||||
# Makefile debug
|
||||
#
|
||||
# Q=@ do not echo internal makefile actions (quiet mode)
|
||||
# Q= echo internal makefile actions (debug / verbose mode)
|
||||
# Q=@ do not echo internal Makefile actions (quiet mode)
|
||||
# Q= echo internal Makefile actions (debug / verbose mode)
|
||||
#
|
||||
# H=@: do not report hsrc file formation progress
|
||||
# H=@ do echo hsrc file formation progress
|
||||
#
|
||||
# S= >/dev/null 2>&1 silence ${CC} output during hsrc file formation
|
||||
# S= full ${CC} output 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)
|
||||
# V=@ do echo debug statements (debug / verbose mode)
|
||||
#
|
||||
#Q=
|
||||
Q=@
|
||||
#
|
||||
S= >/dev/null 2>&1
|
||||
#S=
|
||||
#
|
||||
E= 2>/dev/null
|
||||
#E=
|
||||
#
|
||||
#H=@:
|
||||
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
|
||||
#
|
||||
CALC_FILES= README bigprime.cal deg.cal ellip.cal lucas.cal lucas_chk.cal \
|
||||
lucas_tbl.cal mersenne.cal mod.cal pell.cal pi.cal pix.cal \
|
||||
pollard.cal poly.cal psqrt.cal quat.cal regress.cal solve.cal \
|
||||
sumsq.cal surd.cal unitfrac.cal varargs.cal chrem.cal mfactor.cal \
|
||||
bindings randmprime.cal test1700.cal randrun.cal linear.cal \
|
||||
randbitrun.cal bernoulli.cal test2300.cal test2600.cal \
|
||||
test2700.cal test3100.cal test3300.cal test3400.cal prompt.cal \
|
||||
test3500.cal seedrandom.cal test4000.cal test4100.cal test4600.cal \
|
||||
beer.cal hello.cal test5100.cal test5200.cal randombitrun.cal \
|
||||
randomrun.cal repeat.cal xx_print.cal natnumset.cal qtime.cal \
|
||||
test8400.cal test8500.cal test8600.cal chi.cal intfile.cal screen.cal \
|
||||
dotest.cal set8700.cal set8700.line alg_config.cal sumtimes.cal
|
||||
# This list is produced by the detaillist rule when no WARNINGS are detected.
|
||||
#
|
||||
# Please use:
|
||||
#
|
||||
# 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 \
|
||||
palindrome.cal pell.cal pi.cal pix.cal pollard.cal poly.cal prompt.cal \
|
||||
psqrt.cal qtime.cal quat.cal randbitrun.cal randmprime.cal \
|
||||
randombitrun.cal randomrun.cal randrun.cal regress.cal repeat.cal \
|
||||
screen.cal seedrandom.cal set8700.cal set8700.line smallfactors.cal \
|
||||
solve.cal specialfunctions.cal statistics.cal strings.cal sumsq.cal \
|
||||
sumtimes.cal surd.cal test1700.cal test2300.cal test2600.cal \
|
||||
test2700.cal test3100.cal test3300.cal test3400.cal test3500.cal \
|
||||
test4000.cal test4100.cal test4600.cal test5100.cal test5200.cal \
|
||||
test8400.cal test8500.cal test8600.cal test8900.cal toomcook.cal \
|
||||
unitfrac.cal varargs.cal xx_print.cal zeta2.cal
|
||||
|
||||
# These calc files are now obsolete and are removed by the install rule.
|
||||
#
|
||||
DEAD_CALC_FILES= lucas_tbl.cal
|
||||
|
||||
# These files are found (but not built) in the distribution
|
||||
#
|
||||
@@ -186,14 +293,20 @@ DISTLIST= ${CALC_FILES} ${MAKE_FILE}
|
||||
# These files are used to make (but not built) a calc .a link library
|
||||
#
|
||||
CALCLIBLIST=
|
||||
#
|
||||
# rules that are not also names of files
|
||||
#
|
||||
PHONY= all clobber distlist install
|
||||
|
||||
all: ${CALC_FILES} ${MAKE_FILE} .all
|
||||
|
||||
# used by the upper level Makefile to determine of we have done all
|
||||
#
|
||||
.all:
|
||||
rm -f .all
|
||||
touch .all
|
||||
${RM} -f .all
|
||||
${TOUCH} .all
|
||||
|
||||
.PHONY: ${PHONY}
|
||||
|
||||
##
|
||||
#
|
||||
@@ -204,7 +317,7 @@ all: ${CALC_FILES} ${MAKE_FILE} .all
|
||||
# sub-directory called calc/cal.
|
||||
#
|
||||
# NOTE: Due to bogus shells found on one common system we must have
|
||||
# an non-emoty else clause for every if condition. *sigh*
|
||||
# an non-empty else clause for every if condition. *sigh*
|
||||
#
|
||||
##
|
||||
|
||||
@@ -225,6 +338,21 @@ calcliblist:
|
||||
fi; \
|
||||
done
|
||||
|
||||
# These next rule help form the ${CALC_FILES} makefile variables above.
|
||||
#
|
||||
calc_files_list:
|
||||
${Q} -(find . -mindepth 1 -maxdepth 1 -type f -name '*.cal' -print | \
|
||||
while read i; do \
|
||||
echo $$i; \
|
||||
done; \
|
||||
echo '--first_line--'; \
|
||||
echo README; \
|
||||
echo set8700.line; \
|
||||
echo bindings) | \
|
||||
${SED} -e 's:^\./::' | LANG=C ${SORT} | ${FMT} -70 | \
|
||||
${SED} -e '1s/--first_line--/CALC_FILES=/' -e '2,$$s/^/ /' \
|
||||
-e 's/$$/ \\/' -e '$$s/ \\$$//'
|
||||
|
||||
##
|
||||
#
|
||||
# rpm rules
|
||||
@@ -246,38 +374,68 @@ echo_inst_files:
|
||||
|
||||
clean:
|
||||
|
||||
clobber:
|
||||
rm -f .all
|
||||
clobber: clean
|
||||
${RM} -f .all
|
||||
-${Q} if [ -e .DS_Store ]; then \
|
||||
echo ${RM} -rf .DS_Store; \
|
||||
${RM} -rf .DS_Store; \
|
||||
fi
|
||||
-${Q} for i in ${DEAD_CALC_FILES} /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; \
|
||||
fi; \
|
||||
done
|
||||
|
||||
# install everything
|
||||
#
|
||||
# NOTE: Keep the uninstall rule in reverse order to the install rule
|
||||
#
|
||||
install: all
|
||||
-${Q} if [ ! -d $T${CALC_SHAREDIR} ]; then \
|
||||
echo mkdir $T${CALC_SHAREDIR}; \
|
||||
mkdir $T${CALC_SHAREDIR}; \
|
||||
if [ ! -d "$T${CALC_SHAREDIR}" ]; then \
|
||||
echo mkdir -p "$T${CALC_SHAREDIR}"; \
|
||||
mkdir -p "$T${CALC_SHAREDIR}"; \
|
||||
-${Q} if [ ! -d ${T}${CALC_SHAREDIR} ]; then \
|
||||
echo ${MKDIR} -p ${T}${CALC_SHAREDIR}; \
|
||||
${MKDIR} -p ${T}${CALC_SHAREDIR}; \
|
||||
if [ ! -d "${T}${CALC_SHAREDIR}" ]; then \
|
||||
echo ${MKDIR} -p "${T}${CALC_SHAREDIR}"; \
|
||||
${MKDIR} -p "${T}${CALC_SHAREDIR}"; \
|
||||
fi; \
|
||||
echo ${CHMOD} 0755 $T${CALC_SHAREDIR}; \
|
||||
${CHMOD} 0755 $T${CALC_SHAREDIR}; \
|
||||
echo ${CHMOD} 0755 ${T}${CALC_SHAREDIR}; \
|
||||
${CHMOD} 0755 ${T}${CALC_SHAREDIR}; \
|
||||
else \
|
||||
true; \
|
||||
${TRUE}; \
|
||||
fi
|
||||
${Q} for i in ${CALC_FILES} /dev/null; do \
|
||||
if [ "$$i" = "/dev/null" ]; then \
|
||||
continue; \
|
||||
fi; \
|
||||
if ${CMP} -s $$i $T${CALC_SHAREDIR}/$$i; then \
|
||||
true; \
|
||||
if ${CMP} -s $$i ${T}${CALC_SHAREDIR}/$$i; then \
|
||||
${TRUE}; \
|
||||
else \
|
||||
rm -f $T${CALC_SHAREDIR}/$$i.new; \
|
||||
cp -f $$i $T${CALC_SHAREDIR}/$$i.new; \
|
||||
${CHMOD} 0444 $T${CALC_SHAREDIR}/$$i.new; \
|
||||
mv -f $T${CALC_SHAREDIR}/$$i.new $T${CALC_SHAREDIR}/$$i; \
|
||||
echo "installed $T${CALC_SHAREDIR}/$$i"; \
|
||||
${RM} -f ${T}${CALC_SHAREDIR}/$$i.new; \
|
||||
${CP} -f $$i ${T}${CALC_SHAREDIR}/$$i.new; \
|
||||
${CHMOD} 0444 ${T}${CALC_SHAREDIR}/$$i.new; \
|
||||
${MV} -f ${T}${CALC_SHAREDIR}/$$i.new ${T}${CALC_SHAREDIR}/$$i;\
|
||||
echo "installed ${T}${CALC_SHAREDIR}/$$i"; \
|
||||
fi; \
|
||||
done
|
||||
${Q} for i in ${DEAD_CALC_FILES} /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; \
|
||||
fi; \
|
||||
done
|
||||
|
||||
@@ -286,22 +444,35 @@ install: all
|
||||
# NOTE: Keep the uninstall rule in reverse order to the install rule
|
||||
#
|
||||
uninstall:
|
||||
- ${Q} for i in ${DEAD_CALC_FILES} /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; \
|
||||
fi; \
|
||||
done
|
||||
-${Q} for i in ${CALC_FILES} /dev/null; do \
|
||||
if [ "$$i" = "/dev/null" ]; then \
|
||||
continue; \
|
||||
fi; \
|
||||
if [ -f "$T${CALC_SHAREDIR}/$$i" ]; then \
|
||||
rm -f "$T${CALC_SHAREDIR}/$$i"; \
|
||||
if [ -f "$T${CALC_SHAREDIR}/$$i" ]; then \
|
||||
echo "cannot uninstall $T${CALC_SHAREDIR}/$$i"; \
|
||||
if [ -f "${T}${CALC_SHAREDIR}/$$i" ]; then \
|
||||
${RM} -f "${T}${CALC_SHAREDIR}/$$i"; \
|
||||
if [ -f "${T}${CALC_SHAREDIR}/$$i" ]; then \
|
||||
echo "cannot uninstall ${T}${CALC_SHAREDIR}/$$i"; \
|
||||
else \
|
||||
echo "uninstalled $T${CALC_SHAREDIR}/$$i"; \
|
||||
echo "un-installed ${T}${CALC_SHAREDIR}/$$i"; \
|
||||
fi; \
|
||||
fi; \
|
||||
done
|
||||
-${Q} for i in ${CALC_SHAREDIR}; do \
|
||||
if [ -d "$T$$i" ]; then \
|
||||
rmdir "$T$$i" 2>/dev/null; \
|
||||
echo "cleaned up $T$$i"; \
|
||||
if [ -d "${T}$$i" ]; then \
|
||||
${RMDIR} "${T}$$i" 2>/dev/null; \
|
||||
echo "cleaned up ${T}$$i"; \
|
||||
fi; \
|
||||
done
|
||||
|
897
cal/README
897
cal/README
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* alg_config - help determine optimal values for algorithm levels
|
||||
*
|
||||
* Copyright (C) 2006 Landon Curt Noll
|
||||
* Copyright (C) 2006,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
|
||||
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.14 $
|
||||
* @(#) $Id: alg_config.cal,v 29.14 2006/06/11 07:22:05 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/alg_config.cal,v $
|
||||
* 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
|
||||
@@ -28,8 +24,37 @@
|
||||
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
|
||||
*/
|
||||
|
||||
static test_time; /* try for this many seconds in loop test */
|
||||
|
||||
global test_time; /* try for this many seconds in loop test */
|
||||
|
||||
/*
|
||||
* close_to_one - set to 1 if the ratio is close enough to 1
|
||||
*
|
||||
* given:
|
||||
* ratio the ratio of time between two algorithms
|
||||
*
|
||||
* returns:
|
||||
* 1 When ratio is near 1.0
|
||||
* 0 otherwise
|
||||
*
|
||||
* We consider the range [0.995, 1.005] to be close enough to 1 to be call unity
|
||||
* because of the precision of the CPU timing.
|
||||
*/
|
||||
define close_to_one(ratio)
|
||||
{
|
||||
/* firewall */
|
||||
if (!isreal(ratio)) {
|
||||
quit "close: 1st arg: must be a real number";
|
||||
}
|
||||
|
||||
/* check if the ratio is far from unity */
|
||||
if ((ratio < 0.995) || (ratio > 1.005)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* we are close to unity */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@@ -80,12 +105,13 @@ define mul_loop(repeat, x)
|
||||
len = sizeof((*x)[0]) / baseb_bytes;
|
||||
for (i=1; i < 4; ++i) {
|
||||
if ((sizeof((*x)[i]) / baseb_bytes) != len) {
|
||||
quit "mul_loop: 2nd arg matrix elements are not of equal BASEB-bit word length";
|
||||
quit "mul_loop: 2nd arg matrix elements are not of "
|
||||
"equal BASEB-bit word length";
|
||||
}
|
||||
}
|
||||
|
||||
/* multiply pairwise, all sets of a given length */
|
||||
start = runtime();
|
||||
start = usertime();
|
||||
for (i=0; i < repeat; ++i) {
|
||||
|
||||
if (len == 1) {
|
||||
@@ -130,7 +156,7 @@ define mul_loop(repeat, x)
|
||||
/*
|
||||
* return duration
|
||||
*/
|
||||
end = runtime();
|
||||
end = usertime();
|
||||
return end-start;
|
||||
}
|
||||
|
||||
@@ -142,7 +168,7 @@ define mul_loop(repeat, x)
|
||||
* len length in BASEB-bit words to multiply
|
||||
*
|
||||
* return:
|
||||
* ratio of (1st / 2nd) algorithm rate
|
||||
* ratio of (1st / 2nd) algorithm rate.
|
||||
*
|
||||
* When want to determine a rate to a precision of 1 part in 1000.
|
||||
* Most systems today return CPU time to at least 10 msec precision.
|
||||
@@ -165,6 +191,7 @@ define mul_ratio(len)
|
||||
local tover; /* est of time for loop overhead */
|
||||
local alg1_rate; /* loop rate of 1st algorithm */
|
||||
local alg2_rate; /* loop rate of 2nd algorithm */
|
||||
local ret; /* return ratio, or 1.0 */
|
||||
local i;
|
||||
|
||||
/*
|
||||
@@ -217,12 +244,12 @@ define mul_ratio(len)
|
||||
* determine the 1st algorithm rate
|
||||
*/
|
||||
loops = max(1, ceil(loops * test_time / tlen));
|
||||
if (loops < 8) {
|
||||
if (loops < 16) {
|
||||
if (config("user_debug") > 1) {
|
||||
printf(" we must expand loop test time to more than %d secs\n",
|
||||
ceil(test_time * (8 / loops)));
|
||||
printf(" we must expand alg1 loop test time to about %d secs\n",
|
||||
ceil(test_time * (16 / loops)));
|
||||
}
|
||||
loops = 8;
|
||||
loops = 16;
|
||||
}
|
||||
if (config("user_debug") > 3) {
|
||||
printf("\t will try alg1 %d loops\n", loops);
|
||||
@@ -263,12 +290,12 @@ define mul_ratio(len)
|
||||
* determine the 2nd algorithm rate
|
||||
*/
|
||||
loops = max(1, ceil(loops * test_time / tlen));
|
||||
if (loops < 8) {
|
||||
if (loops < 16) {
|
||||
if (config("user_debug") > 1) {
|
||||
printf(" we must expand loop test time to more than %d secs\n",
|
||||
ceil(test_time * (8 / loops)));
|
||||
printf(" we must expand alg2 loop test time to about %d secs\n",
|
||||
ceil(test_time * (16 / loops)));
|
||||
}
|
||||
loops = 8;
|
||||
loops = 16;
|
||||
}
|
||||
tlen = mul_loop(loops, &x);
|
||||
if (config("user_debug") > 3) {
|
||||
@@ -297,7 +324,12 @@ define mul_ratio(len)
|
||||
/*
|
||||
* return alg1 / alg2 rate ratio
|
||||
*/
|
||||
return (alg1_rate / alg2_rate);
|
||||
ret = alg1_rate / alg2_rate;
|
||||
if (config("user_debug") > 2) {
|
||||
printf("\tprecise ratio is: %.f mul_ratio will return: %.3f\n",
|
||||
alg1_rate / alg2_rate, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -319,30 +351,40 @@ define best_mul2()
|
||||
{
|
||||
local ratio; /* previously calculated alg1/alg2 ratio */
|
||||
local low; /* low loop value tested */
|
||||
local high; /* low loop value tested */
|
||||
local high; /* high loop value tested */
|
||||
local mid; /* between low and high */
|
||||
local best_val; /* value found with ratio closest to unity */
|
||||
local best_ratio; /* closest ratio found to unity */
|
||||
local expand; /* how fast to expand the length */
|
||||
|
||||
/*
|
||||
* setup
|
||||
*/
|
||||
test_time = 15.0;
|
||||
if (config("user_debug") > 0) {
|
||||
printf("will start with loop test time of %d secs\n", test_time);
|
||||
printf("WARNING: This tool may not be computing the correct best value\n");
|
||||
test_time = 5.0;
|
||||
printf("The best_mul2() function will take a LONG time to run!\n");
|
||||
printf("It is important that best_mul2() run on an otherwise idle host!\n");
|
||||
if (config("user_debug") <= 0) {
|
||||
printf("To monitor progress, set user_debug to 2: "
|
||||
"config(\"user_debug\", 2)\n");
|
||||
}
|
||||
printf("Starting with loop test time of %d secs\n", test_time);
|
||||
|
||||
/*
|
||||
* firewall - must have a >1 ratio for the initial length
|
||||
*/
|
||||
high = 16;
|
||||
high = 8;
|
||||
best_val = high;
|
||||
if (config("user_debug") > 0) {
|
||||
printf("testing multiply alg1/alg2 ratio for len = %d\n", high);
|
||||
}
|
||||
ratio = mul_ratio(high);
|
||||
best_ratio = ratio;
|
||||
if (config("user_debug") > 1) {
|
||||
printf(" multiply alg1/alg2 ratio = %.3f\n", ratio);
|
||||
printf(" multiply alg1/alg2 ratio = %.6f\n", ratio);
|
||||
}
|
||||
if (ratio <= 1.0) {
|
||||
quit "best_mul2: tests imply config(\"mul2\") should be < 4";
|
||||
if (ratio < 1.0) {
|
||||
quit "best_mul2: tests imply mul2 should be < 16, which seems bogus";
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -350,12 +392,12 @@ define best_mul2()
|
||||
*/
|
||||
do {
|
||||
/*
|
||||
* determine the paramters of the next ratio test
|
||||
* determine the parameters of the next ratio test
|
||||
*
|
||||
* We will multiplicatively expand our test level until
|
||||
* the ratio drops below 1.0.
|
||||
*/
|
||||
expand = ((ratio >= 3.5) ? 16 : 2^round(ratio));
|
||||
expand = 2;
|
||||
low = high;
|
||||
high *= expand;
|
||||
if (config("user_debug") > 1) {
|
||||
@@ -367,19 +409,64 @@ define best_mul2()
|
||||
* determine the alg1/alg2 test ratio for this new length
|
||||
*/
|
||||
if (high >= 2^31) {
|
||||
quit "best_mul2: tests imply config(\"mul2\") should be >= 2^31";
|
||||
quit "best_mul2: test implies mul2 >= 2^31, which seems bogus";
|
||||
}
|
||||
if (config("user_debug") > 0) {
|
||||
printf("testing multiply alg1/alg2 ratio for len = %d\n", high);
|
||||
}
|
||||
ratio = mul_ratio(high);
|
||||
if (config("user_debug") > 1) {
|
||||
printf(" multiply alg1/alg2 ratio = %.3f\n", ratio);
|
||||
if (abs(ratio - 1.0) < abs(best_ratio - 1.0)) {
|
||||
best_val = high;
|
||||
best_ratio = ratio;
|
||||
if (config("user_debug") > 1) {
|
||||
printf(" len %d has a new closest ratio to unity: %.6f\n",
|
||||
best_val, best_ratio);
|
||||
}
|
||||
}
|
||||
} while (ratio >= 1.0);
|
||||
if (config("user_debug") > 1) {
|
||||
printf(" multiply alg1/alg2 ratio = %.6f\n", ratio);
|
||||
}
|
||||
} while (ratio > 1.0);
|
||||
|
||||
/*
|
||||
* If we previously expanded more than by a factor of 2, then
|
||||
* we may have jumped over the crossover point. So now
|
||||
* drop down powers of two until the ratio is again >= 1.0
|
||||
*/
|
||||
if (expand > 2) {
|
||||
do {
|
||||
|
||||
/*
|
||||
* contract by 2
|
||||
*/
|
||||
high /= 2;
|
||||
low = high / 2;
|
||||
if (config("user_debug") > 0) {
|
||||
printf("re-testing multiply alg1/alg2 ratio for len = %d\n",
|
||||
high);
|
||||
}
|
||||
ratio = mul_ratio(high);
|
||||
if (abs(ratio - 1.0) < abs(best_ratio - 1.0)) {
|
||||
best_val = high;
|
||||
best_ratio = ratio;
|
||||
if (config("user_debug") > 1) {
|
||||
printf(" len %d has a new closest ratio "
|
||||
"to unity: %.6f\n",
|
||||
best_val, best_ratio);
|
||||
}
|
||||
}
|
||||
if (config("user_debug") > 1) {
|
||||
printf(" multiply alg1/alg2 ratio = %.6f\n", ratio);
|
||||
}
|
||||
|
||||
} while (ratio <= 1.0);
|
||||
|
||||
/* now that the ratio flipped again, use the previous range */
|
||||
low = high;
|
||||
high = high * 2;
|
||||
}
|
||||
if (config("user_debug") > 0) {
|
||||
printf("alg1/alg2 ratio now < 1.0, starting binary search between %d and %d\n",
|
||||
low, high);
|
||||
printf("Starting binary search between %d and %d\n", low, high);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -387,31 +474,55 @@ define best_mul2()
|
||||
*/
|
||||
while (low+1 < high) {
|
||||
|
||||
/* try the mid-point */
|
||||
/* try the mid-point */
|
||||
mid = int((low+high)/2);
|
||||
if (config("user_debug") > 0) {
|
||||
printf("testing multiply alg1/alg2 ratio for len = %d\n",
|
||||
int((low+high)/2));
|
||||
printf("testing multiply alg1/alg2 ratio for len = %d\n", mid);
|
||||
}
|
||||
ratio = mul_ratio(mid);
|
||||
if (abs(ratio - 1.0) < abs(best_ratio - 1.0)) {
|
||||
best_val = mid;
|
||||
best_ratio = ratio;
|
||||
if (config("user_debug") > 1) {
|
||||
printf(" len %d has a new closest ratio to unity: %.6f\n",
|
||||
best_val, best_ratio);
|
||||
}
|
||||
}
|
||||
ratio = mul_ratio(int((low+high)/2));
|
||||
if (config("user_debug") > 1) {
|
||||
printf(" multiply alg1/alg2 ratio = %.3f\n", ratio);
|
||||
printf(" len %d multiply alg1/alg2 ratio = %.6f\n", mid, ratio);
|
||||
}
|
||||
|
||||
/* stop search if near unity */
|
||||
if (close_to_one(ratio)) {
|
||||
low = mid;
|
||||
high = mid;
|
||||
if (config("user_debug") > 0) {
|
||||
printf("\twe are close enough to unity ratio at: %d\n", mid);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* bump lower range up if we went over */
|
||||
if (ratio >= 1.0) {
|
||||
if (ratio > 1.0) {
|
||||
if (config("user_debug") > 2) {
|
||||
printf("\tmove low from %d up to %d\n",
|
||||
low, int((low+high)/2));
|
||||
printf("\tmove low from %d up to %d\n",
|
||||
low, mid);
|
||||
}
|
||||
low = int((low+high)/2);
|
||||
low = mid;
|
||||
|
||||
/* drop higher range down if we went under */
|
||||
} else {
|
||||
if (config("user_debug") > 2) {
|
||||
printf("\tmove high from %d down to %d\n",
|
||||
high, int((low+high)/2));
|
||||
printf("\tmove high from %d down to %d\n",
|
||||
high, mid);
|
||||
}
|
||||
high = int((low+high)/2);
|
||||
high = mid;
|
||||
}
|
||||
|
||||
/* report on test loop progress */
|
||||
if (config("user_debug") > 1) {
|
||||
printf("\tsetting low: %d high: %d diff: %d\n",
|
||||
low, high, high-low);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,10 +530,15 @@ define best_mul2()
|
||||
* return on the suggested config("mul2") value
|
||||
*/
|
||||
if (config("user_debug") > 0) {
|
||||
printf("best value of config(\"mul2\") is %d\n",
|
||||
(ratio >= 1.0) ? high : low);
|
||||
printf("Best value for multiply is near %d\n", best_val);
|
||||
printf("Best multiply alg1/alg2 ratio is: %.6f\n", best_ratio);
|
||||
printf("We suggest placing this line in your .calcrc:\n");
|
||||
printf("config(\"mul2\", %d),;\n", best_val);
|
||||
printf("WARNING: It is believed that the output "
|
||||
"of this resource file is bogus!\n");
|
||||
printf("WARNING: You may NOT wish to follow the above suggestion.\n");
|
||||
}
|
||||
return ((ratio >= 1.0) ? high : low);
|
||||
return mid;
|
||||
}
|
||||
|
||||
|
||||
@@ -472,12 +588,13 @@ define sq_loop(repeat, x)
|
||||
len = sizeof((*x)[0]) / baseb_bytes;
|
||||
for (i=1; i < 4; ++i) {
|
||||
if ((sizeof((*x)[i]) / baseb_bytes) != len) {
|
||||
quit "sq_loop: 2nd arg matrix elements are not of equal BASEB-bit word length";
|
||||
quit "sq_loop: 2nd arg matrix elements are not of equal "
|
||||
"BASEB-bit word length";
|
||||
}
|
||||
}
|
||||
|
||||
/* square pairwise, all sets of a given length */
|
||||
start = runtime();
|
||||
start = usertime();
|
||||
for (i=0; i < repeat; ++i) {
|
||||
|
||||
if (len == 1) {
|
||||
@@ -524,7 +641,7 @@ define sq_loop(repeat, x)
|
||||
/*
|
||||
* return duration
|
||||
*/
|
||||
end = runtime();
|
||||
end = usertime();
|
||||
return end-start;
|
||||
}
|
||||
|
||||
@@ -559,6 +676,7 @@ define sq_ratio(len)
|
||||
local tover; /* est of time for loop overhead */
|
||||
local alg1_rate; /* loop rate of 1st algorithm */
|
||||
local alg2_rate; /* loop rate of 2nd algorithm */
|
||||
local ret; /* return ratio, or 1.0 */
|
||||
local i;
|
||||
|
||||
/*
|
||||
@@ -611,12 +729,12 @@ define sq_ratio(len)
|
||||
* determine the 1st algorithm rate
|
||||
*/
|
||||
loops = max(1, ceil(loops * test_time / tlen));
|
||||
if (loops < 8) {
|
||||
if (loops < 16) {
|
||||
if (config("user_debug") > 1) {
|
||||
printf(" we must expand loop test time to more than %d secs\n",
|
||||
ceil(test_time * (8 / loops)));
|
||||
printf(" we must expand alg1 loop test time to about %d secs\n",
|
||||
ceil(test_time * (16 / loops)));
|
||||
}
|
||||
loops = 8;
|
||||
loops = 16;
|
||||
}
|
||||
tlen = sq_loop(loops, &x);
|
||||
if (config("user_debug") > 3) {
|
||||
@@ -654,12 +772,12 @@ define sq_ratio(len)
|
||||
* determine the 2nd algorithm rate
|
||||
*/
|
||||
loops = max(1, ceil(loops * test_time / tlen));
|
||||
if (loops < 8) {
|
||||
if (loops < 16) {
|
||||
if (config("user_debug") > 1) {
|
||||
printf(" we must expand loop test time to more than %d secs\n",
|
||||
ceil(test_time * (8 / loops)));
|
||||
printf(" we must expand alg2 loop test time to about %d secs\n",
|
||||
ceil(test_time * (16 / loops)));
|
||||
}
|
||||
loops = 8;
|
||||
loops = 16;
|
||||
}
|
||||
tlen = sq_loop(loops, &x);
|
||||
if (config("user_debug") > 3) {
|
||||
@@ -688,7 +806,12 @@ define sq_ratio(len)
|
||||
/*
|
||||
* return alg1 / alg2 rate ratio
|
||||
*/
|
||||
return (alg1_rate / alg2_rate);
|
||||
ret = alg1_rate / alg2_rate;
|
||||
if (config("user_debug") > 2) {
|
||||
printf("\tprecise ratio is: %.f sq_ratio will return: %.3f\n",
|
||||
alg1_rate / alg2_rate, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -710,30 +833,40 @@ define best_sq2()
|
||||
{
|
||||
local ratio; /* previously calculated alg1/alg2 ratio */
|
||||
local low; /* low loop value tested */
|
||||
local high; /* low loop value tested */
|
||||
local high; /* high loop value tested */
|
||||
local mid; /* between low and high */
|
||||
local best_val; /* value found with ratio closest to unity */
|
||||
local best_ratio; /* closest ratio found to unity */
|
||||
local expand; /* how fast to expand the length */
|
||||
|
||||
/*
|
||||
* setup
|
||||
*/
|
||||
test_time = 15.0;
|
||||
if (config("user_debug") > 0) {
|
||||
printf("will start with loop test time of %d secs\n", test_time);
|
||||
printf("WARNING: This tool may not be computing the correct best value\n");
|
||||
test_time = 5.0;
|
||||
printf("The best_sq2() function will take a LONG time to run!\n");
|
||||
printf("It is important that best_sq2() run on an otherwise idle host!\n");
|
||||
if (config("user_debug") <= 0) {
|
||||
printf("To monitor progress, set user_debug to 2: "
|
||||
"config(\"user_debug\", 2)\n");
|
||||
}
|
||||
printf("Starting with loop test time of %d secs\n", test_time);
|
||||
|
||||
/*
|
||||
* firewall - must have a >1 ratio for the initial length
|
||||
*/
|
||||
high = 16;
|
||||
high = 8;
|
||||
best_val = high;
|
||||
if (config("user_debug") > 0) {
|
||||
printf("testing square alg1/alg2 ratio for len = %d\n", high);
|
||||
}
|
||||
ratio = sq_ratio(high);
|
||||
best_ratio = ratio;
|
||||
if (config("user_debug") > 1) {
|
||||
printf(" square alg1/alg2 ratio = %.3f\n", ratio);
|
||||
}
|
||||
if (ratio <= 1.0) {
|
||||
quit "best_sq2: tests imply config(\"sq2\") should be < 4";
|
||||
if (ratio < 1.0) {
|
||||
quit "best_sq2: test implies sq2 < 16, which seems bogus";
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -741,36 +874,81 @@ define best_sq2()
|
||||
*/
|
||||
do {
|
||||
/*
|
||||
* determine the paramters of the next ratio test
|
||||
* determine the parameters of the next ratio test
|
||||
*
|
||||
* We will multiplicatively expand our test level until
|
||||
* the ratio drops below 1.0.
|
||||
*/
|
||||
expand = ((ratio >= 3.5) ? 16 : 2^round(ratio));
|
||||
expand = 2;
|
||||
low = high;
|
||||
high *= expand;
|
||||
if (config("user_debug") > 1) {
|
||||
printf(" expand the next test range by a factor of %d\n",
|
||||
expand);
|
||||
expand);
|
||||
}
|
||||
|
||||
/*
|
||||
* determine the alg1/alg2 test ratio for this new length
|
||||
*/
|
||||
if (high >= 2^31) {
|
||||
quit "best_sq2: tests imply config(\"sq2\") should be >= 2^31";
|
||||
quit "best_sq2: tests imply sq2 >= 2^31, which seems bogus";
|
||||
}
|
||||
if (config("user_debug") > 0) {
|
||||
printf("testing square alg1/alg2 ratio for len = %d\n", high);
|
||||
}
|
||||
ratio = sq_ratio(high);
|
||||
if (abs(ratio - 1.0) < abs(best_ratio - 1.0)) {
|
||||
best_val = high;
|
||||
best_ratio = ratio;
|
||||
if (config("user_debug") > 1) {
|
||||
printf(" len %d has a new closest ratio to unity: %.6f\n",
|
||||
best_val, best_ratio);
|
||||
}
|
||||
}
|
||||
if (config("user_debug") > 1) {
|
||||
printf(" square alg1/alg2 ratio = %.3f\n", ratio);
|
||||
}
|
||||
} while (ratio >= 1.0);
|
||||
} while (ratio > 1.0);
|
||||
|
||||
/*
|
||||
* If we previously expanded more than by a factor of 2, then
|
||||
* we may have jumped over the crossover point. So now
|
||||
* drop down powers of two until the ratio is again >= 1.0
|
||||
*/
|
||||
if (expand > 2) {
|
||||
do {
|
||||
|
||||
/*
|
||||
* contract by 2
|
||||
*/
|
||||
high /= 2;
|
||||
low = high / 2;
|
||||
if (config("user_debug") > 0) {
|
||||
printf("re-testing multiply alg1/alg2 ratio for len = %d\n",
|
||||
high);
|
||||
}
|
||||
ratio = mul_ratio(high);
|
||||
if (abs(ratio - 1.0) < abs(best_ratio - 1.0)) {
|
||||
best_val = high;
|
||||
best_ratio = ratio;
|
||||
if (config("user_debug") > 1) {
|
||||
printf(" len %d has a new closest ratio "
|
||||
"to unity: %.6f\n",
|
||||
best_val, best_ratio);
|
||||
}
|
||||
}
|
||||
if (config("user_debug") > 1) {
|
||||
printf(" multiply alg1/alg2 ratio = %.6f\n", ratio);
|
||||
}
|
||||
|
||||
} while (ratio <= 1.0);
|
||||
|
||||
/* now that the ratio flipped again, use the previous range */
|
||||
low = high;
|
||||
high = high * 2;
|
||||
}
|
||||
if (config("user_debug") > 0) {
|
||||
printf("alg1/alg2 ratio now < 1.0, starting binary search between %d and %d\n",
|
||||
low, high);
|
||||
printf("Starting binary search between %d and %d\n", low, high);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -778,42 +956,72 @@ define best_sq2()
|
||||
*/
|
||||
while (low+1 < high) {
|
||||
|
||||
/* try the mid-point */
|
||||
/* try the mid-point */
|
||||
mid = int((low+high)/2);
|
||||
if (config("user_debug") > 0) {
|
||||
printf("testing square alg1/alg2 ratio for len = %d\n",
|
||||
int((low+high)/2));
|
||||
printf("testing square alg1/alg2 ratio for len = %d\n", mid);
|
||||
}
|
||||
ratio = sq_ratio(mid);
|
||||
if (abs(ratio - 1.0) < abs(best_ratio - 1.0)) {
|
||||
best_val = mid;
|
||||
best_ratio = ratio;
|
||||
if (config("user_debug") > 1) {
|
||||
printf(" len %d has a new closest ratio to unity: %.6f\n",
|
||||
best_val, best_ratio);
|
||||
}
|
||||
}
|
||||
ratio = sq_ratio(int((low+high)/2));
|
||||
if (config("user_debug") > 1) {
|
||||
printf(" square alg1/alg2 ratio = %.3f\n", ratio);
|
||||
printf(" len %d square alg1/alg2 ratio = %.6f\n", mid, ratio);
|
||||
}
|
||||
|
||||
/* stop search if near unity */
|
||||
if (close_to_one(ratio)) {
|
||||
low = mid;
|
||||
high = mid;
|
||||
if (config("user_debug") > 0) {
|
||||
printf("\twe are close enough to unity ratio at: %d\n", mid);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* bump lower range up if we went over */
|
||||
if (ratio >= 1.0) {
|
||||
if (ratio > 1.0) {
|
||||
if (config("user_debug") > 2) {
|
||||
printf("\tmove low from %d up to %d\n",
|
||||
low, int((low+high)/2));
|
||||
printf("\tmove low from %d up to %d\n",
|
||||
low, mid);
|
||||
}
|
||||
low = int((low+high)/2);
|
||||
low = mid;
|
||||
|
||||
/* drop higher range down if we went under */
|
||||
} else {
|
||||
if (config("user_debug") > 2) {
|
||||
printf("\tmove high from %d down to %d\n",
|
||||
high, int((low+high)/2));
|
||||
printf("\tmove high from %d down to %d\n",
|
||||
high, mid);
|
||||
}
|
||||
high = int((low+high)/2);
|
||||
high = mid;
|
||||
}
|
||||
|
||||
/* report on test loop progress */
|
||||
if (config("user_debug") > 1) {
|
||||
printf("\tsetting low: %d high: %d diff: %d\n",
|
||||
low, high, high-low);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* return on the suggested config("sq2") value
|
||||
*/
|
||||
mid = int((low+high)/2);
|
||||
if (config("user_debug") > 0) {
|
||||
printf("best value of config(\"sq2\") is %d\n",
|
||||
(ratio >= 1.0) ? high : low);
|
||||
printf("Best value for square is near %d\n", best_val);
|
||||
printf("Best square alg1/alg2 ratio is: %.6f\n", best_ratio);
|
||||
printf("We suggest placing this line in your .calcrc:\n");
|
||||
printf("config(\"sq2\", %d),;\n", best_val);
|
||||
printf("WARNING: It is believed that the output "
|
||||
"of this resource file is bogus!\n");
|
||||
printf("WARNING: You may NOT wish to follow the above suggestion.\n");
|
||||
}
|
||||
return ((ratio >= 1.0) ? high : low);
|
||||
return mid;
|
||||
}
|
||||
|
||||
|
||||
@@ -866,7 +1074,8 @@ define pow_loop(repeat, x, ex)
|
||||
len = sizeof((*x)[0]) / baseb_bytes;
|
||||
for (i=1; i < 4; ++i) {
|
||||
if ((sizeof((*x)[i]) / baseb_bytes) != len) {
|
||||
quit "pow_loop: 2nd arg matrix elements are not of equal BASEB-bit word length";
|
||||
quit "pow_loop: 2nd arg matrix elements are not of "
|
||||
"equal BASEB-bit word length";
|
||||
}
|
||||
}
|
||||
if (!isint(ex) || ex < 3) {
|
||||
@@ -874,7 +1083,7 @@ define pow_loop(repeat, x, ex)
|
||||
}
|
||||
|
||||
/* pmod pairwise, all sets of a given length */
|
||||
start = runtime();
|
||||
start = usertime();
|
||||
for (i=0; i < repeat; ++i) {
|
||||
|
||||
if (len == 1) {
|
||||
@@ -927,7 +1136,7 @@ define pow_loop(repeat, x, ex)
|
||||
/*
|
||||
* return duration
|
||||
*/
|
||||
end = runtime();
|
||||
end = usertime();
|
||||
return end-start;
|
||||
}
|
||||
|
||||
@@ -963,6 +1172,7 @@ define pow_ratio(len)
|
||||
local alg1_rate; /* loop rate of 1st algorithm */
|
||||
local alg2_rate; /* loop rate of 2nd algorithm */
|
||||
local ex; /* exponent to use in pow_loop() */
|
||||
local ret; /* return ratio, or 1.0 */
|
||||
local i;
|
||||
|
||||
/*
|
||||
@@ -985,7 +1195,7 @@ define pow_ratio(len)
|
||||
/*
|
||||
* setup
|
||||
*/
|
||||
ex = 5;
|
||||
ex = 7;
|
||||
|
||||
/*
|
||||
* initialize x, the values we will pmod
|
||||
@@ -1021,12 +1231,12 @@ define pow_ratio(len)
|
||||
* determine the 1st algorithm rate
|
||||
*/
|
||||
loops = max(1, ceil(loops * test_time / tlen));
|
||||
if (loops < 8) {
|
||||
if (loops < 16) {
|
||||
if (config("user_debug") > 1) {
|
||||
printf(" we must expand loop test time to more than %d secs\n",
|
||||
ceil(test_time * (8 / loops)));
|
||||
printf(" we must expand alg1 loop test time to about %d secs\n",
|
||||
ceil(test_time * (16 / loops)));
|
||||
}
|
||||
loops = 8;
|
||||
loops = 16;
|
||||
}
|
||||
tlen = pow_loop(loops, &x, ex);
|
||||
if (config("user_debug") > 3) {
|
||||
@@ -1065,12 +1275,12 @@ define pow_ratio(len)
|
||||
* determine the 2nd algorithm rate
|
||||
*/
|
||||
loops = max(1, ceil(loops * test_time / tlen));
|
||||
if (loops < 8) {
|
||||
if (loops < 16) {
|
||||
if (config("user_debug") > 1) {
|
||||
printf(" we must expand loop test time to more than %d secs\n",
|
||||
ceil(test_time * (8 / loops)));
|
||||
printf(" we must expand alg2 loop test time to about %d secs\n",
|
||||
ceil(test_time * (16 / loops)));
|
||||
}
|
||||
loops = 8;
|
||||
loops = 16;
|
||||
}
|
||||
tlen = pow_loop(loops, &x, ex);
|
||||
if (config("user_debug") > 3) {
|
||||
@@ -1099,7 +1309,12 @@ define pow_ratio(len)
|
||||
/*
|
||||
* return alg1 / alg2 rate ratio
|
||||
*/
|
||||
return (alg1_rate / alg2_rate);
|
||||
ret = alg1_rate / alg2_rate;
|
||||
if (config("user_debug") > 2) {
|
||||
printf("\tprecise ratio is: %.f pow_ratio will return: %.3f\n",
|
||||
alg1_rate / alg2_rate, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -1121,37 +1336,56 @@ define best_pow2()
|
||||
{
|
||||
local ratio; /* previously calculated alg1/alg2 ratio */
|
||||
local low; /* low loop value tested */
|
||||
local high; /* low loop value tested */
|
||||
local high; /* high loop value tested */
|
||||
local mid; /* between low and high */
|
||||
local best_val; /* value found with ratio closest to unity */
|
||||
local best_ratio; /* closest ratio found to unity */
|
||||
local expand; /* how fast to expand the length */
|
||||
local looped; /* 1 ==> we have expanded lengths before */
|
||||
|
||||
/*
|
||||
* setup
|
||||
*/
|
||||
test_time = 15.0;
|
||||
if (config("user_debug") > 0) {
|
||||
printf("will start with loop test time of %d secs\n", test_time);
|
||||
printf("WARNING: This tool may not be computing the correct best value\n");
|
||||
test_time = 60.0;
|
||||
printf("The best_pow2() function will take a LONG time to run!\n");
|
||||
printf("It is important that best_pow2() run on an otherwise idle host!\n");
|
||||
if (config("user_debug") <= 0) {
|
||||
printf("To monitor progress, set user_debug to 2: "
|
||||
"config(\"user_debug\", 2)\n");
|
||||
}
|
||||
printf("Starting with loop test time of %d secs\n", test_time);
|
||||
|
||||
/*
|
||||
* firewall - must have a >1.02 ratio for the initial length
|
||||
*
|
||||
* We select 1.02 because of the precision of the CPU timing. We
|
||||
* want to firt move into an area where the 1st algoritm clearly
|
||||
* want to first move into an area where the 1st algorithm clearly
|
||||
* dominates.
|
||||
*/
|
||||
low = 4;
|
||||
high = 4;
|
||||
best_val = high;
|
||||
best_ratio = 1e10; /* not a real value */
|
||||
do {
|
||||
high *= 4;
|
||||
if (config("user_debug") > 0) {
|
||||
printf("testing pmod alg1/alg2 ratio for len = %d\n", high);
|
||||
}
|
||||
ratio = pow_ratio(high);
|
||||
if (abs(ratio - 1.0) < abs(best_ratio - 1.0)) {
|
||||
best_val = high;
|
||||
best_ratio = ratio;
|
||||
if (config("user_debug") > 1) {
|
||||
printf(" len %d has a new closest ratio to unity: %.6f\n",
|
||||
best_val, best_ratio);
|
||||
}
|
||||
}
|
||||
if (config("user_debug") > 1) {
|
||||
printf(" pmod alg1/alg2 ratio = %.3f\n", ratio);
|
||||
if (ratio > 1.0 && ratio <= 1.02) {
|
||||
printf(" while alg1 is slightly better than alg2, it is not clearly better\n");
|
||||
printf(" while alg1 is slightly better than alg2, "
|
||||
"it is not clearly better\n");
|
||||
}
|
||||
}
|
||||
} while (ratio <= 1.02);
|
||||
@@ -1165,7 +1399,7 @@ define best_pow2()
|
||||
looped = 0;
|
||||
do {
|
||||
/*
|
||||
* determine the paramters of the next ratio test
|
||||
* determine the parameters of the next ratio test
|
||||
*
|
||||
* We will multiplicatively expand our test level until
|
||||
* the ratio drops below 1.0.
|
||||
@@ -1186,27 +1420,34 @@ define best_pow2()
|
||||
high *= expand;
|
||||
if (config("user_debug") > 1) {
|
||||
printf(" expand the next test range by a factor of %d\n",
|
||||
expand);
|
||||
expand);
|
||||
}
|
||||
|
||||
/*
|
||||
* determine the alg1/alg2 test ratio for this new length
|
||||
*/
|
||||
if (high >= 2^31) {
|
||||
quit "best_pow2: tests imply config(\"pow2\") should be >= 2^31";
|
||||
quit "best_pow2: test implies pow2 >= 2^31, which seems bogus";
|
||||
}
|
||||
if (config("user_debug") > 0) {
|
||||
printf("testing pmod alg1/alg2 ratio for len = %d\n", high);
|
||||
}
|
||||
ratio = pow_ratio(high);
|
||||
if (abs(ratio - 1.0) < abs(best_ratio - 1.0)) {
|
||||
best_val = high;
|
||||
best_ratio = ratio;
|
||||
if (config("user_debug") > 1) {
|
||||
printf(" len %d has a new closest ratio to unity: %.6f\n",
|
||||
best_val, best_ratio);
|
||||
}
|
||||
}
|
||||
if (config("user_debug") > 1) {
|
||||
printf(" pmod alg1/alg2 ratio = %.3f\n", ratio);
|
||||
printf(" pmod alg1/alg2 ratio = %.6f\n", ratio);
|
||||
}
|
||||
looped = 1;
|
||||
} while (ratio >= 1.0);
|
||||
} while (ratio > 1.0);
|
||||
if (config("user_debug") > 0) {
|
||||
printf("alg1/alg2 ratio now < 1.0, starting binary search between %d and %d\n",
|
||||
low, high);
|
||||
printf("Starting binary search between %d and %d\n", low, high);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1214,40 +1455,70 @@ define best_pow2()
|
||||
*/
|
||||
while (low+1 < high) {
|
||||
|
||||
/* try the mid-point */
|
||||
/* try the mid-point */
|
||||
mid = int((low+high)/2);
|
||||
if (config("user_debug") > 0) {
|
||||
printf("testing pmod alg1/alg2 ratio for len = %d\n",
|
||||
int((low+high)/2));
|
||||
printf("testing pow2 alg1/alg2 ratio for len = %d\n", mid);
|
||||
}
|
||||
ratio = pow_ratio(mid);
|
||||
if (abs(ratio - 1.0) < abs(best_ratio - 1.0)) {
|
||||
best_val = mid;
|
||||
best_ratio = ratio;
|
||||
if (config("user_debug") > 1) {
|
||||
printf(" len %d has a new closest ratio to unity: %.6f\n",
|
||||
best_val, best_ratio);
|
||||
}
|
||||
}
|
||||
ratio = pow_ratio(int((low+high)/2));
|
||||
if (config("user_debug") > 1) {
|
||||
printf(" pmod alg1/alg2 ratio = %.3f\n", ratio);
|
||||
printf(" len %d pmod alg1/alg2 ratio = %.6f\n", mid, ratio);
|
||||
}
|
||||
|
||||
/* stop search if near unity */
|
||||
if (close_to_one(ratio)) {
|
||||
low = mid;
|
||||
high = mid;
|
||||
if (config("user_debug") > 0) {
|
||||
printf("\twe are close enough to unity ratio at: %d\n", mid);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* bump lower range up if we went over */
|
||||
if (ratio >= 1.0) {
|
||||
if (ratio > 1.0) {
|
||||
if (config("user_debug") > 2) {
|
||||
printf("\tmove low from %d up to %d\n",
|
||||
low, int((low+high)/2));
|
||||
printf("\tmove low from %d up to %d\n",
|
||||
low, mid);
|
||||
}
|
||||
low = int((low+high)/2);
|
||||
low = mid;
|
||||
|
||||
/* drop higher range down if we went under */
|
||||
} else {
|
||||
if (config("user_debug") > 2) {
|
||||
printf("\tmove high from %d down to %d\n",
|
||||
high, int((low+high)/2));
|
||||
printf("\tmove high from %d down to %d\n",
|
||||
high, mid);
|
||||
}
|
||||
high = int((low+high)/2);
|
||||
high = mid;
|
||||
}
|
||||
|
||||
/* report on test loop progress */
|
||||
if (config("user_debug") > 1) {
|
||||
printf("\tsetting low: %d high: %d diff: %d\n",
|
||||
low, high, high-low);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* return on the suggested config("pow2") value
|
||||
*/
|
||||
mid = int((low+high)/2);
|
||||
if (config("user_debug") > 0) {
|
||||
printf("best value of config(\"pow2\") is %d\n",
|
||||
(ratio >= 1.0) ? high : low);
|
||||
printf("Best value for pmod is near %d\n", best_val);
|
||||
printf("Best pmod alg1/alg2 ratio is: %.6f\n", best_ratio);
|
||||
printf("We suggest placing this line in your .calcrc:\n");
|
||||
printf("config(\"pow2\", %d),;\n", best_val);
|
||||
printf("WARNING: It is believed that the output "
|
||||
"of this resource file is bogus!\n");
|
||||
printf("WARNING: You may NOT wish to follow the above suggestion.\n");
|
||||
}
|
||||
return ((ratio >= 1.0) ? high : low);
|
||||
return mid;
|
||||
}
|
||||
|
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: beer.cal,v 29.2 2000/06/07 14:02:25 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/beer.cal,v $
|
||||
* 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
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* bernoulli - clculate the Nth Bernoulli number B(n)
|
||||
* bernoulli - calculate the Nth Bernoulli number B(n)
|
||||
*
|
||||
* Copyright (C) 2000 David I. Bell and Landon Curt Noll
|
||||
* Copyright (C) 2000,2021 David I. Bell and Landon Curt Noll
|
||||
*
|
||||
* Calc is open software; you can redistribute it and/or modify it under
|
||||
* the terms of the version 2.1 of the GNU Lesser General Public License
|
||||
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.3 $
|
||||
* @(#) $Id: bernoulli.cal,v 29.3 2000/12/17 12:26:04 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/bernoulli.cal,v $
|
||||
* 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
|
||||
@@ -30,9 +26,9 @@
|
||||
/*
|
||||
* Calculate the Nth Bernoulli number B(n).
|
||||
*
|
||||
* NOTE: This is now a bulitin function.
|
||||
* NOTE: This is now a builtin function.
|
||||
*
|
||||
* The non-buildin code used the following symbolic formula to calculate B(n):
|
||||
* The non-builtin code used the following symbolic formula to calculate B(n):
|
||||
*
|
||||
* (b+1)^(n+1) - b^(n+1) = 0
|
||||
*
|
||||
@@ -46,7 +42,7 @@
|
||||
* B(3) = -(6*B(2) + 4*B(1) + 1) / 4
|
||||
*
|
||||
* The combinatorial factors in the expansion of the above formula are
|
||||
* calculated interatively, and we use the fact that B(2i+1) = 0 if i > 0.
|
||||
* calculated interactively, and we use the fact that B(2i+1) = 0 if i > 0.
|
||||
* Since all previous B(n)'s are needed to calculate a particular B(n), all
|
||||
* values obtained are saved in an array for ease in repeated calculations.
|
||||
*/
|
||||
|
55
cal/bernpoly.cal
Normal file
55
cal/bernpoly.cal
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* bernpoly - Bernoulli polynomials B_n(z) for arbitrary n,z..
|
||||
*
|
||||
* Copyright (C) 2013,2021 Christoph Zurnieden
|
||||
*
|
||||
* 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: 2013/08/11 01:31:28
|
||||
* File existed as early as: 2013
|
||||
*/
|
||||
|
||||
|
||||
static resource_debug_level;
|
||||
resource_debug_level = config("resource_debug", 0);
|
||||
|
||||
|
||||
read -once zeta2
|
||||
|
||||
|
||||
/* Idea by Don Zagier */
|
||||
define bernpoly(n,z){
|
||||
local h s c k;
|
||||
if(isint(n) && n>=0){
|
||||
h=0;s=0;c=-1;
|
||||
for(k=1;k<=n+1;k++){
|
||||
c*=1-(n+2)/k;
|
||||
s+=z^n;
|
||||
z++;
|
||||
h+=c*s/k;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
else return -n*hurwitzzeta(1-n,z);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* restore internal function from resource debugging
|
||||
*/
|
||||
config("resource_debug", resource_debug_level),;
|
||||
if (config("resource_debug") & 3) {
|
||||
print "bernpoly(n,z)";
|
||||
}
|
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: bigprime.cal,v 29.2 2000/06/07 14:02:25 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/bigprime.cal,v $
|
||||
* 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
|
||||
|
@@ -14,11 +14,7 @@
|
||||
# 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.
|
||||
#
|
||||
# @(#) $Revision: 29.2 $
|
||||
# @(#) $Id: bindings,v 29.2 2000/06/07 14:02:25 chongo Exp $
|
||||
# @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/bindings,v $
|
||||
# 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
|
||||
|
254
cal/brentsolve.cal
Normal file
254
cal/brentsolve.cal
Normal file
@@ -0,0 +1,254 @@
|
||||
/*
|
||||
* brentsolve - Root finding with the Brent-Dekker trick
|
||||
*
|
||||
* Copyright (C) 2013,2021 Christoph Zurnieden
|
||||
*
|
||||
* 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: 2013/08/11 01:31:28
|
||||
* File existed as early as: 2013
|
||||
*/
|
||||
|
||||
|
||||
static resource_debug_level;
|
||||
resource_debug_level = config("resource_debug", 0);
|
||||
|
||||
|
||||
/*
|
||||
A short explanation is at http://en.wikipedia.org/wiki/Brent%27s_method
|
||||
I tried to follow the description at wikipedia as much as possible to make
|
||||
the slight changes I did more visible.
|
||||
You may give http://people.sc.fsu.edu/~jburkardt/cpp_src/brent/brent.html a
|
||||
short glimpse (Brent's originl Fortran77 versions and some translations of
|
||||
it).
|
||||
*/
|
||||
|
||||
static true = 1;
|
||||
static false = 0;
|
||||
define brentsolve(low, high,eps){
|
||||
local a b c d fa fb fc fa2 fb2 fc2 s fs tmp tmp2 mflag i places;
|
||||
a = low;
|
||||
b = high;
|
||||
c = 0;
|
||||
|
||||
if(isnull(eps))
|
||||
eps = epsilon(epsilon()*1e-3);
|
||||
places = highbit(1 + int( 1/epsilon() ) ) + 1;
|
||||
|
||||
d = 1/eps;
|
||||
|
||||
fa = f(a);
|
||||
fb = f(b);
|
||||
|
||||
fc = 0;
|
||||
s = 0;
|
||||
fs = 0;
|
||||
|
||||
if(fa * fb >= 0){
|
||||
if(fa < fb){
|
||||
epsilon(eps);
|
||||
return a;
|
||||
}
|
||||
else{
|
||||
epsilon(eps);
|
||||
return b;
|
||||
}
|
||||
}
|
||||
|
||||
if(abs(fa) < abs(fb)){
|
||||
tmp = a; a = b; b = tmp;
|
||||
tmp = fa; fa = fb; fb = tmp;
|
||||
}
|
||||
|
||||
c = a;
|
||||
fc = fa;
|
||||
mflag = 1;
|
||||
i = 0;
|
||||
|
||||
while(!(fb==0) && (abs(a-b) > eps)){
|
||||
if((fa != fc) && (fb != fc)){
|
||||
/* Inverse quadratic interpolation*/
|
||||
fc2 = fc^2;
|
||||
fa2 = fa^2;
|
||||
s = bround(((fb^2*((fc*a)-(c*fa)))+(fb*((c*fa2)-(fc2*a)))+(b*((fc2*fa)
|
||||
-(fc*fa2))))/((fc - fb)*(fa - fb)*(fc - fa)),places++);
|
||||
}
|
||||
else{
|
||||
/* Secant Rule*/
|
||||
s =bround( b - fb * (b - a) / (fb - fa),places++);
|
||||
}
|
||||
tmp2 = (3 * a + b) / 4;
|
||||
if( (!( ((s > tmp2) && (s < b))||((s < tmp2) && (s > b))))
|
||||
|| (mflag && (abs(s - b) >= (abs(b - c) / 2)))
|
||||
|| (!mflag && (abs(s - b) >= (abs(c - d) / 2)))) {
|
||||
s = (a + b) / 2;
|
||||
mflag = true;
|
||||
}
|
||||
else{
|
||||
if( (mflag && (abs(b - c) < eps))
|
||||
|| (!mflag && (abs(c - d) < eps))) {
|
||||
s = (a + b) / 2;
|
||||
mflag = true;
|
||||
}
|
||||
else
|
||||
mflag = false;
|
||||
}
|
||||
fs = f(s);
|
||||
c = b;
|
||||
fc = fb;
|
||||
if (fa * fs < 0){
|
||||
b = s;
|
||||
fb = fs;
|
||||
}
|
||||
else {
|
||||
a = s;
|
||||
fa = fs;
|
||||
}
|
||||
|
||||
if (abs(fa) < abs(fb)){
|
||||
tmp = a; a = b; b = tmp;
|
||||
tmp = fa; fa = fb; fb = tmp;
|
||||
}
|
||||
i++;
|
||||
if (i > 1000){
|
||||
epsilon(eps);
|
||||
return newerror("brentsolve: does not converge");
|
||||
}
|
||||
}
|
||||
epsilon(eps);
|
||||
return b;
|
||||
}
|
||||
|
||||
/*
|
||||
A variation of the solver to accept functions named differently from "f". The
|
||||
code should explain it.
|
||||
*/
|
||||
define brentsolve2(low, high,which,eps){
|
||||
local a b c d fa fb fc fa2 fb2 fc2 s fs tmp tmp2 mflag i places;
|
||||
a = low;
|
||||
b = high;
|
||||
c = 0;
|
||||
|
||||
switch(param(0)){
|
||||
case 0:
|
||||
case 1: return newerror("brentsolve2: not enough arguments");
|
||||
case 2: eps = epsilon(epsilon()*1e-2);
|
||||
which = 0;break;
|
||||
case 3: eps = epsilon(epsilon()*1e-2);break;
|
||||
default: break;
|
||||
};
|
||||
places = highbit(1 + int(1/epsilon())) + 1;
|
||||
|
||||
d = 1/eps;
|
||||
|
||||
switch(which){
|
||||
case 1: fa = __CZ__invbeta(a);
|
||||
fb = __CZ__invbeta(b); break;
|
||||
case 2: fa = __CZ__invincgamma(a);
|
||||
fb = __CZ__invincgamma(b); break;
|
||||
|
||||
default: fa = f(a);fb = f(b); break;
|
||||
};
|
||||
|
||||
fc = 0;
|
||||
s = 0;
|
||||
fs = 0;
|
||||
|
||||
if(fa * fb >= 0){
|
||||
if(fa < fb)
|
||||
return a;
|
||||
else
|
||||
return b;
|
||||
}
|
||||
|
||||
if(abs(fa) < abs(fb)){
|
||||
tmp = a; a = b; b = tmp;
|
||||
tmp = fa; fa = fb; fb = tmp;
|
||||
}
|
||||
|
||||
c = a;
|
||||
fc = fa;
|
||||
mflag = 1;
|
||||
i = 0;
|
||||
|
||||
while(!(fb==0) && (abs(a-b) > eps)){
|
||||
|
||||
if((fa != fc) && (fb != fc)){
|
||||
/* Inverse quadratic interpolation*/
|
||||
fc2 = fc^2;
|
||||
fa2 = fa^2;
|
||||
s = bround(((fb^2*((fc*a)-(c*fa)))+(fb*((c*fa2)-(fc2*a)))+(b*((fc2*fa)
|
||||
-(fc*fa2))))/((fc - fb)*(fa - fb)*(fc - fa)),places);
|
||||
places++;
|
||||
}
|
||||
else{
|
||||
/* Secant Rule*/
|
||||
s =bround( b - fb * (b - a) / (fb - fa),places);
|
||||
places++;
|
||||
}
|
||||
tmp2 = (3 * a + b) / 4;
|
||||
if( (!( ((s > tmp2) && (s < b))||((s < tmp2) && (s > b))))
|
||||
|| (mflag && (abs(s - b) >= (abs(b - c) / 2)))
|
||||
|| (!mflag && (abs(s - b) >= (abs(c - d) / 2)))) {
|
||||
s = (a + b) / 2;
|
||||
mflag = true;
|
||||
}
|
||||
else{
|
||||
if( (mflag && (abs(b - c) < eps))
|
||||
|| (!mflag && (abs(c - d) < eps))) {
|
||||
s = (a + b) / 2;
|
||||
mflag = true;
|
||||
}
|
||||
else
|
||||
mflag = false;
|
||||
}
|
||||
switch(which){
|
||||
case 1: fs = __CZ__invbeta(s); break;
|
||||
case 2: fs = __CZ__invincgamma(s); break;
|
||||
|
||||
default: fs = f(s); break;
|
||||
};
|
||||
c = b;
|
||||
fc = fb;
|
||||
if (fa * fs < 0){
|
||||
b = s;
|
||||
fb = fs;
|
||||
}
|
||||
else {
|
||||
a = s;
|
||||
fa = fs;
|
||||
}
|
||||
|
||||
if (abs(fa) < abs(fb)){
|
||||
tmp = a; a = b; b = tmp;
|
||||
tmp = fa; fa = fb; fb = tmp;
|
||||
}
|
||||
i++;
|
||||
if (i > 1000){
|
||||
return newerror("brentsolve2: does not converge");
|
||||
}
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* restore internal function from resource debugging
|
||||
*/
|
||||
config("resource_debug", resource_debug_level),;
|
||||
if (config("resource_debug") & 3) {
|
||||
print "brentsolve(low, high,eps)";
|
||||
print "brentsolve2(low, high,which,eps)";
|
||||
}
|
20
cal/chi.cal
20
cal/chi.cal
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* chi - chi^2 probabilities with degrees of freedom for null hypothesis
|
||||
*
|
||||
* Copyright (C) 2001 Landon Curt Noll
|
||||
* Copyright (C) 2001,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
|
||||
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: chi.cal,v 29.2 2001/04/08 10:21:23 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/chi.cal,v $
|
||||
* 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
|
||||
@@ -44,7 +40,7 @@ define Z(x, eps_term)
|
||||
|
||||
/* obtain the error term */
|
||||
if (isnull(eps_term)) {
|
||||
eps = epsilon();
|
||||
eps = epsilon();
|
||||
} else {
|
||||
eps = eps_term;
|
||||
}
|
||||
@@ -55,7 +51,7 @@ define Z(x, eps_term)
|
||||
|
||||
|
||||
/*
|
||||
* P(x[, eps]) asymtotic P(x) expansion for x>0 to an given epsilon error term
|
||||
* P(x[, eps]) asymptotic P(x) expansion for x>0 to an given epsilon error term
|
||||
*
|
||||
* NOTE: If eps is omitted, the stored epsilon value is used.
|
||||
*
|
||||
@@ -85,7 +81,7 @@ define P(x, eps_term)
|
||||
|
||||
/* obtain the error term */
|
||||
if (isnull(eps_term)) {
|
||||
eps = epsilon();
|
||||
eps = epsilon();
|
||||
} else {
|
||||
eps = eps_term;
|
||||
}
|
||||
@@ -103,7 +99,7 @@ define P(x, eps_term)
|
||||
}
|
||||
|
||||
/*
|
||||
* aproximate sum(n=0; n < infinity){x^(2*n+1)/(1*3*5*...(2*n+1)}
|
||||
* approximate sum(n=0; n < infinity){x^(2*n+1)/(1*3*5*...(2*n+1)}
|
||||
*/
|
||||
x2 = x*x;
|
||||
x_term = x;
|
||||
@@ -134,7 +130,7 @@ define P(x, eps_term)
|
||||
*
|
||||
* The chi_prob() function does not work well with odd degrees of freedom.
|
||||
* It is reasonable with even degrees of freedom, although one must give
|
||||
* a sifficently small error term as the degress gets large (>100).
|
||||
* 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
|
||||
@@ -190,7 +186,7 @@ define chi_prob(chi_sq, v, eps_term)
|
||||
local r; /* index in finite sum */
|
||||
local r_lim; /* limit value for r */
|
||||
local s; /* sum */
|
||||
local d; /* demoninator (2*4*6*... or 1*3*5...) */
|
||||
local d; /* denominator (2*4*6*... or 1*3*5...) */
|
||||
local chi_term; /* chi_sq^r */
|
||||
local ret; /* return value */
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* chrem - chinese remainder theorem/problem solver
|
||||
* chrem - Chinese remainder theorem/problem solver
|
||||
*
|
||||
* Copyright (C) 1999 Ernest Bowen and Landon Curt Noll
|
||||
* Copyright (C) 1999,2021 Ernest Bowen and Landon Curt Noll
|
||||
*
|
||||
* Primary author: Ernest Bowen
|
||||
*
|
||||
@@ -17,11 +17,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: chrem.cal,v 29.2 2000/06/07 14:02:25 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/chrem.cal,v $
|
||||
* 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
|
||||
@@ -30,7 +26,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* When possible, chrem finds solutions for x of a set of congruences
|
||||
* When possible, chrem finds solutions for x of a set of congruence
|
||||
* of the form:
|
||||
*
|
||||
* x = r1 (mod m1)
|
||||
@@ -39,7 +35,7 @@
|
||||
*
|
||||
* 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 congruences
|
||||
* m1, m2, ... are relatively prime in pairs, the above congruence
|
||||
* 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:
|
||||
|
100
cal/constants.cal
Normal file
100
cal/constants.cal
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* constants - implementation of different constants to arbitrary precision
|
||||
*
|
||||
* Copyright (C) 2013 Christoph Zurnieden
|
||||
*
|
||||
* 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: 2013/08/11 01:31:28
|
||||
* File existed as early as: 2013
|
||||
*/
|
||||
|
||||
|
||||
static resource_debug_level;
|
||||
resource_debug_level = config("resource_debug", 0);
|
||||
|
||||
|
||||
static __CZ__euler_mascheroni = 0;
|
||||
static __CZ__euler_mascheroni_prec = 0;
|
||||
|
||||
|
||||
define e(){
|
||||
local k temp1 temp2 ret eps factor upperlimit prec;
|
||||
|
||||
prec = digits(1/epsilon());
|
||||
if(__CZ__euler_mascheroni != 0 && __CZ__euler_mascheroni_prec >= prec)
|
||||
return __CZ__euler_mascheroni;
|
||||
if(prec<=20) return 2.718281828459045235360287471;
|
||||
if(prec<=1800){
|
||||
__CZ__euler_mascheroni = exp(1);
|
||||
__CZ__euler_mascheroni_prec = prec;
|
||||
}
|
||||
|
||||
eps=epsilon(1e-20);
|
||||
factor = 1;
|
||||
k = 0;
|
||||
upperlimit = prec * ln(10);
|
||||
while(k<upperlimit){
|
||||
k += ln(factor);
|
||||
factor++;
|
||||
}
|
||||
epsilon(eps);
|
||||
temp1 = 0;
|
||||
ret = 1;
|
||||
for(k=3;k<=factor;k++){
|
||||
temp2 = temp1;
|
||||
temp1 = ret;
|
||||
ret = (k-1) *(temp1 + temp2);
|
||||
}
|
||||
|
||||
ret = inverse( ret * inverse(factorial(factor) ) ) ;
|
||||
__CZ__euler_mascheroni = ret;
|
||||
__CZ__euler_mascheroni_prec = prec;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Lupas' series */
|
||||
static __CZ__catalan = 0;
|
||||
static __CZ__catalan_prec = 0;
|
||||
define G(){
|
||||
local eps a s t n;
|
||||
eps = epsilon(epsilon()*1e-10);
|
||||
if(__CZ__catalan != 0 && __CZ__catalan >= log(1/eps))
|
||||
return __CZ__catalan;
|
||||
a = 1;
|
||||
s = 0;
|
||||
t = 1;
|
||||
n = 1;
|
||||
while(abs(t)> eps){
|
||||
a *= 32 * n^3 * (2*n-1);
|
||||
a /=((3-16*n+16*n^2)^2);
|
||||
t = a * (-1)^(n-1) * (40*n^2-24*n+3) / (n^3 * (2*n-1));
|
||||
s += t;
|
||||
n += 1;
|
||||
}
|
||||
s = s/64;
|
||||
__CZ__catalan = s;
|
||||
__CZ__catalan_prec = log(1/eps);
|
||||
epsilon(eps);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
config("resource_debug", resource_debug_level),;
|
||||
if (config("resource_debug") & 3) {
|
||||
print "e()";
|
||||
print "G()";
|
||||
}
|
40
cal/deg.cal
40
cal/deg.cal
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.4 $
|
||||
* @(#) $Id: deg.cal,v 29.4 2003/01/26 19:32:41 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/deg.cal,v $
|
||||
* 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
|
||||
@@ -28,9 +24,9 @@
|
||||
*/
|
||||
|
||||
|
||||
obj dms {deg, min, sec};
|
||||
obj deg {deg, min, sec};
|
||||
|
||||
define dms(deg, min, sec)
|
||||
define deg(deg, min, sec)
|
||||
{
|
||||
local ans;
|
||||
|
||||
@@ -38,18 +34,18 @@ define dms(deg, min, sec)
|
||||
sec = 0;
|
||||
if (isnull(min))
|
||||
min = 0;
|
||||
obj dms ans;
|
||||
obj deg ans;
|
||||
ans.deg = deg;
|
||||
ans.min = min;
|
||||
ans.sec = sec;
|
||||
fixdms(ans);
|
||||
fixdeg(ans);
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
define dms_add(a, b)
|
||||
define deg_add(a, b)
|
||||
{
|
||||
local obj dms ans;
|
||||
local obj deg ans;
|
||||
|
||||
ans.deg = 0;
|
||||
ans.min = 0;
|
||||
@@ -66,14 +62,14 @@ define dms_add(a, b)
|
||||
ans.sec += b.sec;
|
||||
} else
|
||||
ans.deg += b;
|
||||
fixdms(ans);
|
||||
fixdeg(ans);
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
define dms_neg(a)
|
||||
define deg_neg(a)
|
||||
{
|
||||
local obj dms ans;
|
||||
local obj deg ans;
|
||||
|
||||
ans.deg = -a.deg;
|
||||
ans.min = -a.min;
|
||||
@@ -82,15 +78,15 @@ define dms_neg(a)
|
||||
}
|
||||
|
||||
|
||||
define dms_sub(a, b)
|
||||
define deg_sub(a, b)
|
||||
{
|
||||
return a - b;
|
||||
}
|
||||
|
||||
|
||||
define dms_mul(a, b)
|
||||
define deg_mul(a, b)
|
||||
{
|
||||
local obj dms ans;
|
||||
local obj deg ans;
|
||||
|
||||
if (istype(a, ans) && istype(b, ans))
|
||||
quit "Cannot multiply degrees together";
|
||||
@@ -103,24 +99,24 @@ define dms_mul(a, b)
|
||||
ans.min = b.min * a;
|
||||
ans.sec = b.sec * a;
|
||||
}
|
||||
fixdms(ans);
|
||||
fixdeg(ans);
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
define dms_print(a)
|
||||
define deg_print(a)
|
||||
{
|
||||
print a.deg : 'd' : a.min : 'm' : a.sec : 's' :;
|
||||
}
|
||||
|
||||
|
||||
define dms_abs(a)
|
||||
define deg_abs(a)
|
||||
{
|
||||
return a.deg + a.min / 60 + a.sec / 3600;
|
||||
}
|
||||
|
||||
|
||||
define fixdms(a)
|
||||
define fixdeg(a)
|
||||
{
|
||||
a.min += frac(a.deg) * 60;
|
||||
a.deg = int(a.deg);
|
||||
@@ -134,5 +130,5 @@ define fixdms(a)
|
||||
}
|
||||
|
||||
if (config("resource_debug") & 3) {
|
||||
print "obj dms {deg, min, sec} defined";
|
||||
print "obj deg {deg, min, sec} defined";
|
||||
}
|
||||
|
364
cal/dms.cal
Normal file
364
cal/dms.cal
Normal file
@@ -0,0 +1,364 @@
|
||||
/*
|
||||
* dms - calculate in degrees, minutes, and seconds (based on deg)
|
||||
*
|
||||
* Copyright (C) 1999,2010,2021 David I. Bell and Landon Curt Noll
|
||||
*
|
||||
* Calc is open software; you can redistribute it and/or modify it under
|
||||
* the terms of the version 2.1 of the GNU Lesser General Public License
|
||||
* 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: 1990/02/15 01:50:33
|
||||
* File existed as early as: before 1990
|
||||
*
|
||||
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
|
||||
*/
|
||||
|
||||
|
||||
obj dms {deg, min, sec};
|
||||
|
||||
define dms(deg, min, sec)
|
||||
{
|
||||
local obj dms ans; /* return value */
|
||||
|
||||
/* default missing args to 0 */
|
||||
if (isnull(sec)) {
|
||||
sec = 0;
|
||||
}
|
||||
if (isnull(min)) {
|
||||
min = 0;
|
||||
}
|
||||
|
||||
/* load object */
|
||||
ans.deg = deg;
|
||||
ans.min = min;
|
||||
ans.sec = sec;
|
||||
|
||||
/* return properly formed object */
|
||||
ans = fixdms(ans);
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
define dms_add(a, b)
|
||||
{
|
||||
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;
|
||||
} else {
|
||||
/* 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;
|
||||
} else {
|
||||
/* 2nd arg is not dms, add scalar degrees */
|
||||
ans.deg += b;
|
||||
}
|
||||
|
||||
/* return normalized result */
|
||||
ans = fixdms(ans);
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
define dms_neg(a)
|
||||
{
|
||||
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;
|
||||
} else {
|
||||
/* 2nd arg is not dms, negate scalar degrees */
|
||||
ans.deg = -a;
|
||||
ans.min = 0;
|
||||
ans.sec = 0;
|
||||
}
|
||||
|
||||
/* return normalized result */
|
||||
ans = fixdms(ans);
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
define dms_sub(a, b)
|
||||
{
|
||||
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;
|
||||
} else {
|
||||
/* 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;
|
||||
} else {
|
||||
/* 2nd arg is not dms, subtract scalar degrees */
|
||||
ans.deg -= b;
|
||||
}
|
||||
|
||||
/* return normalized result */
|
||||
ans = fixdms(ans);
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
define dms_mul(a, b)
|
||||
{
|
||||
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;
|
||||
|
||||
/* scalar multiplication */
|
||||
} else 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;
|
||||
}
|
||||
|
||||
/* return normalized result */
|
||||
ans = fixdms(ans);
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
define dms_print(a)
|
||||
{
|
||||
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";
|
||||
}
|
||||
|
||||
/* print in dms form */
|
||||
print a.deg : 'd' : a.min : 'm' : a.sec : 's' :;
|
||||
}
|
||||
|
||||
|
||||
define dms_abs(a)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/* compute degrees */
|
||||
deg = a.deg + a.min / 60 + a.sec / 3600;
|
||||
|
||||
/* return degrees */
|
||||
return deg;
|
||||
}
|
||||
|
||||
|
||||
define dms_norm(a)
|
||||
{
|
||||
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";
|
||||
}
|
||||
|
||||
/* square degrees (norm is the square of absolute value */
|
||||
deg = dms_abs(a);
|
||||
|
||||
/* return degrees */
|
||||
return deg*deg;
|
||||
}
|
||||
|
||||
|
||||
define dms_test(a)
|
||||
{
|
||||
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";
|
||||
}
|
||||
|
||||
/* return false of non-zero */
|
||||
ans = fixdms(a);
|
||||
if (ans.deg == 0 && ans.min == 0 && ans.sec == 0) {
|
||||
/* false */
|
||||
return 0;
|
||||
}
|
||||
/* true */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
define dms_int(a)
|
||||
{
|
||||
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";
|
||||
}
|
||||
|
||||
/* normalize the argument */
|
||||
ans = fixdms(a);
|
||||
|
||||
/* truncate to the nearest second */
|
||||
ans.sec = int(ans.sec);
|
||||
|
||||
/* return value to the nearest second */
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
define dms_frac(a)
|
||||
{
|
||||
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";
|
||||
}
|
||||
|
||||
/* normalize the argument */
|
||||
ans = fixdms(a);
|
||||
|
||||
/* remove all but fractional seconds */
|
||||
ans.deg = 0;
|
||||
ans.min = 0;
|
||||
ans.sec = frac(ans.sec);
|
||||
|
||||
/* return value to the second fraction */
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
define dms_rel(a,b)
|
||||
{
|
||||
local abs_a, abs_b; /* scalars of the arguments */
|
||||
|
||||
/* compute scalars of the arguments */
|
||||
abs_a = dms_abs(a);
|
||||
abs_b = dms_abs(b);
|
||||
|
||||
/* return the comparison */
|
||||
return cmp(abs_a, abs_b);
|
||||
}
|
||||
|
||||
|
||||
define dms_cmp(a,b)
|
||||
{
|
||||
local abs_a, abs_b; /* scalars of the arguments */
|
||||
|
||||
/* compute scalars of the arguments */
|
||||
abs_a = dms_abs(a);
|
||||
abs_b = dms_abs(b);
|
||||
|
||||
/* return the equality comparison */
|
||||
return (abs_a == abs_b);
|
||||
}
|
||||
|
||||
|
||||
define dms_inc(a)
|
||||
{
|
||||
local obj dms ans; /* return value */
|
||||
|
||||
/* increment a dms object */
|
||||
if (istype(a, ans)) {
|
||||
ans = a;
|
||||
++ans.sec;
|
||||
|
||||
/* return normalized result */
|
||||
ans = fixdms(ans);
|
||||
return ans;
|
||||
}
|
||||
|
||||
/* increment a scalar */
|
||||
return a+1;
|
||||
}
|
||||
|
||||
|
||||
define dms_dec(a)
|
||||
{
|
||||
local obj dms ans; /* return value */
|
||||
|
||||
/* decrement a dms object */
|
||||
if (istype(a, ans)) {
|
||||
ans = a;
|
||||
--ans.sec;
|
||||
|
||||
/* return normalized result */
|
||||
ans = fixdms(ans);
|
||||
return ans;
|
||||
}
|
||||
|
||||
/* decrement a scalar */
|
||||
return a-1;
|
||||
}
|
||||
|
||||
|
||||
define fixdms(a)
|
||||
{
|
||||
local obj dms ans; /* temp value */
|
||||
|
||||
/* firewall */
|
||||
if (! istype(a, ans)) {
|
||||
quit "attempt to fix a non dms object";
|
||||
}
|
||||
|
||||
/* use builtin d2dms function */
|
||||
d2dms(a.deg + a.min/60 + a.sec/3600, a.deg, a.min, a.sec),;
|
||||
|
||||
/* return normalized result */
|
||||
return a;
|
||||
}
|
||||
|
||||
if (config("resource_debug") & 3) {
|
||||
print "obj dms {deg, min, sec} defined";
|
||||
}
|
@@ -8,18 +8,14 @@
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: dotest.cal,v 29.2 2006/05/21 00:55:27 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/dotest.cal,v $
|
||||
*
|
||||
* This file is not covered under version 2.1 of the GNU LGPL.
|
||||
*
|
||||
* Under source dotest_code control: 2006/03/08 05:54:09
|
||||
@@ -161,7 +157,7 @@ define dotest(dotest_file, dotest_code = 0, dotest_maxcond = -1)
|
||||
* test the close of the line file
|
||||
*/
|
||||
printf("%d-: detected %d error condition(s), many of which may be OK\n",
|
||||
dotest_code, dotest_old_errcount-dotest_errcnt);
|
||||
dotest_code, dotest_old_errcount-dotest_errcnt);
|
||||
printf("%d-: closing line file: %d\n", dotest_code, dotest_file);
|
||||
fclose(dotest_f_file);
|
||||
|
||||
@@ -177,7 +173,7 @@ define dotest(dotest_file, dotest_code = 0, dotest_maxcond = -1)
|
||||
}
|
||||
|
||||
/*
|
||||
* preppare to return to the caller environment
|
||||
* prepare to return to the caller environment
|
||||
*
|
||||
* We increase the caller's error count by the number
|
||||
* of line tests that failed, not the number of internal
|
||||
|
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.4 $
|
||||
* @(#) $Id: ellip.cal,v 29.4 2006/06/20 09:29:16 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/ellip.cal,v $
|
||||
* 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
|
||||
|
200
cal/factorial.cal
Normal file
200
cal/factorial.cal
Normal file
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* factorial - implementation of different algorithms for the factorial
|
||||
*
|
||||
* Copyright (C) 2013 Christoph Zurnieden
|
||||
*
|
||||
* 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: 2013/08/11 01:31:28
|
||||
* File existed as early as: 2013
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* hide internal function from resource debugging
|
||||
*/
|
||||
static resource_debug_level;
|
||||
resource_debug_level = config("resource_debug", 0);
|
||||
|
||||
|
||||
/*
|
||||
get dependencies
|
||||
*/
|
||||
read -once toomcook;
|
||||
|
||||
|
||||
/* A simple list to keep things...uhm...simple?*/
|
||||
static __CZ__primelist = list();
|
||||
|
||||
/* Helper for primorial: fill list with primes in range a,b */
|
||||
define __CZ__fill_prime_list(a,b)
|
||||
{
|
||||
local k;
|
||||
k=a;
|
||||
if(isprime(k))k--;
|
||||
while(1){
|
||||
k = nextprime(k);
|
||||
if(k > b) break;
|
||||
append(__CZ__primelist,k );
|
||||
}
|
||||
}
|
||||
|
||||
/* Helper for factorial: how often prime p divides the factorial of n */
|
||||
define __CZ__prime_divisors(n,p)
|
||||
{
|
||||
local q,m;
|
||||
q = n;
|
||||
m = 0;
|
||||
if (p > n) return 0;
|
||||
if (p > n/2) return 1;
|
||||
while (q >= p) {
|
||||
q = q//p;
|
||||
m += q;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
/*
|
||||
Wrapper. Please set cut-offs to own taste and hardware.
|
||||
*/
|
||||
define factorial(n){
|
||||
local prime result shift prime_list k k1 k2 expo_list pix cut primorial;
|
||||
|
||||
result = 1;
|
||||
prime = 2;
|
||||
|
||||
if(!isint(n)) {
|
||||
return newerror("factorial(n): n is not an integer"); ## or gamma(n)?
|
||||
}
|
||||
if(n < 0) return newerror("factorial(n): n < 0");
|
||||
if(n < 9000 && !isdefined("test8900")) {
|
||||
## builtin is implemented with splitting but only with
|
||||
## Toom-Cook 2 (by Karatsuba (the father))
|
||||
return n!;
|
||||
}
|
||||
|
||||
shift = __CZ__prime_divisors(n,prime);
|
||||
prime = 3;
|
||||
cut = n//2;
|
||||
pix = pix(cut);
|
||||
prime_list = mat[pix];
|
||||
expo_list = mat[pix];
|
||||
|
||||
k = 0;
|
||||
/*
|
||||
Peter Borwein's algorithm
|
||||
|
||||
@Article{journals/jal/Borwein85,
|
||||
author = {Borwein, Peter B.},
|
||||
title = {On the Complexity of Calculating Factorials.},
|
||||
journal = {J. Algorithms},
|
||||
year = {1985},
|
||||
number = {3},
|
||||
url = {http://dblp.uni-trier.de/db/journals/jal/jal6.html#Borwein85}
|
||||
*/
|
||||
|
||||
do {
|
||||
prime_list[k] = prime;
|
||||
expo_list[k++] = __CZ__prime_divisors(n,prime);
|
||||
prime = nextprime(prime);
|
||||
}while(prime <= cut);
|
||||
|
||||
/* size of the largest exponent in bits */
|
||||
k1 = highbit(expo_list[0]);
|
||||
k2 = size(prime_list)-1;
|
||||
|
||||
for(;k1>=0;k1--){
|
||||
/*
|
||||
the cut-off for T-C-4 ist still to low, using T-C-3 here
|
||||
TODO: check cutoffs
|
||||
*/
|
||||
result = toomcook3square(result);
|
||||
/*
|
||||
almost all time is spend in this loop, so cutting of the
|
||||
upper half of the primes makes sense
|
||||
*/
|
||||
for(k=0; k<=k2; k++) {
|
||||
if((expo_list[k] & (1 << k1)) != 0) {
|
||||
result *= prime_list[k];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
primorial = primorial( cut, n);
|
||||
result *= primorial;
|
||||
result <<= shift;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
Helper for primorial: do the product with binary splitting
|
||||
TODO: do it without the intermediate list
|
||||
*/
|
||||
define __CZ__primorial__lowlevel( a, b ,p)
|
||||
{
|
||||
local c;
|
||||
if( b == a) return p ;
|
||||
if( b-a > 1){
|
||||
c= (b + a) >> 1;
|
||||
return __CZ__primorial__lowlevel( a , c , __CZ__primelist[a] )
|
||||
* __CZ__primorial__lowlevel( c+1 , b , __CZ__primelist[b] ) ;
|
||||
}
|
||||
return __CZ__primelist[a] * __CZ__primelist[b];
|
||||
}
|
||||
|
||||
/*
|
||||
Primorial, Product of consecutive primes in range a,b
|
||||
|
||||
Originally meant to do primorials with a start different from 2, but
|
||||
found out that this is faster at about a=1,b>=10^5 than the builtin
|
||||
function pfact(). With the moderately small list a=1,b=10^6 (78498
|
||||
primes) it is 3 times faster. A quick look-up showed what was already
|
||||
guessed: pfact() does it linearly. (BTW: what is the time complexity
|
||||
of the primorial with the naive algorithm?)
|
||||
*/
|
||||
define primorial(a,b)
|
||||
{
|
||||
local C1 C2;
|
||||
if(!isint(a)) return newerror("primorial(a,b): a is not an integer");
|
||||
else if(!isint(b)) return newerror("primorial(a,b): b is not an integer");
|
||||
else if(a < 0) return newerror("primorial(a,b): a < 0");
|
||||
else if( b < 2 ) return newerror("primorial(a,b): b < 2");
|
||||
else if( b < a) return newerror("primorial(a,b): b < a");
|
||||
else{
|
||||
/* last prime < 2^32 is also max. prime for nextprime()*/
|
||||
if(b >= 4294967291) return newerror("primorial(a,b): max. prime exceeded");
|
||||
if(b == 2) return 2;
|
||||
/*
|
||||
Can be extended by way of pfact(b)/pfact(floor(a-1/2)) for small a
|
||||
*/
|
||||
if(a<=2 && b < 10^5) return pfact(b);
|
||||
/* TODO: use pix() and a simple array (mat[])instead*/
|
||||
__CZ__primelist = list();
|
||||
__CZ__fill_prime_list(a,b);
|
||||
C1 = size(__CZ__primelist)-1;
|
||||
return __CZ__primorial__lowlevel( 0, C1,1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* restore internal function from resource debugging
|
||||
* report important interface functions
|
||||
*/
|
||||
config("resource_debug", resource_debug_level),;
|
||||
if (config("resource_debug") & 3) {
|
||||
print "factorial(n)";
|
||||
print "primorial(a, b)";
|
||||
}
|
719
cal/factorial2.cal
Normal file
719
cal/factorial2.cal
Normal file
@@ -0,0 +1,719 @@
|
||||
/*
|
||||
* factorial2 - implementation of different factorial related functions
|
||||
*
|
||||
* Copyright (C) 2013,2021 Christoph Zurnieden
|
||||
*
|
||||
* 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: 2013/08/11 01:31:28
|
||||
* File existed as early as: 2013
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* hide internal function from resource debugging
|
||||
*/
|
||||
static resource_debug_level;
|
||||
resource_debug_level = config("resource_debug", 0);
|
||||
|
||||
|
||||
/*
|
||||
get dependencies
|
||||
*/
|
||||
read -once factorial toomcook specialfunctions;
|
||||
|
||||
|
||||
/*
|
||||
Factorize a factorial and put the result in a 2-column matrix with pi(n) rows
|
||||
mat[ primes , exponent ]
|
||||
Result can be restricted to start at a prime different from 2 with the second
|
||||
argument "start". That arguments gets taken at face value if it prime and
|
||||
smaller than n, otherwise the next larger prime is taken if that prime is
|
||||
smaller than n.
|
||||
*/
|
||||
|
||||
define __CZ__factor_factorial(n,start){
|
||||
local prime prime_list k pix stop;
|
||||
|
||||
|
||||
if(!isint(n)) return
|
||||
newerror("__CZ__factor_factorial(n,start): n is not integer");
|
||||
if(n < 0) return newerror("__CZ__factor_factorial(n,start): n < 0");
|
||||
if(n == 1) return newerror("__CZ__factor_factorial(n,start): n == 1");
|
||||
|
||||
if(start){
|
||||
if(!isint(start) && start < 0 && start > n)
|
||||
return newerror("__CZ__factor_factorial(n,start): value of "
|
||||
"parameter 'start' out of range");
|
||||
if(start == n && isprime(n)){
|
||||
prime_list = mat[1 , 2];
|
||||
prime_list[0,0] = n;
|
||||
prime_list[0,1] = 1;
|
||||
}
|
||||
else if(!isprime(start) && nextprime(start) >n)
|
||||
return newerror("__CZ__factor_factorial(n,start): value of parameter "
|
||||
"'start' out of range");
|
||||
else{
|
||||
if(!isprime(start)) prime = nextprime(start);
|
||||
else prime = start;
|
||||
}
|
||||
}
|
||||
else
|
||||
prime = 2;
|
||||
|
||||
pix = pix(n);
|
||||
if(start){
|
||||
pix -= pix(prime) -1;
|
||||
}
|
||||
prime_list = mat[pix , 2];
|
||||
|
||||
k = 0;
|
||||
|
||||
do {
|
||||
prime_list[k ,0] = prime;
|
||||
prime_list[k++,1] = __CZ__prime_divisors(n,prime);
|
||||
prime = nextprime(prime);
|
||||
}while(prime <= n);
|
||||
|
||||
return prime_list;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
subtracts exponents of n_1! from exponents of n_2! with n_1<=n_2
|
||||
|
||||
Does not check for size or consecutiveness of the primes or a carry
|
||||
*/
|
||||
|
||||
define __CZ__subtract_factored_factorials(matrix_2n,matrix_n){
|
||||
local k ret len1,len2,tmp count p e;
|
||||
len1 = size(matrix_n)/2;
|
||||
len2 = size(matrix_2n)/2;
|
||||
if(len2<len1){
|
||||
|
||||
swap(len1,len2);
|
||||
tmp = matrix_n;
|
||||
matrix_n = matrix_2n;
|
||||
matrix_2n = tmp;
|
||||
}
|
||||
tmp = mat[len1,2];
|
||||
k = 0;
|
||||
|
||||
for(;k<len1;k++){
|
||||
p = matrix_2n[k,0];
|
||||
e = matrix_2n[k,1] - matrix_n[k,1];
|
||||
if(e!=0){
|
||||
tmp[count ,0] = p;
|
||||
tmp[count++,1] = e;
|
||||
}
|
||||
}
|
||||
ret = mat[count + (len2-len1),2];
|
||||
for(k=0;k<count;k++){
|
||||
ret[k,0] = tmp[k,0];
|
||||
ret[k,1] = tmp[k,1];
|
||||
}
|
||||
|
||||
free(tmp);
|
||||
for(k=len1;k<len2;k++){
|
||||
ret[count,0] = matrix_2n[k,0];
|
||||
ret[count++,1] = matrix_2n[k,1];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
adds exponents of n_1! to exponents of n_2! with n_1<=n_2
|
||||
|
||||
Does not check for size or consecutiveness of the primes or a carry
|
||||
*/
|
||||
|
||||
define __CZ__add_factored_factorials(matrix_2n,matrix_n){
|
||||
local k ret len1,len2,tmp;
|
||||
len1 = size(matrix_n)/2;
|
||||
len2 = size(matrix_2n)/2;
|
||||
if(len2<len1){
|
||||
swap(len1,len2);
|
||||
tmp = matrix_n;
|
||||
matrix_n = matrix_2n;
|
||||
matrix_2n = tmp;
|
||||
}
|
||||
ret = mat[len2,2];
|
||||
k = 0;
|
||||
for(;k<len1;k++){
|
||||
ret[k,0] = matrix_2n[k,0];
|
||||
ret[k,1] = matrix_2n[k,1] + matrix_n[k,1];
|
||||
}
|
||||
for(;k<len2;k++){
|
||||
ret[k,0] = matrix_2n[k,0];
|
||||
ret[k,1] = matrix_2n[k,1];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
Does not check if all exponents are positive
|
||||
|
||||
|
||||
timings
|
||||
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
|
||||
; 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
|
||||
; 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
|
||||
; 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
|
||||
; benchmark_binomial(15,25)
|
||||
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
|
||||
*/
|
||||
|
||||
define benchmark_binomial(s,limit){
|
||||
local ret k A B T1 T2 start end N K;
|
||||
N = 2^(limit);
|
||||
for(k=s;k<limit;k++){
|
||||
K = 2^k;
|
||||
start=usertime();A=binomial(N,K);end=usertime();
|
||||
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;
|
||||
if(A!=B){
|
||||
print "false";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define __CZ__multiply_factored_factorial(matrix,stop){
|
||||
local prime result shift prime_list k k1 k2 expo_list pix count start;
|
||||
local hb flag;
|
||||
|
||||
result = 1;
|
||||
shift = 0;
|
||||
|
||||
|
||||
if(!ismat(matrix))
|
||||
return newerror("__CZ__multiply_factored_factorial(matrix): "
|
||||
"argument matrix not a matrix ");
|
||||
if(!matrix[0,0])
|
||||
return
|
||||
newerror("__CZ__multiply_factored_factorial(matrix): "
|
||||
"matrix[0,0] is null/0");
|
||||
|
||||
if(!isnull(stop))
|
||||
pix = stop;
|
||||
else
|
||||
pix = size(matrix)/2-1;
|
||||
|
||||
if(matrix[0,0] == 2 && matrix[0,1] > 0){
|
||||
shift = matrix[0,1];
|
||||
if(pix-1 == 0)
|
||||
return 2^matrix[0,1];
|
||||
}
|
||||
|
||||
/*
|
||||
This is a more general way to do the multiplication, so any optimization
|
||||
must have been done by the caller.
|
||||
*/
|
||||
k = 0;
|
||||
/*
|
||||
The size of the largest exponent in bits is calculated dynamically.
|
||||
Can be done more elegantly and saves one run over the whole array if done
|
||||
inside the main loop.
|
||||
*/
|
||||
hb =0;
|
||||
for(k=0;k<pix;k++){
|
||||
k1=highbit(matrix[k,1]);
|
||||
if(hb < k1)hb=k1;
|
||||
}
|
||||
|
||||
k2 = pix;
|
||||
start = 0;
|
||||
if(shift) start++;
|
||||
|
||||
for(k1=hb;k1>=0;k1--){
|
||||
/*
|
||||
the cut-off for T-C-4 ist still too low, using T-C-3 here
|
||||
TODO: check cutoffs
|
||||
*/
|
||||
result = toomcook3square(result);
|
||||
|
||||
for(k=start; k<=k2; k++) {
|
||||
if((matrix[k,1] & (1 << k1)) != 0) {
|
||||
result *= matrix[k,0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result <<= shift;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
Compute binomial coefficients n!/(k!(n-k)!)
|
||||
|
||||
One of the rare cases where a formula once meant to ease manual computation
|
||||
is actually the (asymptotically) fastest way to do it (in July 2013) for
|
||||
the extreme case binomial(2N,N) but for a high price, the memory
|
||||
needed is pi(N)--theoretically.
|
||||
*/
|
||||
define binomial(n,k){
|
||||
local ret factored_n factored_k factored_nk denom num quot K prime_list prime;
|
||||
local pix diff;
|
||||
|
||||
if(!isint(n) || !isint(k))
|
||||
return newerror("binomial(n,k): input is not integer");
|
||||
if(n<0 || k<0)
|
||||
return newerror("binomial(n,k): input is not >= 0"); ;
|
||||
if(n<k ) return 0;
|
||||
if(n==k) return 1;
|
||||
if(k==0) return 1;
|
||||
if(k==1) return n;
|
||||
if(n-k==1) return n;
|
||||
/*
|
||||
cut-off depends on real size of n,k and size of n/k
|
||||
The current cut-off is to small for large n, e.g.:
|
||||
for 2n=2^23, k=n-n/2 the quotient is q=2n/k=0.25. Empirical tests showed
|
||||
that 2n=2^23 and k=2^16 with q=0.0078125 are still faster than the
|
||||
builtin function.
|
||||
|
||||
The symmetry (n,k) = (n,n-k) is of not much advantage here. One way
|
||||
might be to get closer to k=n/2 if k<n-k but only if the difference
|
||||
is small and n very large.
|
||||
*/
|
||||
if(n<2e4 && !isdefined("test8900")) return comb(n,k);
|
||||
if(n<2e4 && k< n-n/2 && !isdefined("test8900")) return comb(n,k);
|
||||
/*
|
||||
This should be done in parallel to save some memory, e.g. no temporary
|
||||
arrays are needed, all can be done inline.
|
||||
The theoretical memory needed is pi(k).
|
||||
Which is still a lot.
|
||||
*/
|
||||
|
||||
prime = 2;
|
||||
pix = pix(n);
|
||||
prime_list = mat[pix , 2];
|
||||
K = 0;
|
||||
do {
|
||||
prime_list[K ,0] = prime;
|
||||
diff = __CZ__prime_divisors(n,prime)-
|
||||
( __CZ__prime_divisors(n-k,prime)+__CZ__prime_divisors(k,prime));
|
||||
if(diff != 0)
|
||||
prime_list[K++,1] = diff;
|
||||
prime = nextprime(prime);
|
||||
}while(prime <= k);
|
||||
|
||||
do {
|
||||
prime_list[K ,0] = prime;
|
||||
diff = __CZ__prime_divisors(n,prime)-__CZ__prime_divisors(n-k,prime);
|
||||
if(diff != 0)
|
||||
prime_list[K++,1] = diff;
|
||||
prime = nextprime(prime);
|
||||
}while(prime <= n-k);
|
||||
|
||||
do {
|
||||
prime_list[K ,0] = prime;
|
||||
prime_list[K++,1] = __CZ__prime_divisors(n,prime);
|
||||
prime = nextprime(prime);
|
||||
}while(prime <= n);
|
||||
##print K,pix(k),pix(n-k),pix(n);
|
||||
##factored_k = __CZ__factor_factorial(k,1);
|
||||
##factored_nk = __CZ__factor_factorial(n-k,1);
|
||||
|
||||
##denom = __CZ__add_factored_factorials(factored_k,factored_nk);
|
||||
##free(factored_k,factored_nk);
|
||||
##num = __CZ__factor_factorial(n,1);
|
||||
##quot = __CZ__subtract_factored_factorials( num , denom );
|
||||
##free(num,denom);
|
||||
|
||||
ret = __CZ__multiply_factored_factorial(`prime_list,K-1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
Compute large catalan numbers C(n) = binomial(2n,n)/(n+1) with
|
||||
cut-off: (n>5e4)
|
||||
Needs a lot of memory.
|
||||
*/
|
||||
define bigcatalan(n){
|
||||
if(!isint(n) )return newerror("bigcatalan(n): n is not integer");
|
||||
if( n<0) return newerror("bigcatalan(n): n < 0");
|
||||
if( n<5e4 && !isdefined("test8900") ) return catalan(n);
|
||||
return binomial(2*n,n)/(n+1);
|
||||
}
|
||||
|
||||
/*
|
||||
df(-111) = -1/3472059605858239446587523014902616804783337112829102414124928
|
||||
7753332469144201839599609375
|
||||
|
||||
df(-3+1i) = 0.12532538977287649201-0.0502372106177184607i
|
||||
df(2n + 1) = (2*n)!/(n!*2^n)
|
||||
*/
|
||||
define __CZ__double_factorial(n){
|
||||
local n1 n2 diff prime pix K prime_list k;
|
||||
prime = 3;
|
||||
pix = pix(2*n)+1;
|
||||
prime_list = mat[pix , 2];
|
||||
K = 0;
|
||||
do {
|
||||
prime_list[K ,0] = prime;
|
||||
diff = __CZ__prime_divisors(2*n,prime)-( __CZ__prime_divisors(n,prime));
|
||||
if(diff != 0)
|
||||
prime_list[K++,1] = diff;
|
||||
prime = nextprime(prime);
|
||||
}while(prime <= n);
|
||||
do {
|
||||
prime_list[K ,0] = prime;
|
||||
prime_list[K++,1] = __CZ__prime_divisors(2*n,prime);
|
||||
prime = nextprime(prime);
|
||||
}while(prime <= 2*n);
|
||||
return __CZ__multiply_factored_factorial(prime_list,K);
|
||||
/*
|
||||
n1=__CZ__factor_factorial(2*n,1);
|
||||
n1[0,1] = n1[0,1]-n;
|
||||
n2=__CZ__factor_factorial(n,1);
|
||||
diff=__CZ__subtract_factored_factorials( n1 , n2 );
|
||||
return __CZ__multiply_factored_factorial(diff);
|
||||
*/
|
||||
}
|
||||
|
||||
##1, 1, 3, 15, 105, 945, 10395, 135135, 2027025, 34459425, 654729075,
|
||||
##13749310575, 316234143225, 7905853580625, 213458046676875,
|
||||
##6190283353629375, 191898783962510625, 6332659870762850625,
|
||||
##221643095476699771875, 8200794532637891559375
|
||||
|
||||
## 1, 2, 8, 48, 384, 3840, 46080, 645120, 10321920, 185794560,
|
||||
##3715891200, 81749606400, 1961990553600, 51011754393600,
|
||||
##1428329123020800, 42849873690624000, 1371195958099968000,
|
||||
##46620662575398912000, 1678343852714360832000, 63777066403145711616000
|
||||
define doublefactorial(n){
|
||||
local n1 n2 diff eps ret;
|
||||
if(!isint(n) ){
|
||||
/*
|
||||
Probably one of the not-so-good ideas. See result of
|
||||
http://www.wolframalpha.com/input/?i=doublefactorial%28a%2Bbi%29
|
||||
*/
|
||||
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);
|
||||
epsilon(eps);
|
||||
return ret;
|
||||
}
|
||||
if(n==2) return 2;
|
||||
if(n==3) return 3;
|
||||
switch(n){
|
||||
case -1:
|
||||
case 0 : return 1;break;
|
||||
case 2 : return 2;break;
|
||||
case 3 : return 3;break;
|
||||
case 4 : return 8;break;
|
||||
default: break;
|
||||
}
|
||||
if(isodd(n)){
|
||||
/*
|
||||
TODO: find reasonable cutoff
|
||||
df(2n + 1) = (2*n)!/(n!*2^n)
|
||||
*/
|
||||
if(n>0){
|
||||
n = (n+1)//2;
|
||||
return __CZ__double_factorial(n);
|
||||
}
|
||||
else{
|
||||
if(n == -3 ) return -1;
|
||||
n = ((-n)-1)/2;
|
||||
return ((-1)^-n)/__CZ__double_factorial(n);
|
||||
}
|
||||
}
|
||||
else{
|
||||
/*
|
||||
I'm undecided here. The formula for complex n is valid for the negative
|
||||
integers, too.
|
||||
*/
|
||||
n = n>>1;
|
||||
if(n>0){
|
||||
if(!isdefined("test8900"))
|
||||
return factorial(n)<<n;
|
||||
else
|
||||
return n!<<n;
|
||||
}
|
||||
else
|
||||
return newerror("doublefactorial(n): even(n) < 0");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Algorithm 3.17,
|
||||
Donald Kreher and Douglas Simpson,
|
||||
Combinatorial Algorithms,
|
||||
CRC Press, 1998, page 89.
|
||||
*/
|
||||
static __CZ__stirling1;
|
||||
static __CZ__stirling1_n = -1;
|
||||
static __CZ__stirling1_m = -1;
|
||||
|
||||
define stirling1(n,m){
|
||||
local i j k;
|
||||
if(n<0)return newerror("stirling1(n,m): n <= 0");
|
||||
if(m<0)return newerror("stirling1(n,m): m < 0");
|
||||
if(n<m) return 0;
|
||||
if(n==m) return 1;
|
||||
if(m==0 || n==0) return 0;
|
||||
/* We always use the list */
|
||||
/*
|
||||
if(m=1){
|
||||
if(iseven(n)) return -factorial(n-1);
|
||||
else return factorial(n-1);
|
||||
}
|
||||
if(m == n-1){
|
||||
if(iseven(n)) return -binomial(n,2);
|
||||
else return -binomial(n,2);
|
||||
}
|
||||
*/
|
||||
if(__CZ__stirling1_n >= n && __CZ__stirling1_m >= m){
|
||||
return __CZ__stirling1[n,m];
|
||||
}
|
||||
else{
|
||||
__CZ__stirling1 = mat[n+1,m+1];
|
||||
__CZ__stirling1[0,0] = 1;
|
||||
for(i=1;i<=n;i++)
|
||||
__CZ__stirling1[i,0] = 0;
|
||||
for(i=1;i<=n;i++){
|
||||
for(j=1;j<=m;j++){
|
||||
if(j<=i){
|
||||
__CZ__stirling1[i, j] = __CZ__stirling1[i - 1, j - 1] - (i - 1)\
|
||||
* __CZ__stirling1[i - 1, j];
|
||||
}
|
||||
else{
|
||||
__CZ__stirling1[i, j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
__CZ__stirling1_n = n;
|
||||
__CZ__stirling1_m = m;
|
||||
return __CZ__stirling1[n,m];
|
||||
}
|
||||
}
|
||||
|
||||
define stirling2(n,m){
|
||||
local k sum;
|
||||
if(n<0)return newerror("stirling2(n,m): n < 0");
|
||||
if(m<0)return newerror("stirling2(n,m): m < 0");
|
||||
if(n<m) return 0;
|
||||
if(n==0 && n!=m) return 0;
|
||||
if(n==m) return 1;
|
||||
if(m==0 )return 0;
|
||||
if(m==1) return 1;
|
||||
if(m==2) return 2^(n-1)-1;
|
||||
/*
|
||||
There are different methods to speed up alternating sums.
|
||||
This one doesn't.
|
||||
*/
|
||||
if(isdefined("test8900")){
|
||||
for(k=0;k<=m;k++){
|
||||
sum += (-1)^(m-k)*comb(m,k)*k^n;
|
||||
}
|
||||
return sum/(m!);
|
||||
}
|
||||
else{
|
||||
for(k=0;k<=m;k++){
|
||||
sum += (-1)^(m-k)*binomial(m,k)*k^n;
|
||||
}
|
||||
return sum/factorial(m);
|
||||
}
|
||||
}
|
||||
|
||||
static __CZ__stirling2;
|
||||
static __CZ__stirling2_n = -1;
|
||||
static __CZ__stirling2_m = -1;
|
||||
define stirling2caching(n,m){
|
||||
local nm i j ;
|
||||
if(n<0)return newerror("stirling2iter(n,m): n < 0");
|
||||
if(m<0)return newerror("stirling2iter(n,m): m < 0");
|
||||
/* no shortcuts here */
|
||||
|
||||
if(n<m) return 0;
|
||||
if(n==0 && n!=m) return 0;
|
||||
if(n==m) return 1;
|
||||
if(m==0 )return 0;
|
||||
if(m==1) return 1;
|
||||
if(m==2) return 2^(n-1)-1;
|
||||
|
||||
nm = n-m;
|
||||
if(__CZ__stirling2_n >= n && __CZ__stirling2_m >= m){
|
||||
return __CZ__stirling2[n,m];
|
||||
}
|
||||
else{
|
||||
__CZ__stirling2 = mat[n+1,m+1];
|
||||
__CZ__stirling2[0,0] = 1;
|
||||
for(i=1;i<=n;i++){
|
||||
__CZ__stirling2[i,0] = 0;
|
||||
for(j=1;j<=m;j++){
|
||||
if(j<=i){
|
||||
__CZ__stirling2[i, j] = __CZ__stirling2[i -1, j -1] + (j )\
|
||||
* __CZ__stirling2[i - 1, j];
|
||||
}
|
||||
else{
|
||||
__CZ__stirling2[i, j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
__CZ__stirling2_n = (n);
|
||||
__CZ__stirling2_m = (m);
|
||||
return __CZ__stirling2[n,m];
|
||||
}
|
||||
|
||||
define bell(n){
|
||||
local sum s2list k A;
|
||||
|
||||
if(!isint(n)) return newerror("bell(n): n is not integer");
|
||||
if(n < 0) return newerror("bell(n): n is not positive");
|
||||
/* place some more shortcuts here?*/
|
||||
if(n<=15){
|
||||
mat A[16] = {
|
||||
1, 1, 2, 5, 15, 52, 203, 877, 4140, 21147, 115975, 678570,
|
||||
4213597, 27644437, 190899322, 1382958545
|
||||
};
|
||||
return A[n];
|
||||
}
|
||||
/* Start by generating the list of stirling numbers of the second kind */
|
||||
s2list = stirling2caching(n,n//2);
|
||||
if(iserror(s2list))
|
||||
return newerror("bell(n): could not build stirling num. list");
|
||||
sum = 0;
|
||||
for(k=1;k<=n;k++){
|
||||
sum += stirling2caching(n,k);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
define subfactorialrecursive(n){
|
||||
if(n==0) return 1;
|
||||
if(n==1) return 0;
|
||||
if(n==2) return 1;
|
||||
return n * subfactorialrecursive(n-1) + (-1)^n;
|
||||
}
|
||||
|
||||
/* This is, quite amusingly, faster than the very same algorithm in
|
||||
PARI/GP + GMP*/
|
||||
define subfactorialiterative(n){
|
||||
local k temp1 temp2 ret;
|
||||
if(n==0) return 1;
|
||||
if(n==1) return 0;
|
||||
if(n==2) return 1;
|
||||
temp1 = 0;
|
||||
ret = 1;
|
||||
for(k=3;k<=n;k++){
|
||||
temp2 = temp1;
|
||||
temp1 = ret;
|
||||
ret = (k-1) *(temp1 + temp2);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
define subfactorial(n){
|
||||
local epsilon eps ret lnfact;
|
||||
if(!isint(n))return newerror("subfactorial(n): n is not integer.");
|
||||
if(n < 0)return newerror("subfactorial(n): n < 0");
|
||||
return subfactorialiterative(n);
|
||||
}
|
||||
|
||||
define risingfactorial(x,n){
|
||||
local num denom quot ret;
|
||||
if(n == 1) return x;
|
||||
if(x==0) return newerror("risingfactorial(x,n): x == 0");
|
||||
if(!isint(x) || !isint(n)){
|
||||
return gamma(x+n)/gamma(x);
|
||||
}
|
||||
if(x<1)return newerror("risingfactorial(x,n): integer x and x < 1");
|
||||
if(x+n < 1)return newerror("risingfactorial(x,n): integer x+n and x+n < 1");
|
||||
if(x<9000&&n<9000){
|
||||
return (x+n-1)!/(x-1)!;
|
||||
}
|
||||
else{
|
||||
num = __CZ__factor_factorial(x+n-1,1);
|
||||
denom = __CZ__factor_factorial(x-1,1);
|
||||
quot = __CZ__subtract_factored_factorials( num , denom );
|
||||
free(num,denom);
|
||||
ret = __CZ__multiply_factored_factorial(quot);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
define fallingfactorial(x,n){
|
||||
local num denom quot ret;
|
||||
if(n == 0) return 1;
|
||||
|
||||
if(!isint(x) || !isint(n)){
|
||||
if(x == n) return gamma(x+1);
|
||||
return gamma(x+1)/gamma(x-n+1);
|
||||
}
|
||||
else{
|
||||
if(x<0 || x-n < 0)
|
||||
return newerror("fallingfactorial(x,n): integer x<0 or x-n < 0");
|
||||
if(x == n) return factorial(x);
|
||||
if(x<9000&&n<9000){
|
||||
return (x)!/(x-n)!;
|
||||
}
|
||||
else{
|
||||
num = __CZ__factor_factorial(x,1);
|
||||
denom = __CZ__factor_factorial(x-n,1);
|
||||
quot = __CZ__subtract_factored_factorials( num , denom );
|
||||
free(num,denom);
|
||||
ret = __CZ__multiply_factored_factorial(quot);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* restore internal function from resource debugging
|
||||
* report important interface functions
|
||||
*/
|
||||
config("resource_debug", resource_debug_level),;
|
||||
if (config("resource_debug") & 3) {
|
||||
print "binomial(n,k)";
|
||||
print "bigcatalan(n)";
|
||||
print "doublefactorial(n)";
|
||||
print "subfactorial(n)";
|
||||
print "stirling1(n,m)";
|
||||
print "stirling2(n,m)";
|
||||
print "stirling2caching(n,m)";
|
||||
print "bell(n)";
|
||||
print "subfactorial(n)";
|
||||
print "risingfactorial(x,n)";
|
||||
print "fallingfactorial(x,n)";
|
||||
}
|
103
cal/gvec.cal
Normal file
103
cal/gvec.cal
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* gvec - vectorize any single-input function or trailing operator
|
||||
*
|
||||
* This version accepts arbitrary number of arguments, but of course
|
||||
* they must all be same length vectors.
|
||||
*
|
||||
* The gvec function is for use in either a two-arg function or a two-arg
|
||||
* operation "function" must be first; calc doesn't care how many more
|
||||
* arguments there actually are.
|
||||
*
|
||||
* Under source code control: 2011/03/31 17:54:55
|
||||
* File existed as early as: 2010
|
||||
*
|
||||
* By Carl Witthoft carl at witthoft dot com
|
||||
*/
|
||||
|
||||
define gvec(function, vector)
|
||||
{
|
||||
local xlen,y,foo;
|
||||
local precx = 1e-50; /* default for now */
|
||||
local argc = param(0)-1;
|
||||
local old_tilde; /* previous config("tilde") */
|
||||
|
||||
/*
|
||||
* parse args
|
||||
*/
|
||||
local plist = mat[argc];
|
||||
if (config("resource_debug") & 8) {
|
||||
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 slist=sort(plist);
|
||||
if (config("resource_debug") & 8) {
|
||||
print "plist=", plist;
|
||||
}
|
||||
local argm = argc-1;
|
||||
if (config("resource_debug") & 8) {
|
||||
print "argm=", argm;
|
||||
}
|
||||
if (slist[0] != slist[argm]) {
|
||||
quit "lengths don't match";
|
||||
}
|
||||
xlen = size(vector);
|
||||
y = mat[xlen];
|
||||
|
||||
/*
|
||||
* We can't do str(vector[j]) outside loop, eval() petulantly refuses to
|
||||
* look at local variables.
|
||||
*
|
||||
* Also we need to config("tilde",0) to turn off lead tilde
|
||||
* (so str(vector[j]) looks like a number.
|
||||
*/
|
||||
old_tilde = config("tilde",0);
|
||||
|
||||
/*
|
||||
* Ok, now check to see if "function" is a function. If not, it's an
|
||||
* operation and it's up to user to make it valid
|
||||
*/
|
||||
if (isdefined(function)) {
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
/* restore tilde mode if needed */
|
||||
config("tilde", old_tilde);
|
||||
|
||||
/* return result */
|
||||
return y;
|
||||
}
|
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: hello.cal,v 29.2 2000/06/07 14:02:25 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/hello.cal,v $
|
||||
* 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
|
||||
|
364
cal/hms.cal
Normal file
364
cal/hms.cal
Normal file
@@ -0,0 +1,364 @@
|
||||
/*
|
||||
* hms - calculate in hours, minutes, and seconds
|
||||
*
|
||||
* Copyright (C) 2010,2021 Landon Curt Noll
|
||||
*
|
||||
* Calc is open software; you can redistribute it and/or modify it under
|
||||
* the terms of the version 2.1 of the GNU Lesser General Public License
|
||||
* 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: 2010/09/01 17:14:55
|
||||
* File existed as early as: 2010
|
||||
*
|
||||
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
|
||||
*/
|
||||
|
||||
|
||||
obj hms {hour, min, sec};
|
||||
|
||||
define hms(hour, min, sec)
|
||||
{
|
||||
local obj hms ans; /* return value */
|
||||
|
||||
/* default missing args to 0 */
|
||||
if (isnull(sec)) {
|
||||
sec = 0;
|
||||
}
|
||||
if (isnull(min)) {
|
||||
min = 0;
|
||||
}
|
||||
|
||||
/* load object */
|
||||
ans.hour = hour;
|
||||
ans.min = min;
|
||||
ans.sec = sec;
|
||||
|
||||
/* return properly formed object */
|
||||
ans = fixhms(ans);
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
define hms_add(a, b)
|
||||
{
|
||||
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;
|
||||
} else {
|
||||
/* 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;
|
||||
} else {
|
||||
/* 2nd arg is not hms, add scalar hours */
|
||||
ans.hour += b;
|
||||
}
|
||||
|
||||
/* return normalized result */
|
||||
ans = fixhms(ans);
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
define hms_neg(a)
|
||||
{
|
||||
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;
|
||||
} else {
|
||||
/* 2nd arg is not hms, negate scalar hours */
|
||||
ans.hour = -a;
|
||||
ans.min = 0;
|
||||
ans.sec = 0;
|
||||
}
|
||||
|
||||
/* return normalized result */
|
||||
ans = fixhms(ans);
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
define hms_sub(a, b)
|
||||
{
|
||||
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;
|
||||
} else {
|
||||
/* 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;
|
||||
} else {
|
||||
/* 2nd arg is not hms, subtract scalar hours */
|
||||
ans.hour -= b;
|
||||
}
|
||||
|
||||
/* return normalized result */
|
||||
ans = fixhms(ans);
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
define hms_mul(a, b)
|
||||
{
|
||||
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;
|
||||
|
||||
/* scalar multiplication */
|
||||
} else if (istype(a, ans)) {
|
||||
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;
|
||||
}
|
||||
|
||||
/* return normalized result */
|
||||
ans = fixhms(ans);
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
define hms_print(a)
|
||||
{
|
||||
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";
|
||||
}
|
||||
|
||||
/* print in hms form */
|
||||
print a.hour : ':' : a.min : ':' : a.sec :;
|
||||
}
|
||||
|
||||
|
||||
define hms_abs(a)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/* compute hours */
|
||||
hour = a.hour + a.min / 60 + a.sec / 3600;
|
||||
|
||||
/* return hours */
|
||||
return hour;
|
||||
}
|
||||
|
||||
|
||||
define hms_norm(a)
|
||||
{
|
||||
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";
|
||||
}
|
||||
|
||||
/* square hours (norm is the square of absolute value */
|
||||
hour = hms_abs(a);
|
||||
|
||||
/* return hours */
|
||||
return hour*hour;
|
||||
}
|
||||
|
||||
|
||||
define hms_test(a)
|
||||
{
|
||||
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";
|
||||
}
|
||||
|
||||
/* return false of non-zero */
|
||||
ans = fixhms(a);
|
||||
if (ans.hour == 0 && ans.min == 0 && ans.sec == 0) {
|
||||
/* false */
|
||||
return 0;
|
||||
}
|
||||
/* true */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
define hms_int(a)
|
||||
{
|
||||
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";
|
||||
}
|
||||
|
||||
/* normalize the argument */
|
||||
ans = fixhms(a);
|
||||
|
||||
/* truncate to the nearest second */
|
||||
ans.sec = int(ans.sec);
|
||||
|
||||
/* return value to the nearest second */
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
define hms_frac(a)
|
||||
{
|
||||
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";
|
||||
}
|
||||
|
||||
/* normalize the argument */
|
||||
ans = fixhms(a);
|
||||
|
||||
/* remove all but fractional seconds */
|
||||
ans.hour = 0;
|
||||
ans.min = 0;
|
||||
ans.sec = frac(ans.sec);
|
||||
|
||||
/* return value to the second fraction */
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
define hms_rel(a,b)
|
||||
{
|
||||
local abs_a, abs_b; /* scalars of the arguments */
|
||||
|
||||
/* compute scalars of the arguments */
|
||||
abs_a = hms_abs(a);
|
||||
abs_b = hms_abs(b);
|
||||
|
||||
/* return the comparison */
|
||||
return cmp(abs_a, abs_b);
|
||||
}
|
||||
|
||||
|
||||
define hms_cmp(a,b)
|
||||
{
|
||||
local abs_a, abs_b; /* scalars of the arguments */
|
||||
|
||||
/* compute scalars of the arguments */
|
||||
abs_a = hms_abs(a);
|
||||
abs_b = hms_abs(b);
|
||||
|
||||
/* return the equality comparison */
|
||||
return (abs_a == abs_b);
|
||||
}
|
||||
|
||||
|
||||
define hms_inc(a)
|
||||
{
|
||||
local obj hms ans; /* return value */
|
||||
|
||||
/* increment a hms object */
|
||||
if (istype(a, ans)) {
|
||||
ans = a;
|
||||
++ans.sec;
|
||||
|
||||
/* return normalized result */
|
||||
ans = fixhms(ans);
|
||||
return ans;
|
||||
}
|
||||
|
||||
/* increment a scalar */
|
||||
return a+1;
|
||||
}
|
||||
|
||||
|
||||
define hms_dec(a)
|
||||
{
|
||||
local obj hms ans; /* return value */
|
||||
|
||||
/* decrement a hms object */
|
||||
if (istype(a, ans)) {
|
||||
ans = a;
|
||||
--ans.sec;
|
||||
|
||||
/* return normalized result */
|
||||
ans = fixhms(ans);
|
||||
return ans;
|
||||
}
|
||||
|
||||
/* decrement a scalar */
|
||||
return a-1;
|
||||
}
|
||||
|
||||
|
||||
define fixhms(a)
|
||||
{
|
||||
local obj hms ans; /* temp value */
|
||||
|
||||
/* firewall */
|
||||
if (! istype(a, ans)) {
|
||||
quit "attempt to fix a non hms object";
|
||||
}
|
||||
|
||||
/* use builtin h2hms function */
|
||||
h2hms(a.hour + a.min/60 + a.sec/3600, a.hour, a.min, a.sec),;
|
||||
|
||||
/* return normalized result */
|
||||
return a;
|
||||
}
|
||||
|
||||
if (config("resource_debug") & 3) {
|
||||
print "obj hms {hour, min, sec} defined";
|
||||
}
|
88
cal/infinities.cal
Normal file
88
cal/infinities.cal
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* infinities - handle infinities symbolically, a little helper file
|
||||
*
|
||||
* Copyright (C) 2013 Christoph Zurnieden
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
static resource_debug_level;
|
||||
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;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
define iscinf(x)
|
||||
{
|
||||
if (isstr(x)) {
|
||||
if (strncmp(x, "cinf", 4) == 0)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
define ispinf(x)
|
||||
{
|
||||
if (isstr(x)) {
|
||||
if (strncmp(x, "pinf", 4) == 0)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
define isninf(x)
|
||||
{
|
||||
if (isstr(x)) {
|
||||
if (strncmp(x, "ninf", 4) == 0)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
define cinf()
|
||||
{
|
||||
return "cinf";
|
||||
}
|
||||
|
||||
define ninf()
|
||||
{
|
||||
return "ninf";
|
||||
}
|
||||
|
||||
define pinf()
|
||||
{
|
||||
return "pinf";
|
||||
}
|
||||
|
||||
|
||||
config("resource_debug", resource_debug_level),;
|
||||
if (config("resource_debug") & 3) {
|
||||
print "isinfinite(x)";
|
||||
print "iscinf(x)";
|
||||
print "ispinf(x)";
|
||||
print "isninf(x)";
|
||||
print "cinf()";
|
||||
print "ninf()";
|
||||
print "pinf()";
|
||||
}
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* intfile - integer to file and file to integer conversion
|
||||
*
|
||||
* Copyright (C) 2001 Landon Curt Noll
|
||||
* Copyright (C) 2001,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
|
||||
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.5 $
|
||||
* @(#) $Id: intfile.cal,v 29.5 2001/04/10 22:09:34 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/intfile.cal,v $
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Under source code control: 2001/03/31 08:13:11
|
||||
* File existed as early as: 2001
|
||||
@@ -31,20 +27,20 @@
|
||||
|
||||
/*
|
||||
* 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)
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* file2be - convert a file into an big endian integer
|
||||
* file2be - convert a file into an big Endian integer
|
||||
*
|
||||
* given:
|
||||
* 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)
|
||||
{
|
||||
@@ -79,13 +75,13 @@ define file2be(filename)
|
||||
|
||||
|
||||
/*
|
||||
* file2le - convert a file into an little endian integer
|
||||
* file2le - convert a file into an little Endian integer
|
||||
*
|
||||
* given:
|
||||
* 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)
|
||||
{
|
||||
@@ -122,7 +118,7 @@ define file2le(filename)
|
||||
|
||||
|
||||
/*
|
||||
* be2file - convert a big endian integer into a file
|
||||
* be2file - convert a big Endian integer into a file
|
||||
*
|
||||
* given:
|
||||
* v integer to write to the file
|
||||
@@ -160,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)));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -172,7 +168,7 @@ define be2file(v, filename)
|
||||
|
||||
|
||||
/*
|
||||
* le2file - convert a little endian integer into a file
|
||||
* le2file - convert a little Endian integer into a file
|
||||
*
|
||||
* given:
|
||||
* v integer to write to the file
|
||||
|
728
cal/intnum.cal
Normal file
728
cal/intnum.cal
Normal file
@@ -0,0 +1,728 @@
|
||||
/*
|
||||
* intnum - implementation of tanhsinh- and Gauss-Legendre quadrature
|
||||
*
|
||||
* Copyright (C) 2013,2021 Christoph Zurnieden
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
static resource_debug_level;
|
||||
resource_debug_level = config("resource_debug", 0);
|
||||
|
||||
|
||||
read -once infinities;
|
||||
|
||||
static __CZ__tanhsinh_x;
|
||||
static __CZ__tanhsinh_w;
|
||||
static __CZ__tanhsinh_order;
|
||||
static __CZ__tanhsinh_prec;
|
||||
|
||||
define quadtsdeletenodes()
|
||||
{
|
||||
free(__CZ__tanhsinh_x);
|
||||
free(__CZ__tanhsinh_w);
|
||||
free(__CZ__tanhsinh_order);
|
||||
free(__CZ__tanhsinh_prec);
|
||||
}
|
||||
|
||||
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;
|
||||
__CZ__tanhsinh_order = order;
|
||||
__CZ__tanhsinh_prec = eps;
|
||||
__CZ__tanhsinh_x = list();
|
||||
__CZ__tanhsinh_w = list();
|
||||
/* The tanhsinh algorithm needs a slightly higher precision than G-L */
|
||||
eps = epsilon(eps * 1e-2);
|
||||
places = highbit(1 + int (1 / epsilon())) +1;
|
||||
PI = pi();
|
||||
sum = 0;
|
||||
t0 = 2 ^ (-expo);
|
||||
h = 2 * t0;
|
||||
/*
|
||||
* The author wanted to use the mpmath trick here which was
|
||||
* advertised---and reasonably so!---to be faster. Didn't work out
|
||||
* so well with calc.
|
||||
* PI4 = PI/4;
|
||||
* expt0 = bround(exp(t0),places);
|
||||
* a = bround( PI4 * expt0,places);
|
||||
* b = bround(PI4 / expt0,places);
|
||||
* udelta = bround(exp(h),places);
|
||||
* urdelta = bround(1/udelta,places);
|
||||
*/
|
||||
/* 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);
|
||||
|
||||
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;
|
||||
*/
|
||||
}
|
||||
|
||||
/* Normalize the weights to make them add up to 2 (two) */
|
||||
/*
|
||||
* for(k=0;k < size(__CZ__tanhsinh_w);k++)
|
||||
* sum = bround(sum + __CZ__tanhsinh_w[k],places);
|
||||
* sum *= 2;
|
||||
* for(k=0;k < size(__CZ__tanhsinh_w);k++)
|
||||
* __CZ__tanhsinh_w[k] = bround(2.0 * __CZ__tanhsinh_w[k] / sum,places);
|
||||
*/
|
||||
|
||||
epsilon(eps);
|
||||
return 1;
|
||||
}
|
||||
|
||||
define quadtscore(a, b, n)
|
||||
{
|
||||
local k c d order eps places sum ret x x1 x2 xm w w1 w2 m sizel;
|
||||
|
||||
eps = epsilon(epsilon() * 1e-2);
|
||||
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;
|
||||
} else
|
||||
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 = 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");
|
||||
}
|
||||
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;
|
||||
}
|
||||
epsilon(eps);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __CZ__quadts_error;
|
||||
|
||||
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");
|
||||
epsbits = highbit(1 + int (1 / epsilon())) +1;
|
||||
if (param(0) < 3 || isnull(points)) {
|
||||
/* 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 (a != points[0]) {
|
||||
results[0] = quadtscore(a, points[0]);
|
||||
} else {
|
||||
results[0] = 0;
|
||||
}
|
||||
if (sp == 1) {
|
||||
if (b != points[0]) {
|
||||
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]);
|
||||
}
|
||||
if (b != points[k - 1]) {
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
/* 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) */
|
||||
/* With a bit of undeserved luck we have a result by now. */
|
||||
sp = size(results);
|
||||
for (k = 0; k < sp; k++) {
|
||||
sum += results[k];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
static __CZ__gl_x;
|
||||
static __CZ__gl_w;
|
||||
static __CZ__gl_order;
|
||||
static __CZ__gl_prec;
|
||||
|
||||
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;
|
||||
|
||||
__CZ__gl_x = mat[N];
|
||||
__CZ__gl_w = mat[N];
|
||||
__CZ__gl_order = N;
|
||||
__CZ__gl_prec = epsilon();
|
||||
|
||||
places = highbit(1 + int (1 / epsilon())) +1;
|
||||
|
||||
/*
|
||||
* Compute roots and weights (doing it inline seems to be fastest)
|
||||
* 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);
|
||||
|
||||
__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;
|
||||
}
|
||||
|
||||
define quadgldeletenodes()
|
||||
{
|
||||
free(__CZ__gl_x);
|
||||
free(__CZ__gl_w);
|
||||
free(__CZ__gl_order);
|
||||
free(__CZ__gl_prec);
|
||||
}
|
||||
|
||||
define quadglcore(a, b, n)
|
||||
{
|
||||
local k c d digs order eps places sum ret err x x1 w w1 m;
|
||||
local phalf x2 px1 spx1 u b1 a1 half;
|
||||
|
||||
eps = epsilon(epsilon() * 1e-2);
|
||||
places = highbit(1 + int (1 / epsilon())) +1;
|
||||
if (!isnull(n))
|
||||
order = n;
|
||||
else {
|
||||
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];
|
||||
|
||||
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;
|
||||
} 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;
|
||||
}
|
||||
epsilon(eps);
|
||||
return ret;
|
||||
}
|
||||
|
||||
define quadgl(a, b, points)
|
||||
{
|
||||
local k sp results epsbits nsect interval length segment slope C x1 y1 x2
|
||||
y2;
|
||||
local sum D1 D2 D3 D4;
|
||||
if (param(0) < 2)
|
||||
return newerror("quadgl: not enough arguments");
|
||||
epsbits = highbit(1 + int (1 / epsilon())) +1;
|
||||
if (isnull(points)) {
|
||||
/* 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];
|
||||
if (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);
|
||||
} else {
|
||||
results[1] = 0;
|
||||
}
|
||||
} 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);
|
||||
} 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;
|
||||
|
||||
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 */
|
||||
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) */
|
||||
/* With a bit of undeserved luck we have a result by now. */
|
||||
sp = size(results);
|
||||
for (k = 0; k < sp; k++) {
|
||||
sum += results[k];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
define quad(a, b, points = -1, method = "tanhsinh")
|
||||
{
|
||||
if (isnull(a) || isnull(b) || param(0) < 2)
|
||||
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 (isstr(b)) {
|
||||
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 (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 (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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define makerange(start, end, steps)
|
||||
{
|
||||
local ret k l step C length slope x1 x2 y1 y2;
|
||||
local segment;
|
||||
steps = int (steps);
|
||||
if (steps < 1) {
|
||||
return newerror("makerange: number of steps must be > 0");
|
||||
}
|
||||
if (!isnum(start) || !isnum(end)) {
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
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);
|
||||
|
||||
for (k = re(start), l = 0; k <= (re(end)); k += segment, l++) {
|
||||
x1 = slope * (k) + C;
|
||||
ret[l] = k + x1 * 1i;
|
||||
}
|
||||
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
if (!isnum(center)) {
|
||||
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");
|
||||
}
|
||||
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;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
if (!isnum(center)) {
|
||||
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");
|
||||
}
|
||||
if (!isreal(b) || b <= 0) {
|
||||
return newerror("makecircle: b is not a real > 0");
|
||||
}
|
||||
if (!isreal(angle)) {
|
||||
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;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
config("resource_debug", resource_debug_level),;
|
||||
if (config("resource_debug") & 3) {
|
||||
print "quadtsdeletenodes()";
|
||||
print "quadtscomputenodes(order, expo, eps)";
|
||||
print "quadtscore(a,b,n)";
|
||||
print "quadts(a,b,points)";
|
||||
print "quadglcomputenodes(N)";
|
||||
print "quadgldeletenodes()";
|
||||
print "quadglcore(a,b,n)";
|
||||
print "quadgl(a,b,points)";
|
||||
print "quad(a,b,points=-1,method=\"tanhsinh\")";
|
||||
print "makerange(start, end, steps)";
|
||||
print "makecircle(radius, center, points)";
|
||||
print "makeellipse(angle, a, b, center, points)";
|
||||
print "makepoints(a1,[...])";
|
||||
}
|
284
cal/lambertw.cal
Normal file
284
cal/lambertw.cal
Normal file
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* lambertw - Lambert's W-function
|
||||
*
|
||||
* Copyright (C) 2013,2021 Christoph Zurnieden
|
||||
*
|
||||
* 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: 2013/08/11 01:31:28
|
||||
* File existed as early as: 2013
|
||||
*/
|
||||
|
||||
|
||||
static resource_debug_level;
|
||||
resource_debug_level = config("resource_debug", 0);
|
||||
|
||||
|
||||
/*
|
||||
|
||||
R. M. Corless and G. H. Gonnet and D. E. G. Hare and D. J. Jeffrey and
|
||||
D. E. Knuth, "On the Lambert W Function", Advances n Computational
|
||||
Mathematics, 329--359, (1996)
|
||||
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.112.6117
|
||||
|
||||
D. J. Jeffrey, D. E. G. Hare, R. M. Corless, "Unwinding the branches of the
|
||||
Lambert W function", The Mathematical Scientist, 21, pp 1-7, (1996)
|
||||
http://www.apmaths.uwo.ca/~djeffrey/Offprints/wbranch.pdf
|
||||
|
||||
Darko Verebic, "Having Fun with Lambert W(x) Function"
|
||||
arXiv:1003.1628v1, March 2010, http://arxiv.org/abs/1003.1628
|
||||
|
||||
Winitzki, S. "Uniform Approximations for Transcendental Functions",
|
||||
In Part 1 of Computational Science and its Applications - ICCSA 2003,
|
||||
Lecture Notes in Computer Science, Vol. 2667, Springer-Verlag,
|
||||
Berlin, 2003, 780-789. DOI 10.1007/3-540-44839-X_82
|
||||
A copy may be found by Google.
|
||||
|
||||
|
||||
*/
|
||||
static true = 1;
|
||||
static false = 0;
|
||||
|
||||
/* Branch 0, Winitzki (2003) , the well known Taylor series*/
|
||||
define __CZ__lambertw_0(z,eps){
|
||||
local a=2.344e0, b=0.8842e0, c=0.9294e0, d=0.5106e0, e=-1.213e0;
|
||||
local y=sqrt(2*exp(1)*z+2);
|
||||
return (2*ln(1+b*y)-ln(1+c*ln(1+d*y))+e)/(1+1/(2*ln(1+b*y)+2*a));
|
||||
}
|
||||
/* branch -1 */
|
||||
define __CZ__lambertw_m1(z,eps){
|
||||
local wn k;
|
||||
/* Cut-off found in Maxima */
|
||||
if(z < 0.3) return __CZ__lambertw_app(z,eps);
|
||||
wn = z;
|
||||
/* Verebic (2010) eqs. 16-18*/
|
||||
for(k=0;k<10;k++){
|
||||
wn = ln(-z)-ln(-wn);
|
||||
}
|
||||
return wn;
|
||||
}
|
||||
|
||||
/*
|
||||
generic approximation
|
||||
|
||||
series for 1+W((z-2)/(2 e))
|
||||
|
||||
Corless et al (1996) (4.22)
|
||||
Verebic (2010) eqs. 35-37; more coefficients given at the end of sect. 3.1
|
||||
or online
|
||||
http://www.wolframalpha.com/input/?
|
||||
i=taylor+%28+1%2Bproductlog%28+%28z-2%29%2F%282*e%29+%29+%29
|
||||
or by using the function lambertw_series_print() after running
|
||||
lambertw_series(z,eps,branch,terms) at least once with the wanted number of
|
||||
terms and z = 1 (which might throw an error because the series will not
|
||||
converge in anybodies lifetime for something that far from the branch point).
|
||||
|
||||
|
||||
*/
|
||||
define __CZ__lambertw_app(z,eps){
|
||||
local b0=-1, b1=1, b2=-1/3, b3=11/72;
|
||||
local y=sqrt(2*exp(1)*z+2);
|
||||
return b0 + ( y * (b1 + (y * (b2 + (b3 * y)))));
|
||||
}
|
||||
|
||||
static __CZ__Ws_a;
|
||||
static __CZ__Ws_c;
|
||||
static __CZ__Ws_len=0;
|
||||
|
||||
define lambertw_series_print(){
|
||||
local k;
|
||||
for(k=0;k<__CZ__Ws_len;k++){
|
||||
print num(__CZ__Ws_c[k]):"/":den(__CZ__Ws_c[k]):"*p^":k;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
The series is fast but only if _very_ close to the branch point
|
||||
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.00000000000000000000000000000000000000000000000000i
|
||||
; lambertw(-exp(-1)+.001)-lambertw_series(-exp(-1)+.001,epsilon()*1e-10,1)
|
||||
0.00000000000000000000000000000000000000000000000000-
|
||||
0.00000000000000000000000000000000000000000000000000i
|
||||
*/
|
||||
define lambertw_series(z,eps,branch,terms){
|
||||
local k l limit tmp sum A C P PP epslocal;
|
||||
if(!isnull(terms))
|
||||
limit = terms;
|
||||
else
|
||||
limit = 100;
|
||||
|
||||
if(isnull(eps))
|
||||
eps = epsilon(epsilon()*1e-10);
|
||||
epslocal = epsilon(eps);
|
||||
|
||||
P = sqrt(2*(exp(1)*z+1));
|
||||
if(branch != 0) P = -P;
|
||||
tmp=0;sum=0;PP=P;
|
||||
|
||||
__CZ__Ws_a = mat[limit+1];
|
||||
__CZ__Ws_c = mat[limit+1];
|
||||
__CZ__Ws_len = limit;
|
||||
/*
|
||||
c0 = -1; c1 = 1
|
||||
a0 = 2; a1 =-1
|
||||
*/
|
||||
__CZ__Ws_c[0] = -1; __CZ__Ws_c[1] = 1;
|
||||
__CZ__Ws_a[0] = 2; __CZ__Ws_a[1] = -1;
|
||||
sum += __CZ__Ws_c[0];
|
||||
sum += __CZ__Ws_c[1] * P;
|
||||
PP *= P;
|
||||
for(k=2;k<limit;k++){
|
||||
for(l=2;l<k;l++){
|
||||
__CZ__Ws_a[k] += __CZ__Ws_c[l]*__CZ__Ws_c[k+1-l];
|
||||
}
|
||||
|
||||
__CZ__Ws_c[k] = (k-1) * ( __CZ__Ws_c[k-2]/2
|
||||
+__CZ__Ws_a[k-2]/4)/
|
||||
(k+1)-__CZ__Ws_a[k]/2-__CZ__Ws_c[k-1]/(k+1);
|
||||
tmp = __CZ__Ws_c[k] * PP;
|
||||
sum += tmp;
|
||||
if(abs(tmp) <= eps){
|
||||
epsilon(epslocal);
|
||||
return sum;
|
||||
}
|
||||
PP *= P;
|
||||
}
|
||||
epsilon(epslocal);
|
||||
return
|
||||
newerror(strcat("lambertw_series: does not converge in ",
|
||||
str(limit)," terms" ));
|
||||
}
|
||||
|
||||
/* */
|
||||
define lambertw(z,branch){
|
||||
local eps epslarge ret branchpoint bparea w we ew w1e wn k places m1e;
|
||||
local closeness;
|
||||
|
||||
eps = epsilon();
|
||||
if(branch == 0){
|
||||
if(!im(z)){
|
||||
if(abs(z) <= eps) return 0;
|
||||
if(abs(z-exp(1)) <= eps) return 1;
|
||||
if(abs(z - (-ln(2)/2)) <= eps ) return -ln(2);
|
||||
if(abs(z - (-pi()/2)) <= eps ) return 1i*pi()/2;
|
||||
}
|
||||
}
|
||||
|
||||
branchpoint = -exp(-1);
|
||||
bparea = .2;
|
||||
if(branch == 0){
|
||||
if(!im(z) && abs(z-branchpoint) == 0) return -1;
|
||||
ret = __CZ__lambertw_0(z,eps);
|
||||
/* Yeah, C&P, I know, sorry */
|
||||
##ret = ln(z) + 2*pi()*1i*branch - ln(ln(z)+2*pi()*1i*branch);
|
||||
}
|
||||
else if(branch == 1){
|
||||
if(im(z)<0 && abs(z-branchpoint) <= bparea)
|
||||
ret = __CZ__lambertw_app(z,eps);
|
||||
/* Does calc have a goto? Oh, it does! */
|
||||
ret =ln(z) + 2*pi()*1i*branch - ln(ln(z)+2*pi()*1i*branch);
|
||||
}
|
||||
else if(branch == -1){##print "-1";
|
||||
if(!im(z) && abs(z-branchpoint) == 0) return -1;
|
||||
if(!im(z) && z>branchpoint && z < 0){##print "0";
|
||||
ret = __CZ__lambertw_m1(z,eps);}
|
||||
if(im(z)>=0 && abs(z-branchpoint) <= bparea){##print "1";
|
||||
ret = __CZ__lambertw_app(z,eps);}
|
||||
ret =ln(z) + 2*pi()*1i*branch - ln(ln(z)+2*pi()*1i*branch);
|
||||
}
|
||||
else
|
||||
ret = ln(z) + 2*pi()*1i*branch - ln(ln(z)+2*pi()*1i*branch);
|
||||
|
||||
/*
|
||||
Such a high precision is only needed _very_ close to the branchpoint
|
||||
and might even be insufficient if z has not been computed with
|
||||
sufficient precision itself (M below was calculated by Mathematica and also
|
||||
with the series above with epsilon(1e-200)):
|
||||
; epsilon(1e-50)
|
||||
0.00000000000000000001
|
||||
; display(50)
|
||||
20
|
||||
; M=-0.9999999999999999999999997668356018402875796636464119050387
|
||||
; lambertw(-exp(-1)+1e-50,0)-M
|
||||
-0.00000000000000000000000002678416515423276355643684
|
||||
; epsilon(1e-60)
|
||||
0.0000000000000000000000000000000000000000000000000
|
||||
; A=-exp(-1)+1e-50
|
||||
; epsilon(1e-50)
|
||||
0.00000000000000000000000000000000000000000000000000
|
||||
; lambertw(A,0)-M
|
||||
-0.00000000000000000000000000000000000231185460220585
|
||||
; lambertw_series(A,epsilon(),0)-M
|
||||
-0.00000000000000000000000000000000000132145133161626
|
||||
; epsilon(1e-100)
|
||||
0.00000000000000000000000000000000000000000000000001
|
||||
; A=-exp(-1)+1e-50
|
||||
; epsilon(1e-65)
|
||||
0.00000000000000000000000000000000000000000000000000
|
||||
; lambertw_series(A,epsilon(),0)-M
|
||||
0.00000000000000000000000000000000000000000000000000
|
||||
; lambertw_series(-exp(-1)+1e-50,epsilon(),0)-M
|
||||
-0.00000000000000000000000000000000000000002959444084
|
||||
; epsilon(1e-74)
|
||||
0.00000000000000000000000000000000000000000000000000
|
||||
; lambertw_series(-exp(-1)+1e-50,epsilon(),0)-M
|
||||
-0.00000000000000000000000000000000000000000000000006
|
||||
*/
|
||||
closeness = abs(z-branchpoint);
|
||||
if( closeness< 1){
|
||||
if(closeness != 0)
|
||||
eps = epsilon(epsilon()*( closeness));
|
||||
else
|
||||
eps = epsilon(epsilon()^2);
|
||||
}
|
||||
else
|
||||
eps = epsilon(epsilon()*1e-2);
|
||||
|
||||
|
||||
epslarge =epsilon();
|
||||
|
||||
places = highbit(1 + int(1/epslarge)) + 1;
|
||||
w = ret;
|
||||
for(k=0;k<100;k++){
|
||||
ew = exp(w);
|
||||
we = w*ew;
|
||||
if(abs(we-z)<= 4*epslarge*abs(z))break;
|
||||
w1e = (1+w)*ew;
|
||||
wn = bround(w- ((we - z) / ( w1e - ( (w+2)*(we-z) )/(2*w+2) ) ),places++) ;
|
||||
if( abs(wn - w) <= epslarge*abs(wn)) break;
|
||||
else w = wn;
|
||||
}
|
||||
|
||||
if(k==100){
|
||||
epsilon(eps);
|
||||
return newerror("lambertw: Halley iteration does not converge");
|
||||
}
|
||||
/* The Maxima coders added a check if the iteration converged to the correct
|
||||
branch. This coder deems it superfluous. */
|
||||
|
||||
epsilon(eps);
|
||||
return wn;
|
||||
}
|
||||
|
||||
|
||||
config("resource_debug", resource_debug_level),;
|
||||
if (config("resource_debug") & 3) {
|
||||
print "lambertw(z,branch)";
|
||||
print "lambertw_series(z,eps,branch,terms)";
|
||||
print "lambertw_series_print()";
|
||||
}
|
@@ -1,9 +1,35 @@
|
||||
/*
|
||||
* linear - perform a simple two point 2D linear interpolation
|
||||
*
|
||||
* Copyright (C) 2005-2007,2021 Landon Curt Noll
|
||||
*
|
||||
* Calc is open software; you can redistribute it and/or modify it under
|
||||
* the terms of the version 2.1 of the GNU Lesser General Public License
|
||||
* 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: 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/
|
||||
*/
|
||||
|
||||
/*
|
||||
* linear - perform a simple two point 2D linear interpolation
|
||||
*
|
||||
* given:
|
||||
* x0, y0 first known point on the line
|
||||
* x1, y1 second knonw point on the line
|
||||
* x1, y1 second known point on the line
|
||||
* x a given point to interpolate on
|
||||
*
|
||||
* returns:
|
||||
|
108
cal/lnseries.cal
Normal file
108
cal/lnseries.cal
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* lnseries - special functions (e.g.: gamma, zeta, psi)
|
||||
*
|
||||
* Copyright (C) 2013 Christoph Zurnieden
|
||||
*
|
||||
* 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: 2013/08/11 01:31:28
|
||||
* File existed as early as: 2013
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* hide internal function from resource debugging
|
||||
*/
|
||||
static resource_debug_level;
|
||||
resource_debug_level = config("resource_debug", 0);
|
||||
|
||||
|
||||
static __CZ__int_logs;
|
||||
static __CZ__int_logs_limit;
|
||||
static __CZ__int_logs_prec;
|
||||
|
||||
|
||||
define deletelnseries(){
|
||||
free(__CZ__int_logs,__CZ__int_logs_limit,__CZ__int_logs_prec);
|
||||
}
|
||||
|
||||
define lnfromseries(n){
|
||||
if( isnull(__CZ__int_logs)
|
||||
|| __CZ__int_logs_limit < n
|
||||
|| __CZ__int_logs_prec < log(1/epsilon())){
|
||||
|
||||
lnseries(n+1);
|
||||
}
|
||||
return __CZ__int_logs[n,0];
|
||||
}
|
||||
|
||||
define lnseries(limit){
|
||||
local k j eps ;
|
||||
if( isnull(__CZ__int_logs)
|
||||
|| __CZ__int_logs_limit < limit
|
||||
|| __CZ__int_logs_prec < log(1/epsilon())){
|
||||
__CZ__int_logs = mat[limit+1,2];
|
||||
__CZ__int_logs_limit = limit;
|
||||
__CZ__int_logs_prec = log(1/epsilon());
|
||||
|
||||
/* probably still too much */
|
||||
eps = epsilon(epsilon()*10^(-(5+log(limit))));
|
||||
k =2;
|
||||
while(1){
|
||||
/* the prime itself, compute logarithm */
|
||||
__CZ__int_logs[k,0] = ln(k);
|
||||
__CZ__int_logs[k,1] = k;
|
||||
|
||||
for(j = 2*k;j<=limit;j+=k){
|
||||
/* multiples of prime k, add logarithm of k computed earlier */
|
||||
__CZ__int_logs[j,0] += __CZ__int_logs[k,0];
|
||||
/* First hit, set counter to number */
|
||||
if(__CZ__int_logs[j,1] ==0)
|
||||
__CZ__int_logs[j,1]=j;
|
||||
/* reduce counter by prime added */
|
||||
__CZ__int_logs[j,1] //= __CZ__int_logs[k,1];
|
||||
}
|
||||
|
||||
k++;
|
||||
if(k>=limit) break;
|
||||
/* Erastothenes-sieve: look for next prime. */
|
||||
while(__CZ__int_logs[k,0]!=0){
|
||||
k++;
|
||||
if(k>=limit) break;
|
||||
}
|
||||
}
|
||||
/* Second run to include the last factor */
|
||||
for(k=1;k<=limit;k++){
|
||||
if(__CZ__int_logs[k,1] != k){
|
||||
__CZ__int_logs[k,0] +=__CZ__int_logs[ __CZ__int_logs[k,1],0];
|
||||
__CZ__int_logs[k,1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
epsilon(eps);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* restore internal function from resource debugging
|
||||
*/
|
||||
config("resource_debug", resource_debug_level),;
|
||||
if (config("resource_debug") & 3) {
|
||||
print "lnseries(limit)";
|
||||
print "lnfromseries(n)";
|
||||
print "deletelnseries()";
|
||||
}
|
1018
cal/lucas.cal
1018
cal/lucas.cal
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* lucas_chk - test all primes of the form h*2^n-1, 1<=h<200 and n <= high_n
|
||||
*
|
||||
* Copyright (C) 1999 Landon Curt Noll
|
||||
* Copyright (C) 1999,2021 Landon Curt Noll
|
||||
*
|
||||
* Calc is open software; you can redistribute it and/or modify it under
|
||||
* the terms of the version 2.1 of the GNU Lesser General Public License
|
||||
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.3 $
|
||||
* @(#) $Id: lucas_chk.cal,v 29.3 2001/03/31 13:31:34 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/lucas_chk.cal,v $
|
||||
* 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
|
||||
@@ -307,7 +303,7 @@ read -once "lucas.cal";
|
||||
* [quiet] if given and != 0, then do not print individual test results
|
||||
*
|
||||
* returns:
|
||||
* 1 all is ok
|
||||
* 1 all is OK
|
||||
* 0 something went wrong
|
||||
*/
|
||||
define
|
||||
|
@@ -1,165 +0,0 @@
|
||||
/*
|
||||
* lucas_tbl - lucasian criteria for primality tables
|
||||
*
|
||||
* Copyright (C) 1999 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.
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: lucas_tbl.cal,v 29.2 2000/06/07 14:02:25 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/lucas_tbl.cal,v $
|
||||
*
|
||||
* Under source code control: 1991/01/26 02:43: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/
|
||||
*/
|
||||
|
||||
/*
|
||||
* Lucasian criteria for primality
|
||||
*
|
||||
* The following table is taken from:
|
||||
*
|
||||
* "Lucasian Criteria for the Primality of N=h*2^n-1", by Hans Riesel,
|
||||
* Mathematics of Computation, Vol 23 #108, p 872.
|
||||
*
|
||||
* The index of the *_val[] arrays correspond to the v(1) values found
|
||||
* in the table. That is, for v(1) == x:
|
||||
*
|
||||
* D == d_val[x]
|
||||
* a == a_val[x]
|
||||
* b == b_val[x]
|
||||
* r == r_val[x] (r == abs(a^2 - b^2*D))
|
||||
*
|
||||
*
|
||||
* Note that when *_val[i] is not a number, the related v(1) value
|
||||
* is not found in Table 1.
|
||||
*/
|
||||
|
||||
|
||||
trymax = 100;
|
||||
mat d_val[trymax+1];
|
||||
mat a_val[trymax+1];
|
||||
mat b_val[trymax+1];
|
||||
mat r_val[trymax+1];
|
||||
/* v1= 0 INVALID */
|
||||
/* v1= 1 INVALID */
|
||||
/* v1= 2 INVALID */
|
||||
d_val[ 3]= 5; a_val[ 3]= 1; b_val[ 3]=1; r_val[ 3]=4;
|
||||
d_val[ 4]= 3; a_val[ 4]= 1; b_val[ 4]=1; r_val[ 4]=2;
|
||||
d_val[ 5]= 21; a_val[ 5]= 3; b_val[ 5]=1; r_val[ 5]=12;
|
||||
d_val[ 6]= 2; a_val[ 6]= 1; b_val[ 6]=1; r_val[ 6]=1;
|
||||
/* v1= 7 INVALID */
|
||||
d_val[ 8]= 15; a_val[ 8]= 3; b_val[ 8]=1; r_val[ 8]=6;
|
||||
d_val[ 9]= 77; a_val[ 9]= 7; b_val[ 9]=1; r_val[ 9]=28;
|
||||
d_val[10]= 6; a_val[10]= 2; b_val[10]=1; r_val[10]=2;
|
||||
d_val[11]= 13; a_val[11]= 3; b_val[11]=1; r_val[11]=4;
|
||||
d_val[12]= 35; a_val[12]= 5; b_val[12]=1; r_val[12]=10;
|
||||
d_val[13]= 165; a_val[13]=11; b_val[13]=1; r_val[13]=44;
|
||||
/* v1=14 INVALID */
|
||||
d_val[15]= 221; a_val[15]=13; b_val[15]=1; r_val[15]=52;
|
||||
d_val[16]= 7; a_val[16]= 3; b_val[16]=1; r_val[16]=2;
|
||||
d_val[17]= 285; a_val[17]=15; b_val[17]=1; r_val[17]=60;
|
||||
/* v1=18 INVALID */
|
||||
d_val[19]= 357; a_val[19]=17; b_val[19]=1; r_val[19]=68;
|
||||
d_val[20]= 11; a_val[20]= 3; b_val[20]=1; r_val[20]=2;
|
||||
d_val[21]= 437; a_val[21]=19; b_val[21]=1; r_val[21]=76;
|
||||
d_val[22]= 30; a_val[22]= 5; b_val[22]=1; r_val[22]=5;
|
||||
/* v1=23 INVALID */
|
||||
d_val[24]= 143; a_val[24]=11; b_val[24]=1; r_val[24]=22;
|
||||
d_val[25]= 69; a_val[25]= 9; b_val[25]=1; r_val[25]=12;
|
||||
d_val[26]= 42; a_val[26]= 6; b_val[26]=1; r_val[26]=6;
|
||||
d_val[27]= 29; a_val[27]= 5; b_val[27]=1; r_val[27]=4;
|
||||
d_val[28]= 195; a_val[28]=13; b_val[28]=1; r_val[28]=26;
|
||||
d_val[29]= 93; a_val[29]= 9; b_val[29]=1; r_val[29]=12;
|
||||
d_val[30]= 14; a_val[30]= 4; b_val[30]=1; r_val[30]=2;
|
||||
d_val[31]= 957; a_val[31]=29; b_val[31]=1; r_val[31]=116;
|
||||
d_val[32]= 255; a_val[32]=15; b_val[32]=1; r_val[32]=30;
|
||||
d_val[33]=1085; a_val[33]=31; b_val[33]=1; r_val[33]=124;
|
||||
/* v1=34 INVALID */
|
||||
d_val[35]=1221; a_val[35]=33; b_val[35]=1; r_val[35]=132;
|
||||
d_val[36]= 323; a_val[36]=17; b_val[36]=1; r_val[36]=34;
|
||||
d_val[37]=1365; a_val[37]=35; b_val[37]=1; r_val[37]=140;
|
||||
d_val[38]= 10; a_val[38]= 3; b_val[38]=1; r_val[38]=1;
|
||||
d_val[39]=1517; a_val[39]=37; b_val[39]=1; r_val[39]=148;
|
||||
d_val[40]= 399; a_val[40]=19; b_val[40]=1; r_val[40]=38;
|
||||
d_val[41]=1677; a_val[41]=39; b_val[41]=1; r_val[41]=156;
|
||||
d_val[42]= 110; a_val[42]=10; b_val[42]=1; r_val[42]=10;
|
||||
d_val[43]= 205; a_val[43]=15; b_val[43]=1; r_val[43]=20;
|
||||
d_val[44]= 483; a_val[44]=21; b_val[44]=1; r_val[44]=42;
|
||||
d_val[45]=2021; a_val[45]=43; b_val[45]=1; r_val[45]=172;
|
||||
d_val[46]= 33; a_val[46]= 6; b_val[46]=1; r_val[46]=3;
|
||||
/* v1=47 INVALID */
|
||||
d_val[48]= 23; a_val[48]= 5; b_val[48]=1; r_val[48]=2;
|
||||
d_val[49]=2397; a_val[49]=47; b_val[49]=1; r_val[49]=188;
|
||||
d_val[50]= 39; a_val[50]= 6; b_val[50]=1; r_val[50]=3;
|
||||
d_val[51]= 53; a_val[51]= 7; b_val[51]=1; r_val[51]=4;
|
||||
/* v1=52 INVALID */
|
||||
d_val[53]=2805; a_val[53]=51; b_val[53]=1; r_val[53]=204;
|
||||
d_val[54]= 182; a_val[54]=13; b_val[54]=1; r_val[54]=13;
|
||||
d_val[55]=3021; a_val[55]=53; b_val[55]=1; r_val[55]=212;
|
||||
d_val[56]= 87; a_val[56]= 9; b_val[56]=1; r_val[56]=6;
|
||||
d_val[57]=3245; a_val[57]=55; b_val[57]=1; r_val[57]=220;
|
||||
d_val[58]= 210; a_val[58]=14; b_val[58]=1; r_val[58]=14;
|
||||
d_val[59]=3477; a_val[59]=57; b_val[59]=1; r_val[59]=228;
|
||||
d_val[60]= 899; a_val[60]=29; b_val[60]=1; r_val[60]=58;
|
||||
d_val[61]= 413; a_val[61]=21; b_val[61]=1; r_val[61]=28;
|
||||
/* v1=62 INVALID */
|
||||
d_val[63]=3965; a_val[63]=61; b_val[63]=1; r_val[63]=244;
|
||||
d_val[64]=1023; a_val[64]=31; b_val[64]=1; r_val[64]=62;
|
||||
d_val[65]= 469; a_val[65]=21; b_val[65]=1; r_val[65]=28;
|
||||
d_val[66]= 17; a_val[66]= 4; b_val[66]=1; r_val[66]=1;
|
||||
d_val[67]=4485; a_val[67]=65; b_val[67]=1; r_val[67]=260;
|
||||
d_val[68]=1155; a_val[68]=33; b_val[68]=1; r_val[68]=66;
|
||||
d_val[69]=4757; a_val[69]=67; b_val[69]=1; r_val[69]=268;
|
||||
d_val[70]= 34; a_val[70]= 6; b_val[70]=1; r_val[70]=2;
|
||||
d_val[71]=5037; a_val[71]=69; b_val[71]=1; r_val[71]=276;
|
||||
d_val[72]=1295; a_val[72]=35; b_val[72]=1; r_val[72]=70;
|
||||
d_val[73]= 213; a_val[73]=15; b_val[73]=1; r_val[73]=12;
|
||||
d_val[74]= 38; a_val[74]= 6; b_val[74]=1; r_val[74]=2;
|
||||
d_val[75]=5621; a_val[75]=73; b_val[75]=1; r_val[75]=292;
|
||||
d_val[76]=1443; a_val[76]=37; b_val[76]=1; r_val[76]=74;
|
||||
d_val[77]= 237; a_val[77]=15; b_val[77]=1; r_val[77]=12;
|
||||
d_val[78]= 95; a_val[78]=10; b_val[78]=1; r_val[78]=5;
|
||||
/* v1=79 INVALID */
|
||||
d_val[80]=1599; a_val[80]=39; b_val[80]=1; r_val[80]=78;
|
||||
d_val[81]=6557; a_val[81]=79; b_val[81]=1; r_val[81]=316;
|
||||
d_val[82]= 105; a_val[82]=10; b_val[82]=1; r_val[82]=5;
|
||||
d_val[83]= 85; a_val[83]= 9; b_val[83]=1; r_val[83]=4;
|
||||
d_val[84]=1763; a_val[84]=41; b_val[84]=1; r_val[84]=82;
|
||||
d_val[85]=7221; a_val[85]=83; b_val[85]=1; r_val[85]=332;
|
||||
d_val[86]= 462; a_val[86]=21; b_val[86]=1; r_val[86]=21;
|
||||
d_val[87]=7565; a_val[87]=85; b_val[87]=1; r_val[87]=340;
|
||||
d_val[88]= 215; a_val[88]=15; b_val[88]=1; r_val[88]=10;
|
||||
d_val[89]=7917; a_val[89]=87; b_val[89]=1; r_val[89]=348;
|
||||
d_val[90]= 506; a_val[90]=22; b_val[90]=1; r_val[90]=22;
|
||||
d_val[91]=8277; a_val[91]=89; b_val[91]=1; r_val[91]=356;
|
||||
d_val[92]= 235; a_val[92]=15; b_val[92]=1; r_val[92]=10;
|
||||
d_val[93]=8645; a_val[93]=91; b_val[93]=1; r_val[93]=364;
|
||||
d_val[94]= 138; a_val[94]=12; b_val[94]=1; r_val[94]=6;
|
||||
d_val[95]=9021; a_val[95]=93; b_val[95]=1; r_val[95]=372;
|
||||
d_val[96]= 47; a_val[96]= 7; b_val[96]=1; r_val[96]=2;
|
||||
d_val[97]=1045; a_val[97]=33; b_val[97]=1; r_val[97]=44;
|
||||
/* v1=98 INVALID */
|
||||
d_val[99]=9797; a_val[99]=97; b_val[99]=1; r_val[99]=388;
|
||||
d_val[100]= 51; a_val[100]= 7; b_val[100]=1; r_val[100]=2;
|
||||
|
||||
if (config("resource_debug") & 3) {
|
||||
print "d_val[100] defined";
|
||||
print "a_val[100] defined";
|
||||
print "b_val[100] defined";
|
||||
print "r_val[100] defined";
|
||||
}
|
@@ -17,11 +17,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: mersenne.cal,v 29.2 2000/06/07 14:02:25 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/mersenne.cal,v $
|
||||
* 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
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* mfactor - return the lowest factor of 2^n-1, for n > 0
|
||||
*
|
||||
* Copyright (C) 1999 Landon Curt Noll
|
||||
* Copyright (C) 1999,2021 Landon Curt Noll
|
||||
*
|
||||
* Calc is open software; you can redistribute it and/or modify it under
|
||||
* the terms of the version 2.1 of the GNU Lesser General Public License
|
||||
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: mfactor.cal,v 29.2 2000/06/07 14:02:25 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/mfactor.cal,v $
|
||||
* 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
|
||||
@@ -83,7 +79,7 @@
|
||||
* hindx = 0;
|
||||
* } while (test_factor < some_limit);
|
||||
*
|
||||
* The test, mfactor(67, 1, 10000) took on an 200 Mhz r4k (user CPU seconds):
|
||||
* 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)
|
||||
@@ -103,7 +99,7 @@
|
||||
* 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
|
||||
* 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
|
||||
* takes about 3 seconds and requires ~1.5 Megs of memory.
|
||||
*
|
||||
@@ -260,8 +256,8 @@ define mfactor(n, start_k, rept_loop, p_elim)
|
||||
return q;
|
||||
} else {
|
||||
/* report this loop */
|
||||
printf("at 2*%d*%d+1, cpu: %f\n",
|
||||
(q-1)/(2*n), n, runtime());
|
||||
printf("at 2*%d*%d+1, CPU: %f\n",
|
||||
(q-1)/(2*n), n, usertime());
|
||||
fflush(files(1));
|
||||
loop = 0;
|
||||
}
|
||||
@@ -273,14 +269,14 @@ define mfactor(n, start_k, rept_loop, p_elim)
|
||||
*/
|
||||
if (rept_loop <= ++loop) {
|
||||
/* report this loop */
|
||||
printf("at 2*%d*%d+1, cpu: %f\n",
|
||||
(q-1)/(2*n), n, runtime());
|
||||
printf("at 2*%d*%d+1, CPU: %f\n",
|
||||
(q-1)/(2*n), n, usertime());
|
||||
fflush(files(1));
|
||||
loop = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* skip if divisable by a prime <= 449
|
||||
* skip if divisible by a prime <= 449
|
||||
*
|
||||
* The value 281 was determined by timing loops
|
||||
* which found that 281 was at or near the
|
||||
@@ -289,7 +285,7 @@ define mfactor(n, start_k, rept_loop, p_elim)
|
||||
* 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.
|
||||
* 15.62 sec of CPU time on a 200MHz r4k.
|
||||
*/
|
||||
do {
|
||||
/*
|
||||
|
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: mod.cal,v 29.2 2000/06/07 14:02:25 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/mod.cal,v $
|
||||
* 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
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* natnumset - functions for sets of natural numbers not exceeding a fixed bound
|
||||
*
|
||||
* Copyright (C) 1999 Ernest Bowen
|
||||
* Copyright (C) 1999,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
|
||||
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.3 $
|
||||
* @(#) $Id: natnumset.cal,v 29.3 2006/05/01 19:19:46 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/natnumset.cal,v $
|
||||
* 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
|
||||
@@ -80,7 +76,7 @@
|
||||
* A \ B = set difference, integers in A but not in B
|
||||
*
|
||||
* ~A = complement of A, integers not in A
|
||||
* #A = number ofintegers 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
|
||||
*
|
||||
@@ -104,7 +100,7 @@
|
||||
* A >= B = (B <= A)
|
||||
* A > B = (B < A)
|
||||
*
|
||||
* Expresssions may be formed from the above "arithmetic" operations in
|
||||
* Expressions may be formed from the above "arithmetic" operations in
|
||||
* the usual way, with parentheses for variations from the usual precedence
|
||||
* rules. For example
|
||||
*
|
||||
|
641
cal/palindrome.cal
Normal file
641
cal/palindrome.cal
Normal file
@@ -0,0 +1,641 @@
|
||||
/*
|
||||
* palindrome - palindrome utilities
|
||||
*
|
||||
* Copyright (C) 2021 Landon Curt Noll
|
||||
*
|
||||
* Calc is open software; you can redistribute it and/or modify it under
|
||||
* the terms of the version 2.1 of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* Calc is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
|
||||
* Public License for more details.
|
||||
*
|
||||
* A copy of version 2.1 of the GNU Lesser General Public License is
|
||||
* distributed with calc under the filename COPYING-LGPL. You should have
|
||||
* received a copy with calc; if not, write to Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Under source code control: 2021/11/06 14:35:37
|
||||
* File existed as early as: 2021
|
||||
*
|
||||
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* digitof - return the a digit of a value
|
||||
*
|
||||
* NOTE: We assume base 10 digits and place 1 is the units digit.
|
||||
*
|
||||
* given:
|
||||
* val value to find a digit of
|
||||
* place digit place
|
||||
*
|
||||
* returns:
|
||||
* value (>= 0 and < 10) that is the place-th digit of val
|
||||
* or 0 if place is not a digit of val
|
||||
*/
|
||||
define digitof(val, place)
|
||||
{
|
||||
local d; /* length of val in digits */
|
||||
|
||||
/* determine length */
|
||||
d = digits(val);
|
||||
|
||||
/* firewall - return 0 if digit place doesn't exist */
|
||||
if (place < 1 || place > d) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* return the place-th digit of val as a single digit */
|
||||
return (val // (10^(place-1))) % 10;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* copalplace - determine the other place in a palindrome
|
||||
*
|
||||
* NOTE: We assume base 10 digits and place 1 is the units digit.
|
||||
*
|
||||
* given:
|
||||
* d digits of a value
|
||||
* place digit place
|
||||
*
|
||||
* returns:
|
||||
* given palindrome val, the other digit paired with place
|
||||
* or 0 if place is not a digit of val
|
||||
*/
|
||||
define copalplace(d, place)
|
||||
{
|
||||
/* firewall - return 0 if digit place doesn't exist */
|
||||
if (d < 1 || place < 1 || place > d) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* return digit coplace */
|
||||
return d+1 - place;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* upperhalf - return the upper half of a palindrome
|
||||
*
|
||||
* NOTE: We assume base 10 digits and place 1 is the units digit.
|
||||
*
|
||||
* NOTE: When the value has an odd number of digits, the upper half
|
||||
* includes the middle digit.
|
||||
*
|
||||
* given:
|
||||
* val a value
|
||||
*
|
||||
* returns:
|
||||
* the upper half digits of a value
|
||||
*/
|
||||
define upperhalf(val)
|
||||
{
|
||||
local d; /* length of val in digits */
|
||||
local halfd; /* length of upper hand of val */
|
||||
|
||||
/* determine length */
|
||||
d = digits(val);
|
||||
halfd = d // 2;
|
||||
|
||||
/* return upper half */
|
||||
return (val // 10^halfd);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* mkpal - make a value into a palindrome
|
||||
*
|
||||
* NOTE: We assume base 10 digits and place 1 is the units digit.
|
||||
*
|
||||
* given:
|
||||
* val a value
|
||||
*
|
||||
* returns:
|
||||
* val as a palindrome with lower half being reverse digits of val
|
||||
*/
|
||||
define mkpal(val)
|
||||
{
|
||||
local d; /* length of val in digits */
|
||||
local i; /* counter */
|
||||
local ret; /* palindrome being formed */
|
||||
|
||||
/* determine length */
|
||||
d = digits(val);
|
||||
|
||||
/* insert digits in reverse order at the bottom */
|
||||
ret = val;
|
||||
for (i=0; i < d; ++i) {
|
||||
ret = ret*10 + digit(val, i);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* mkpalmiddigit - make a value into a palindrome with a middle digit
|
||||
*
|
||||
* NOTE: We assume base 10 digits and place 1 is the units digit.
|
||||
*
|
||||
* given:
|
||||
* val a value
|
||||
* digit the digit to put into the middle of the palindrome
|
||||
*
|
||||
* returns:
|
||||
* val as a palindrome with lower half being reverse digits of val
|
||||
* and digit as a middle digit
|
||||
*/
|
||||
define mkpalmiddigit(val, digit)
|
||||
{
|
||||
local d; /* length of val in digits */
|
||||
local i; /* counter */
|
||||
local ret; /* palindrome being formed */
|
||||
|
||||
/* determine length */
|
||||
d = digits(val);
|
||||
|
||||
/* insert digits in reverse order at the bottom */
|
||||
ret = val*10 + digit;
|
||||
for (i=0; i < d; ++i) {
|
||||
ret = ret*10 + digit(val, i);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ispal - determine if a value is a palindrome
|
||||
*
|
||||
* NOTE: We assume base 10 digits and place 1 is the units digit.
|
||||
*
|
||||
* given:
|
||||
* val a value
|
||||
*
|
||||
* returns:
|
||||
* 1 ==> val is a palindrome
|
||||
* 0 ==> val is NOT a palindrome
|
||||
*/
|
||||
define ispal(val)
|
||||
{
|
||||
local half; /* upper half of digits of val */
|
||||
local digit; /* middle digit */
|
||||
|
||||
/* case: val has an even number of digits */
|
||||
if (iseven(digits(val))) {
|
||||
|
||||
/* test palindrome-ness */
|
||||
return (val == mkpal(upperhalf(val)));
|
||||
|
||||
/* case: val can an odd number of digits */
|
||||
} else {
|
||||
|
||||
/* test palindrome-ness */
|
||||
half = upperhalf(val);
|
||||
digit = half % 10;
|
||||
half //= 10;
|
||||
return (val == mkpalmiddigit(half, digit));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* palnextpal - return next palindrome from a known palindrome
|
||||
*
|
||||
* NOTE: We assume base 10 digits and place 1 is the units digit.
|
||||
*
|
||||
* given:
|
||||
* pal a palindrome
|
||||
*
|
||||
* returns:
|
||||
* next palindrome > pal
|
||||
*/
|
||||
define palnextpal(pal)
|
||||
{
|
||||
local paldigits; /* digits in pal */
|
||||
local half; /* upper half of newval */
|
||||
local newhalf; /* half+1 */
|
||||
local newpal; /* new palindrome */
|
||||
|
||||
/* case: negative palindrome */
|
||||
if (pal < 0) {
|
||||
return -(palprevpal(-pal));
|
||||
}
|
||||
|
||||
/*
|
||||
* start with upper half
|
||||
*/
|
||||
half = upperhalf(pal);
|
||||
|
||||
/*
|
||||
* prep to find a larger palindrome
|
||||
*/
|
||||
newhalf = half+1;
|
||||
|
||||
/*
|
||||
* form palindrome from new upper half
|
||||
*
|
||||
* We need to watch for the corner case where changing the
|
||||
* half changes the number of digits as this will impact
|
||||
* or even/odd number of digits processing.
|
||||
*/
|
||||
paldigits = digits(pal);
|
||||
if (digits(newhalf) == digits(half)) {
|
||||
/* no change in half digits: process as normal */
|
||||
if (iseven(paldigits)) {
|
||||
newpal = mkpal(newhalf);
|
||||
} else {
|
||||
newpal = mkpalmiddigit(newhalf // 10, newhalf % 10);
|
||||
}
|
||||
} else {
|
||||
/* change in half digits: process as opposite */
|
||||
if (iseven(paldigits)) {
|
||||
newpal = mkpalmiddigit(newhalf // 10, newhalf % 10);
|
||||
} else {
|
||||
newpal = mkpal(newhalf);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* return the new palindrome
|
||||
*/
|
||||
return newpal;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nextpal - return next palindrome from a value
|
||||
*
|
||||
* NOTE: We assume base 10 digits and place 1 is the units digit.
|
||||
*
|
||||
* given:
|
||||
* val a value
|
||||
*
|
||||
* returns:
|
||||
* next palindrome > val
|
||||
*/
|
||||
define nextpal(val)
|
||||
{
|
||||
local newval; /* val+1 */
|
||||
local newvaldigits; /* digits in newval */
|
||||
local half; /* upper half of newval */
|
||||
local pal; /* palindrome test value */
|
||||
local newpal; /* new palindrome */
|
||||
|
||||
/* case: negative value */
|
||||
if (val < 0) {
|
||||
return -(prevpal(-val));
|
||||
}
|
||||
|
||||
/*
|
||||
* start looking from a larger value
|
||||
*/
|
||||
newval = val+1;
|
||||
newvaldigits = digits(newval);
|
||||
|
||||
/* case: single digit palindrome */
|
||||
if (newvaldigits < 2) {
|
||||
return newval;
|
||||
}
|
||||
|
||||
/*
|
||||
* start with next upper half
|
||||
*/
|
||||
half = upperhalf(newval);
|
||||
|
||||
/*
|
||||
* form palindrome from upper half
|
||||
*
|
||||
* We need to deal with even vs. odd digit counts
|
||||
* when forming a palindrome from a half as the
|
||||
* half may not or may include the middle digit.
|
||||
*/
|
||||
if (iseven(newvaldigits)) {
|
||||
pal = mkpal(half);
|
||||
} else {
|
||||
pal = mkpalmiddigit(half // 10, half % 10);
|
||||
}
|
||||
|
||||
/*
|
||||
* case: we found a larger palindrome, we are done
|
||||
*/
|
||||
if (pal > val) {
|
||||
return pal;
|
||||
}
|
||||
|
||||
/*
|
||||
* we need to find an even larger palindrome
|
||||
*/
|
||||
newpal = palnextpal(pal);
|
||||
|
||||
/*
|
||||
* return the new palindrome
|
||||
*/
|
||||
return newpal;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* palprevpal - return previous palindrome from a palindrome
|
||||
*
|
||||
* NOTE: We assume base 10 digits and place 1 is the units digit.
|
||||
*
|
||||
* given:
|
||||
* pal a palindrome
|
||||
*
|
||||
* returns:
|
||||
* previous palindrome < pal
|
||||
*/
|
||||
define palprevpal(pal)
|
||||
{
|
||||
local paldigits; /* digits in pal */
|
||||
local half; /* upper half of newval */
|
||||
local newhalf; /* half+1 */
|
||||
local newpal; /* new palindrome */
|
||||
|
||||
/* case: negative value */
|
||||
if (pal < 0) {
|
||||
return -(palnextpal(-pal));
|
||||
}
|
||||
|
||||
/* case: single digit palindrome */
|
||||
if (pal < 10) {
|
||||
newpal = pal-1;
|
||||
return newpal;
|
||||
}
|
||||
|
||||
/* case: 10 or 11 */
|
||||
if (pal < 12) {
|
||||
newpal = 9;
|
||||
return newpal;
|
||||
}
|
||||
|
||||
/*
|
||||
* start with upper half
|
||||
*/
|
||||
half = upperhalf(pal);
|
||||
|
||||
/*
|
||||
* prep to find a smaller palindrome
|
||||
*/
|
||||
newhalf = half-1;
|
||||
|
||||
/*
|
||||
* form palindrome from new upper half
|
||||
*
|
||||
* We need to watch for the corner case where changing the
|
||||
* half changes the number of digits as this will impact
|
||||
* or even/odd number of digits processing.
|
||||
*/
|
||||
paldigits = digits(pal);
|
||||
if (digits(newhalf) == digits(half)) {
|
||||
/* no change in half digits: process as normal */
|
||||
if (iseven(paldigits)) {
|
||||
newpal = mkpal(newhalf);
|
||||
} else {
|
||||
newpal = mkpalmiddigit(newhalf // 10, newhalf % 10);
|
||||
}
|
||||
} else {
|
||||
/* change in half digits: process as opposite */
|
||||
if (iseven(paldigits)) {
|
||||
newpal = mkpalmiddigit(newhalf // 10, newhalf % 10);
|
||||
} else {
|
||||
newpal = mkpal(newhalf);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* return the new palindrome
|
||||
*/
|
||||
return newpal;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* prevpal - return previous palindrome from a value
|
||||
*
|
||||
* NOTE: We assume base 10 digits and place 1 is the units digit.
|
||||
*
|
||||
* given:
|
||||
* val a value
|
||||
*
|
||||
* returns:
|
||||
* previous palindrome < val
|
||||
*/
|
||||
define prevpal(val)
|
||||
{
|
||||
local newval; /* val-1 */
|
||||
local newvaldigits; /* digits in newval */
|
||||
local half; /* upper half of newval */
|
||||
local pal; /* palindrome test value */
|
||||
local newpal; /* new palindrome */
|
||||
|
||||
/* case: negative value */
|
||||
if (val < 0) {
|
||||
return -(nextpal(-val));
|
||||
}
|
||||
|
||||
/*
|
||||
* start looking from a smaller value
|
||||
*/
|
||||
newval = val-1;
|
||||
newvaldigits = digits(newval);
|
||||
|
||||
/* case: single digit palindrome */
|
||||
if (newvaldigits < 2) {
|
||||
return newval;
|
||||
}
|
||||
|
||||
/*
|
||||
* start with previous upper half
|
||||
*/
|
||||
half = upperhalf(newval);
|
||||
|
||||
/*
|
||||
* form palindrome from upper half
|
||||
*
|
||||
* We need to deal with even vs. odd digit counts
|
||||
* when forming a palindrome from a half as the
|
||||
* half may not or may include the middle digit.
|
||||
*/
|
||||
if (iseven(newvaldigits)) {
|
||||
pal = mkpal(half);
|
||||
} else {
|
||||
pal = mkpalmiddigit(half // 10, half % 10);
|
||||
}
|
||||
|
||||
/*
|
||||
* case: we found a smaller palindrome, we are done
|
||||
*/
|
||||
if (pal < val) {
|
||||
return pal;
|
||||
}
|
||||
|
||||
/*
|
||||
* we need to find an even smaller palindrome
|
||||
*/
|
||||
newpal = palprevpal(pal);
|
||||
|
||||
/*
|
||||
* return the new palindrome
|
||||
*/
|
||||
return newpal;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nextprimepal - return next palindrome that is a (highly probable) prime
|
||||
*
|
||||
* NOTE: We assume base 10 digits and place 1 is the units digit.
|
||||
*
|
||||
* given:
|
||||
* val a value
|
||||
*
|
||||
* returns:
|
||||
* next palindrome (highly probable) prime > val
|
||||
*/
|
||||
define nextprimepal(val)
|
||||
{
|
||||
local pal; /* palindrome test value */
|
||||
local dpal; /* digits in pal */
|
||||
|
||||
/*
|
||||
* pre-start under the next palindrome
|
||||
*/
|
||||
pal = nextpal(val-1);
|
||||
|
||||
/*
|
||||
* loop until we find a (highly probable) prime or 0
|
||||
*/
|
||||
do {
|
||||
|
||||
/* case: negative values and tiny values */
|
||||
if (pal < 2) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* compute the next palindrome
|
||||
*/
|
||||
pal = palnextpal(pal);
|
||||
dpal = digits(pal);
|
||||
|
||||
/* case: 11 is the only prime palindrome with even digit count */
|
||||
if (pal == 11) {
|
||||
return 11;
|
||||
}
|
||||
|
||||
/* case: even number of digits and not 11 */
|
||||
if (iseven(dpal)) {
|
||||
|
||||
/*
|
||||
* Except for 11 (which is handled above already), there are
|
||||
* no prime palindrome with even digits. So we need to
|
||||
* increase the digit count and work with that larger palindrome.
|
||||
*/
|
||||
pal = nextpal(10^dpal);
|
||||
}
|
||||
|
||||
/* case: palindrome is even or ends in 5 */
|
||||
if (iseven(pal % 10) || (pal%10 == 10/2)) {
|
||||
|
||||
/*
|
||||
* we need to increase the bottom and top digits
|
||||
* so that we have a chance to be prime
|
||||
*/
|
||||
pal += (1 + 10^(dpal-1));
|
||||
}
|
||||
if (config("resource_debug") & 0x8) {
|
||||
print "DEBUG: nextprimepal:", pal;
|
||||
}
|
||||
} while (ptest(pal) == 0 && pal > 0);
|
||||
|
||||
/* return palindrome that his (highly probable) prime or 0 */
|
||||
return pal;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* prevprimepal - return prev palindrome that is a (highly probable) prime
|
||||
*
|
||||
* NOTE: We assume base 10 digits and place 1 is the units digit.
|
||||
*
|
||||
* given:
|
||||
* val a value
|
||||
*
|
||||
* returns:
|
||||
* prev palindrome (highly probable) prime < val or 0
|
||||
*/
|
||||
define prevprimepal(val)
|
||||
{
|
||||
local pal; /* palindrome test value */
|
||||
local dpal; /* digits in pal */
|
||||
|
||||
/*
|
||||
* pre-start over the previous palindrome
|
||||
*/
|
||||
pal = prevpal(val+1);
|
||||
|
||||
/*
|
||||
* loop until we find a (highly probable) prime or 0
|
||||
*/
|
||||
do {
|
||||
|
||||
/*
|
||||
* case: single digit values are always palindromes
|
||||
*/
|
||||
if (val < 10) {
|
||||
/*
|
||||
* The prevcand() call will return 0 if there is no previous prime
|
||||
* such as the case when val < 2.
|
||||
*/
|
||||
return prevcand(pal);
|
||||
}
|
||||
|
||||
/*
|
||||
* compute the previous palindrome
|
||||
*/
|
||||
pal = palprevpal(pal);
|
||||
dpal = digits(pal);
|
||||
|
||||
/* case: 11 is the only prime palindrome with even digit count */
|
||||
if (pal == 11) {
|
||||
return 11;
|
||||
}
|
||||
|
||||
/* case: 2 digit palindrome and not 11 */
|
||||
if (dpal == 2) {
|
||||
return 7;
|
||||
}
|
||||
|
||||
/* case: even number of digits */
|
||||
if (iseven(dpal)) {
|
||||
|
||||
/*
|
||||
* Except for 11 (which is handled above already), there are
|
||||
* no prime palindrome with even digits. So we need to
|
||||
* decrease the digit count and work with that smaller palindrome.
|
||||
*/
|
||||
pal = prevpal(10^(dpal-1));
|
||||
}
|
||||
|
||||
/* case: palindrome is even or ends in 5 */
|
||||
if (iseven(pal % 10) || (pal%10 == 10/2)) {
|
||||
|
||||
/*
|
||||
* we need to decrease the bottom and top digits
|
||||
* so that we have a chance to be prime
|
||||
*/
|
||||
pal -= (1 + 10^(dpal-1));
|
||||
}
|
||||
if (config("resource_debug") & 0x8) {
|
||||
print "DEBUG: prevprimepal:", pal;
|
||||
}
|
||||
} while (ptest(pal) == 0 && pal > 0);
|
||||
|
||||
/* return palindrome that his (highly probable) prime or 0 */
|
||||
return pal;
|
||||
}
|
10
cal/pell.cal
10
cal/pell.cal
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* pell - solve Pell's equation
|
||||
*
|
||||
* Copyright (C) 1999 David I. Bell
|
||||
* Copyright (C) 1999,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
|
||||
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: pell.cal,v 29.2 2000/06/07 14:02:25 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/pell.cal,v $
|
||||
* 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
|
||||
@@ -29,7 +25,7 @@
|
||||
|
||||
/*
|
||||
* Solve Pell's equation; Returns the solution X to: X^2 - D * Y^2 = 1.
|
||||
* Type the solution to pells equation for a particular D.
|
||||
* Type the solution to Pell's equation for a particular D.
|
||||
*/
|
||||
|
||||
|
||||
|
10
cal/pi.cal
10
cal/pi.cal
@@ -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
|
||||
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.5 $
|
||||
* @(#) $Id: pi.cal,v 29.5 2004/02/23 14:04:01 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/pi.cal,v $
|
||||
* 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
|
||||
@@ -78,7 +74,7 @@ define qpi(epsilon)
|
||||
/*
|
||||
* 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.
|
||||
|
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: pix.cal,v 29.2 2000/06/07 14:02:25 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/pix.cal,v $
|
||||
* 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
|
||||
|
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: pollard.cal,v 29.2 2000/06/07 14:02:25 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/pollard.cal,v $
|
||||
* 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
|
||||
|
12
cal/poly.cal
12
cal/poly.cal
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* poly - calculate with polynomials of one variable
|
||||
*
|
||||
* Copyright (C) 1999 Ernest Bowen
|
||||
* Copyright (C) 1999,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
|
||||
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: poly.cal,v 29.2 2000/06/07 14:02:25 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/poly.cal,v $
|
||||
* 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
|
||||
@@ -39,7 +35,7 @@
|
||||
* variable has only one name. For some purposes, a name like
|
||||
* "sin(t)" or "(a + b)" or "\lambda" might be useful;
|
||||
* names like "*" or "-27" are legal but might give expressions
|
||||
* that are difficult to intepret.
|
||||
* that are difficult to interpret.
|
||||
*
|
||||
* Polynomial expressions may be constructed from numbers and the
|
||||
* independent variable and other polynomials by the algebraic
|
||||
@@ -47,7 +43,7 @@
|
||||
* The operations // and % are defined to have the quotient and
|
||||
* remainder meanings as usually defined for polynomials.
|
||||
*
|
||||
* When polynomials are assigned to idenfifiers, it is convenient to
|
||||
* When polynomials are assigned to identifiers, it is convenient to
|
||||
* think of the polynomials as values. For example, p = (x - 1)^2
|
||||
* assigns to p a polynomial value in the same way as q = (7 - 1)^2
|
||||
* would assign to q a number value. As with number expressions
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* prompt - eemonstration of some uses of prompt() and eval()
|
||||
* prompt - demonstration of some uses of prompt() and eval()
|
||||
*
|
||||
* Copyright (C) 1999 Ernest Bowen
|
||||
* Copyright (C) 1999,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
|
||||
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.3 $
|
||||
* @(#) $Id: prompt.cal,v 29.3 2006/06/20 09:29:16 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/prompt.cal,v $
|
||||
* 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
|
||||
@@ -65,9 +61,9 @@
|
||||
* 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)
|
||||
* calc but eval("print 7") causes an exit from calc. XXX)
|
||||
*
|
||||
* If the value returned is not a number (e.g. the name of a list or matrix,
|
||||
* or if the string has syntax errors as in "2 + ", in which case the
|
||||
@@ -79,7 +75,7 @@
|
||||
* "sin(x)", "x^2 + 3*x", "exp(x, 1e-5)".
|
||||
*
|
||||
* Values of the function so defined are returned for values of x
|
||||
* entered in reponse to the ? prompt. Operation is terminated by
|
||||
* entered in response to the ? prompt. Operation is terminated by
|
||||
* entering "end", "exit" or "quit".
|
||||
*/
|
||||
|
||||
|
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: psqrt.cal,v 29.2 2000/06/07 14:02:25 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/psqrt.cal,v $
|
||||
* 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
|
||||
|
@@ -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
|
||||
@@ -18,11 +18,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.4 $
|
||||
* @(#) $Id: qtime.cal,v 29.4 2000/12/18 10:18:40 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/qtime.cal,v $
|
||||
* 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
|
||||
|
13
cal/quat.cal
13
cal/quat.cal
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* quat - alculate using quaternions of the form: a + bi + cj + dk
|
||||
* quat - calculate using quaternions of the form: a + bi + cj + dk
|
||||
*
|
||||
* Copyright (C) 1999 David I. Bell
|
||||
* Copyright (C) 1999,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
|
||||
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: quat.cal,v 29.2 2000/06/07 14:02:25 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/quat.cal,v $
|
||||
* 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
|
||||
@@ -55,7 +51,8 @@ define quat(a,b,c,d)
|
||||
|
||||
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] : ")" :;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: randbitrun.cal,v 29.2 2000/06/07 14:02:25 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/randbitrun.cal,v $
|
||||
* 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
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* randmprime - generate a random prime of the form h*2^n-1
|
||||
*
|
||||
* Copyright (C) 1999 Landon Curt Noll
|
||||
* Copyright (C) 1999,2021 Landon Curt Noll
|
||||
*
|
||||
* Calc is open software; you can redistribute it and/or modify it under
|
||||
* the terms of the version 2.1 of the GNU Lesser General Public License
|
||||
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: randmprime.cal,v 29.2 2000/06/07 14:02:25 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/randmprime.cal,v $
|
||||
* 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
|
||||
@@ -49,9 +45,9 @@ 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 afte last test */
|
||||
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 */
|
||||
|
||||
@@ -88,8 +84,8 @@ randmprime(bits, seed, dbg)
|
||||
* loop until we find a prime
|
||||
*/
|
||||
if (dbg >= 1) {
|
||||
start = runtime();
|
||||
init = runtime();
|
||||
start = usertime();
|
||||
init = usertime();
|
||||
plush = 0;
|
||||
print "DEBUG1: testing (h+" : plush : ")*2^" : n : "-1";
|
||||
}
|
||||
@@ -97,7 +93,7 @@ randmprime(bits, seed, dbg)
|
||||
|
||||
/* bump h, and n if needed */
|
||||
if (dbg >= 2) {
|
||||
stop = runtime();
|
||||
stop = usertime();
|
||||
print "DEBUG2: last test:", stop-start, " total time:", stop-init;
|
||||
}
|
||||
if (dbg >= 1) {
|
||||
@@ -116,7 +112,7 @@ randmprime(bits, seed, dbg)
|
||||
|
||||
/* found a prime */
|
||||
if (dbg >= 2) {
|
||||
stop = runtime();
|
||||
stop = usertime();
|
||||
print "DEBUG2: last test:", stop-start, " total time:", stop-init;
|
||||
print "DEBUG3: " : h : "*2^" : n : "-1 is prime";
|
||||
}
|
||||
|
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: randombitrun.cal,v 29.2 2000/06/07 14:02:25 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/randombitrun.cal,v $
|
||||
* 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
|
||||
|
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: randomrun.cal,v 29.2 2000/06/07 14:02:25 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/randomrun.cal,v $
|
||||
* 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
|
||||
|
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: randrun.cal,v 29.2 2000/06/07 14:02:25 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/randrun.cal,v $
|
||||
* 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
|
||||
|
1428
cal/regress.cal
1428
cal/regress.cal
File diff suppressed because it is too large
Load Diff
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.4 $
|
||||
* @(#) $Id: repeat.cal,v 29.4 2003/01/26 19:42:03 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/repeat.cal,v $
|
||||
* 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
|
||||
|
@@ -15,10 +15,6 @@
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: screen.cal,v 29.2 2006/05/01 19:21:18 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/screen.cal,v $
|
||||
*
|
||||
* This file is not covered under version 2.1 of the GNU LGPL.
|
||||
*
|
||||
* Under source code control: 2006/03/08 05:54:09
|
||||
|
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.3 $
|
||||
* @(#) $Id: seedrandom.cal,v 29.3 2001/03/31 13:31:34 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/seedrandom.cal,v $
|
||||
* 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
|
||||
|
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: set8700.cal,v 29.2 2006/08/20 16:16:11 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/set8700.cal,v $
|
||||
* 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
|
||||
|
@@ -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
|
||||
@@ -15,11 +15,7 @@
|
||||
## 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.
|
||||
##
|
||||
## @(#) $Revision: 29.4 $
|
||||
## @(#) $Id: set8700.line,v 29.4 2006/08/20 16:16:11 chongo Exp $
|
||||
## @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/set8700.line,v $
|
||||
## 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
|
||||
@@ -163,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
|
||||
@@ -265,7 +261,7 @@ 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
|
||||
|
||||
## 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
|
||||
set8700_L = {1,set8700_A}, set8700_L[1] == set8700_A
|
||||
|
71
cal/smallfactors.cal
Normal file
71
cal/smallfactors.cal
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* smallfactors - find the factors of a number < 2^32
|
||||
*
|
||||
* Copyright (C) 2013 Christoph Zurnieden
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
static resource_debug_level;
|
||||
resource_debug_level = config("resource_debug", 0);
|
||||
|
||||
|
||||
define smallfactors(x0)
|
||||
{
|
||||
local d q x flist tuple w;
|
||||
|
||||
if (x >= (2 ^ 32) - 1)
|
||||
return newerror("smallfactors: number must be < 2^32 -1");
|
||||
|
||||
tuple = mat[2];
|
||||
flist = list();
|
||||
x = x0;
|
||||
d = 2;
|
||||
q = 0;
|
||||
tuple[0] = d;
|
||||
if (x < 2)
|
||||
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];
|
||||
} while (d <= x);
|
||||
return flist;
|
||||
}
|
||||
|
||||
define printsmallfactors(flist)
|
||||
{
|
||||
local k;
|
||||
for (k = 0; k < size(flist); k++) {
|
||||
print flist[k][0]:"^":flist[k][1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
config("resource_debug", resource_debug_level),;
|
||||
if (config("resource_debug") & 3) {
|
||||
print "smallfactors(x0)";
|
||||
print "printsmallfactors(flist)";
|
||||
|
||||
}
|
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: solve.cal,v 29.2 2000/06/07 14:02:25 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/solve.cal,v $
|
||||
* 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
|
||||
@@ -47,12 +43,13 @@ define solve(low, high, epsilon)
|
||||
if (abs(flow) < epsilon)
|
||||
return low;
|
||||
fhigh = f(high);
|
||||
if (abs(flow) < epsilon)
|
||||
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);
|
||||
mid = bround(high - fhigh * (high - low) / (fhigh - flow),
|
||||
places);
|
||||
if ((mid == low) || (mid == high))
|
||||
places++;
|
||||
fmid = f(mid);
|
||||
|
1465
cal/specialfunctions.cal
Normal file
1465
cal/specialfunctions.cal
Normal file
File diff suppressed because it is too large
Load Diff
498
cal/statistics.cal
Normal file
498
cal/statistics.cal
Normal file
@@ -0,0 +1,498 @@
|
||||
/*
|
||||
* statistics - Some assorted statistics functions.
|
||||
*
|
||||
* Copyright (C) 2013,2021 Christoph Zurnieden
|
||||
*
|
||||
* 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: 2013/08/11 01:31:28
|
||||
* File existed as early as: 2013
|
||||
*/
|
||||
|
||||
|
||||
static resource_debug_level;
|
||||
resource_debug_level = config("resource_debug", 0);
|
||||
|
||||
|
||||
/*
|
||||
* get dependencies
|
||||
*/
|
||||
read -once factorial2 brentsolve
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
*
|
||||
* Continuous distributions
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/* regularized incomplete gamma function like in Octave, hence the name */
|
||||
define gammaincoctave(z,a){
|
||||
local tmp;
|
||||
tmp = gamma(z);
|
||||
return (tmp-gammainc(a,z))/tmp;
|
||||
}
|
||||
|
||||
/* Inverse incomplete beta function. Old and slow. */
|
||||
static __CZ__invbeta_a;
|
||||
static __CZ__invbeta_b;
|
||||
static __CZ__invbeta_x;
|
||||
define __CZ__invbeta(x){
|
||||
return __CZ__invbeta_x-__CZ__ibetaas63(x,__CZ__invbeta_a,__CZ__invbeta_b);
|
||||
}
|
||||
|
||||
define invbetainc_slow(x,a,b){
|
||||
local flag ret eps;
|
||||
/* place checks and balances here */
|
||||
eps = epsilon();
|
||||
if(.5 < x){
|
||||
__CZ__invbeta_x = 1 - x;
|
||||
__CZ__invbeta_a = b;
|
||||
__CZ__invbeta_b = a;
|
||||
flag = 1;
|
||||
}
|
||||
else{
|
||||
__CZ__invbeta_x = x;
|
||||
__CZ__invbeta_a = a;
|
||||
__CZ__invbeta_b = b;
|
||||
flag = 0;
|
||||
}
|
||||
|
||||
ret = brentsolve2(0,1,1);
|
||||
|
||||
if(flag == 1)
|
||||
ret = 1-ret;
|
||||
epsilon(eps);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Inverse incomplete beta function. Still old but not as slow as the function
|
||||
above. */
|
||||
/*
|
||||
Purpose:
|
||||
|
||||
invbetainc computes inverse of the incomplete Beta function.
|
||||
|
||||
Licensing:
|
||||
|
||||
This code is distributed under the GNU LGPL license.
|
||||
|
||||
Modified:
|
||||
|
||||
10 August 2013
|
||||
|
||||
Author:
|
||||
|
||||
Original FORTRAN77 version by GW Cran, KJ Martin, GE Thomas.
|
||||
C version by John Burkardt.
|
||||
Calc version by Christoph Zurnieden
|
||||
|
||||
Reference:
|
||||
|
||||
GW Cran, KJ Martin, GE Thomas,
|
||||
Remark AS R19 and Algorithm AS 109:
|
||||
A Remark on Algorithms AS 63: The Incomplete Beta Integral
|
||||
and AS 64: Inverse of the Incomplete Beta integral,
|
||||
Applied Statistics,
|
||||
Volume 26, Number 1, 1977, pages 111-114.
|
||||
|
||||
Parameters:
|
||||
|
||||
Input, P, Q, the parameters of the incomplete
|
||||
Beta function.
|
||||
|
||||
Input, BETA, the logarithm of the value of
|
||||
the complete Beta function.
|
||||
|
||||
Input, ALPHA, the value of the incomplete Beta
|
||||
function. 0 <= ALPHA <= 1.
|
||||
|
||||
Output, the argument of the incomplete
|
||||
Beta function which produces the value ALPHA.
|
||||
|
||||
Local Parameters:
|
||||
|
||||
Local, SAE, the most negative decimal exponent
|
||||
which does not cause an underflow.
|
||||
*/
|
||||
define invbetainc(x,a,b){
|
||||
return __CZ__invbetainc(a,b,lnbeta(a,b),x);
|
||||
}
|
||||
|
||||
define __CZ__invbetainc(p,q,beta,alpha){
|
||||
local a acu adj fpu g h iex indx pp prev qq r s sae sq t tx value;
|
||||
local w xin y yprev places eps;
|
||||
|
||||
/* Dirty trick, don't try at home */
|
||||
eps= epsilon(epsilon()^2);
|
||||
sae = -((log(1/epsilon())/log(2))//2);
|
||||
fpu = 10.0^sae;
|
||||
|
||||
places = highbit(1 + int(1/epsilon())) + 1;
|
||||
value = alpha;
|
||||
if( p <= 0.0 ){
|
||||
epsilon(eps);
|
||||
return newerror("invbeta: argument p <= 0");
|
||||
}
|
||||
if( q <= 0.0 ){
|
||||
epsilon(eps);
|
||||
return newerror("invbeta: argument q <= 0");
|
||||
}
|
||||
|
||||
if( alpha < 0.0 || 1.0 < alpha ){
|
||||
epsilon(eps);
|
||||
return newerror("invbeta: argument alpha out of domain");
|
||||
}
|
||||
if( alpha == 0.0 ){
|
||||
epsilon(eps);
|
||||
return 0;
|
||||
}
|
||||
if( alpha == 1.0 ){
|
||||
epsilon(eps);
|
||||
return 1;
|
||||
}
|
||||
if ( 0.5 < alpha ){
|
||||
a = 1.0 - alpha;
|
||||
pp = q;
|
||||
qq = p;
|
||||
indx = 1;
|
||||
}
|
||||
else{
|
||||
a = alpha;
|
||||
pp = p;
|
||||
qq = q;
|
||||
indx = 0;
|
||||
}
|
||||
r = sqrt ( - ln ( a * a ) );
|
||||
|
||||
y = r-(2.30753+0.27061*r)/(1.0+(0.99229+0.04481*r)*r);
|
||||
|
||||
if ( 1.0 < pp && 1.0 < qq ){
|
||||
r = ( y * y - 3.0 ) / 6.0;
|
||||
s = 1.0 / ( pp + pp - 1.0 );
|
||||
t = 1.0 / ( qq + qq - 1.0 );
|
||||
h = 2.0 / ( s + t );
|
||||
w = y*sqrt(h+r)/h-(t-s)*(r+5.0/6.0-2.0/(3.0*h));
|
||||
value = pp / ( pp + qq * exp ( w + w ) );
|
||||
}
|
||||
else{
|
||||
r = qq + qq;
|
||||
t = 1.0 / ( 9.0 * qq );
|
||||
t = r * ( 1.0 - t + y * sqrt ( t )^ 3 );
|
||||
|
||||
if ( t <= 0.0 ){
|
||||
value = 1.0 - exp ( ( ln ( ( 1.0 - a ) * qq ) + beta ) / qq );
|
||||
}
|
||||
else{
|
||||
t = ( 4.0 * pp + r - 2.0 ) / t;
|
||||
|
||||
if ( t <= 1.0 ) {
|
||||
value = exp ( ( ln ( a * pp ) + beta ) / pp );
|
||||
}
|
||||
else{
|
||||
value = 1.0 - 2.0 / ( t + 1.0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
r = 1.0 - pp;
|
||||
t = 1.0 - qq;
|
||||
yprev = 0.0;
|
||||
sq = 1.0;
|
||||
prev = 1.0;
|
||||
|
||||
if ( value < 0.0001 )
|
||||
value = 0.0001;
|
||||
|
||||
if ( 0.9999 < value )
|
||||
value = 0.9999;
|
||||
|
||||
acu = 10^sae;
|
||||
|
||||
for ( ; ; ){
|
||||
y = bround(__CZ__ibetaas63( value, pp, qq, beta),places);
|
||||
xin = value;
|
||||
y = bround(exp(ln(y-a)+(beta+r*ln(xin)+t*ln(1.0- xin ) )),places);
|
||||
|
||||
if ( y * yprev <= 0.0 ) {
|
||||
prev = max ( sq, fpu );
|
||||
}
|
||||
|
||||
g = 1.0;
|
||||
|
||||
for ( ; ; ){
|
||||
for ( ; ; ){
|
||||
adj = g * y;
|
||||
sq = adj * adj;
|
||||
if ( sq < prev ){
|
||||
tx = value - adj;
|
||||
if ( 0.0 <= tx && tx <= 1.0 ) break;
|
||||
}
|
||||
g = g / 3.0;
|
||||
}
|
||||
if ( prev <= acu ){
|
||||
if ( indx )
|
||||
value = 1.0 - value;
|
||||
epsilon(eps);
|
||||
return value;
|
||||
}
|
||||
if ( y * y <= acu ){
|
||||
if ( indx )
|
||||
value = 1.0 - value;
|
||||
epsilon(eps);
|
||||
return value;
|
||||
}
|
||||
if ( tx != 0.0 && tx != 1.0 )
|
||||
break;
|
||||
g = g / 3.0;
|
||||
}
|
||||
if ( tx == value ) break;
|
||||
value = tx;
|
||||
yprev = y;
|
||||
}
|
||||
if ( indx )
|
||||
value = 1.0 - value;
|
||||
|
||||
epsilon(eps);
|
||||
return value;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
*
|
||||
* Beta distribution
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
define betapdf(x,a,b){
|
||||
if(x<0 || x>1) return newerror("betapdf: parameter x out of domain");
|
||||
if(a<=0) return newerror("betapdf: parameter a out of domain");
|
||||
if(b<=0) return newerror("betapdf: parameter b out of domain");
|
||||
|
||||
return 1/beta(a,b) *x^(a-1)*(1-x)^(b-1);
|
||||
}
|
||||
|
||||
define betacdf(x,a,b){
|
||||
if(x<0 || x>1) return newerror("betacdf: parameter x out of domain");
|
||||
if(a<=0) return newerror("betacdf: parameter a out of domain");
|
||||
if(b<=0) return newerror("betacdf: parameter b out of domain");
|
||||
|
||||
return betainc(x,a,b);
|
||||
}
|
||||
|
||||
define betacdfinv(x,a,b){
|
||||
return invbetainc(x,a,b);
|
||||
}
|
||||
|
||||
define betamedian(a,b){
|
||||
local t106 t104 t103 t105 approx ret;
|
||||
if(a == b) return 1/2;
|
||||
if(a == 1 && b > 0) return 1-(1/2)^(1/b);
|
||||
if(a > 0 && b == 1) return (1/2)^(1/a);
|
||||
if(a == 3 && b == 2){
|
||||
/* Yes, the author is not ashamed to ask Maxima for the exact solution
|
||||
of a quartic equation. */
|
||||
t103 = ( (2^(3/2))/27 +4/27 )^(1/3);
|
||||
t104 = sqrt( ( 9*t103^2 + 4*t103 + 2 )/(t103) )/3;
|
||||
t105 = -t103-2/(9*t103) +8/9;
|
||||
t106 = sqrt( (27*t104*t105+16)/(t104) )/(2*3^(3/2));
|
||||
return -t106+t104/2+1/3;
|
||||
}
|
||||
if(a == 2 && b == 3){
|
||||
t103 = ( (2^(3/2))/27 +4/27 )^(1/3);
|
||||
t104 = sqrt( ( 9*t103^2 + 4*t103 + 2 )/(t103) )/3;
|
||||
t105 = -t103-2/(9*t103) +8/9;
|
||||
t106 = sqrt( (27*t104*t105+16)/(t104) )/(2*3^(3/2));
|
||||
return 1-(-t106+t104/2+1/3);
|
||||
}
|
||||
return invbetainc(1/2,a,b);
|
||||
}
|
||||
|
||||
define betamode(a,b){
|
||||
if(a + b == 2) return newerror("betamod: a + b = 2 = division by zero");
|
||||
return (a-1)/(a+b-2);
|
||||
}
|
||||
|
||||
define betavariance(a,b){
|
||||
return (a*b)/( (a+b)^2*(a+b+1) );
|
||||
}
|
||||
|
||||
define betalnvariance(a,b){
|
||||
return polygamma(1,a)-polygamma(a+b);
|
||||
}
|
||||
|
||||
define betaskewness(a,b){
|
||||
return (2*(b-a)*sqrt(a+b+1))/( (a+b+1)*sqrt(a*b) );
|
||||
}
|
||||
|
||||
define betakurtosis(a,b){
|
||||
local num denom;
|
||||
|
||||
num = 6*( (a-b)^2*(a+b+1)-a*b*(a+b+2));
|
||||
denom = a*b*(a+b+2)*(a+b+3);
|
||||
return num/denom;
|
||||
}
|
||||
|
||||
define betaentropy(a,b){
|
||||
return lnbeta(a,b)-(a-1)*psi(a)-(b-1)*psi(b)+(a+b+1)*psi(a+b);
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
*
|
||||
* Normal (Gaussian) distribution
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
define normalpdf(x,mu,sigma){
|
||||
return 1/(sqrt(2*pi()*sigma^2))*exp( ( (x-mu)^2 )/( 2*sigma^2 ) );
|
||||
}
|
||||
|
||||
define normalcdf(x,mu,sigma){
|
||||
return 1/2*(1+erf( ( x-mu )/( sqrt(2*sigma^2) ) ) );
|
||||
}
|
||||
|
||||
define probit(p){
|
||||
if(p<0 || p > 1) return newerror("probit: p out of domain 0<=p<=1");
|
||||
return sqrt(2)*erfinv(2*p-1);
|
||||
}
|
||||
|
||||
define normalcdfinv(p,mu,sigma){
|
||||
if(p<0 || p > 1) return newerror("normalcdfinv: p out of domain 0<=p<=1");
|
||||
return mu+ sigma*probit(p);
|
||||
}
|
||||
|
||||
define normalmean(mu,sigma){return mu;}
|
||||
|
||||
define normalmedian(mu,sigma){return mu;}
|
||||
|
||||
define normalmode(mu,sigma){return mu;}
|
||||
|
||||
define normalvariance(mu,sigma){return sigma^2;}
|
||||
|
||||
define normalskewness(mu,sigma){return 0;}
|
||||
|
||||
define normalkurtosis(mu,sigma){return 0;}
|
||||
|
||||
define normalentropy(mu,sigma){
|
||||
return 1/3*ln( 2*pi()*exp(1)*sigma^2 );
|
||||
}
|
||||
|
||||
/* moment generating f. */
|
||||
define normalmgf(mu,sigma,t){
|
||||
return exp(mu*t+1/2*sigma^2*t^2);
|
||||
}
|
||||
|
||||
/* characteristic f. */
|
||||
define normalcf(mu,sigma,t){
|
||||
return exp(mu*t-1/2*sigma^2*t^2);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
*
|
||||
* Chi-squared distribution
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
define chisquaredpdf(x,k){
|
||||
if(!isint(k) || k<0) return newerror("chisquaredpdf: k not in N");
|
||||
if(im(x) || x<0) return newerror("chisquaredpdf: x not in +R");
|
||||
/* The gamma function does not check for half integers, do it here? */
|
||||
return 1/(2^(k/2)*gamma(k/2))*x^((k/2)-1)*exp(-x/2);
|
||||
}
|
||||
|
||||
define chisquaredpcdf(x,k){
|
||||
if(!isint(k) || k<0) return newerror("chisquaredcdf: k not in N");
|
||||
if(im(x) || x<0) return newerror("chisquaredcdf: x not in +R");
|
||||
|
||||
return 1/(gamma(k/2))*gammainc(k/2,x/2);
|
||||
}
|
||||
|
||||
define chisquaredmean(x,k){return k;}
|
||||
|
||||
define chisquaredmedian(x,k){
|
||||
/* TODO: implement a FAST inverse incomplete gamma-{q,p} function */
|
||||
return k*(1-2/(9*k))^3;
|
||||
}
|
||||
|
||||
define chisquaredmode(x,k){return max(k-2,0);}
|
||||
define chisquaredvariance(x,k){return 2*k;}
|
||||
define chisquaredskewness(x,k){return sqrt(8/k);}
|
||||
define chisquaredkurtosis(x,k){return 12/k;}
|
||||
define chisquaredentropy(x,k){
|
||||
return k/2+ln(2*gamma(k/2)) + (1-k/2)*psi(k/2);
|
||||
}
|
||||
|
||||
define chisquaredmfg(k,t){
|
||||
if(t>=1/2)return newerror("chisquaredmfg: t >= 1/2");
|
||||
return (1-2*t)^(k/2);
|
||||
}
|
||||
|
||||
define chisquaredcf(k,t){
|
||||
return (1-2*1i*t)^(k/2);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* restore internal function from resource debugging
|
||||
*/
|
||||
config("resource_debug", resource_debug_level),;
|
||||
if (config("resource_debug") & 3) {
|
||||
print "gammaincoctave(z,a)";
|
||||
print "invbetainc(x,a,b)";
|
||||
print "betapdf(x,a,b)";
|
||||
print "betacdf(x,a,b)";
|
||||
print "betacdfinv(x,a,b)";
|
||||
print "betamedian(a,b)";
|
||||
print "betamode(a,b)";
|
||||
print "betavariance(a,b)";
|
||||
print "betalnvariance(a,b)";
|
||||
print "betaskewness(a,b)";
|
||||
print "betakurtosis(a,b)";
|
||||
print "betaentropy(a,b)";
|
||||
print "normalpdf(x,mu,sigma)";
|
||||
print "normalcdf(x,mu,sigma)";
|
||||
print "probit(p)";
|
||||
print "normalcdfinv(p,mu,sigma)";
|
||||
print "normalmean(mu,sigma)";
|
||||
print "normalmedian(mu,sigma)";
|
||||
print "normalmode(mu,sigma)";
|
||||
print "normalvariance(mu,sigma)";
|
||||
print "normalskewness(mu,sigma)";
|
||||
print "normalkurtosis(mu,sigma)";
|
||||
print "normalentropy(mu,sigma)";
|
||||
print "normalmgf(mu,sigma,t)";
|
||||
print "normalcf(mu,sigma,t)";
|
||||
print "chisquaredpdf(x,k)";
|
||||
print "chisquaredpcdf(x,k)";
|
||||
print "chisquaredmean(x,k)";
|
||||
print "chisquaredmedian(x,k)";
|
||||
print "chisquaredmode(x,k)";
|
||||
print "chisquaredvariance(x,k)";
|
||||
print "chisquaredskewness(x,k)";
|
||||
print "chisquaredkurtosis(x,k)";
|
||||
print "chisquaredentropy(x,k)";
|
||||
print "chisquaredmfg(k,t)";
|
||||
print "chisquaredcf(k,t)";
|
||||
}
|
||||
|
41
cal/strings.cal
Normal file
41
cal/strings.cal
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* strings - implementation of some of the macros in ctype.h
|
||||
*
|
||||
* Copyright (C) 2013 Christoph Zurnieden
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
static resource_debug_level;
|
||||
resource_debug_level = config("resource_debug", 0);
|
||||
|
||||
define isascii(c){
|
||||
c = ord(c);
|
||||
return (c >= 0 && c< 128);
|
||||
}
|
||||
|
||||
define isblank(c){
|
||||
c = ord(c);
|
||||
return ( c == 32 || c == 9 );
|
||||
}
|
||||
|
||||
|
||||
config("resource_debug", resource_debug_level),;
|
||||
if (config("resource_debug") & 3) {
|
||||
print "isascii(c)";
|
||||
print "isblank(c)";
|
||||
}
|
||||
|
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: sumsq.cal,v 29.2 2000/06/07 14:02:25 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/sumsq.cal,v $
|
||||
* 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
|
||||
|
@@ -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
|
||||
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.1 $
|
||||
* @(#) $Id: sumtimes.cal,v 29.1 2006/06/23 00:35:30 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/sumtimes.cal,v $
|
||||
* 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
|
||||
@@ -40,13 +36,13 @@ define timematsum(N) {
|
||||
for (n = 0; n < N; n++) sumtimes_A[n] = rand(N);
|
||||
|
||||
ptop = &sumtimes_A[n-1];
|
||||
sumtimes_t0 = runtime();
|
||||
sumtimes_t0 = usertime();
|
||||
for (s = n = 0; n < N; n++) s += sumtimes_A[n];
|
||||
sumtimes_t1 = runtime();
|
||||
sumtimes_t1 = usertime();
|
||||
for (s = 0, p = &sumtimes_A[0]; p <= ptop; p++) s += *p;
|
||||
sumtimes_t2 = runtime();
|
||||
sumtimes_t2 = usertime();
|
||||
s = matsum(sumtimes_A);
|
||||
sumtimes_t3 = runtime();
|
||||
sumtimes_t3 = usertime();
|
||||
|
||||
print "Matrix sum runtimes";
|
||||
printf('\tStandard "for" loop:\t\t%.4f\n', sumtimes_t1 - sumtimes_t0);
|
||||
@@ -60,11 +56,11 @@ define timelistsum(N) {
|
||||
sumtimes_A = makelist(N);
|
||||
for (n = 0; n < N; n++) sumtimes_A[n] = rand(N);
|
||||
|
||||
sumtimes_t0 = runtime();
|
||||
sumtimes_t0 = usertime();
|
||||
for (s = n = 0; n < N; n++) s += sumtimes_A[n];
|
||||
sumtimes_t1 = runtime();
|
||||
sumtimes_t1 = usertime();
|
||||
s = sum(sumtimes_A);
|
||||
sumtimes_t2 = runtime();
|
||||
sumtimes_t2 = usertime();
|
||||
print "List sum runtimes";
|
||||
printf('\tStandard "for" loop:\t\t%.4f\n', sumtimes_t1 - sumtimes_t0);
|
||||
printf('\tUsing builtin "sum":\t\t%.4f\n', sumtimes_t2 - sumtimes_t1);
|
||||
@@ -76,9 +72,9 @@ define timematsort(N) {
|
||||
|
||||
sumtimes_A = mat[N];
|
||||
for (n = 0; n < N; n++) sumtimes_A[n] = rand(N);
|
||||
sumtimes_t0 = runtime();
|
||||
sumtimes_t0 = usertime();
|
||||
sort(sumtimes_A);
|
||||
sumtimes_t1 = runtime();
|
||||
sumtimes_t1 = usertime();
|
||||
printf('\tMatrix sort runtime:\t\t%.4f\n', sumtimes_t1 - sumtimes_t0);
|
||||
}
|
||||
|
||||
@@ -88,9 +84,9 @@ define timelistsort(N) {
|
||||
|
||||
sumtimes_A = makelist(N);
|
||||
for (n = 0; n < N; n++) sumtimes_A[n] = rand(N);
|
||||
sumtimes_t0 = runtime();
|
||||
sumtimes_t0 = usertime();
|
||||
sort(sumtimes_A);
|
||||
sumtimes_t1 = runtime();
|
||||
sumtimes_t1 = usertime();
|
||||
printf('\tList sort runtime:\t\t%.4f\n', sumtimes_t1 - sumtimes_t0);
|
||||
}
|
||||
|
||||
@@ -99,9 +95,9 @@ define timematreverse(N) {
|
||||
|
||||
sumtimes_A = mat[N];
|
||||
for (n = 0; n < N; n++) sumtimes_A[n] = rand(N);
|
||||
sumtimes_t0 = runtime();
|
||||
sumtimes_t0 = usertime();
|
||||
reverse(sumtimes_A);
|
||||
sumtimes_t1 = runtime();
|
||||
sumtimes_t1 = usertime();
|
||||
printf('\tMatrix reverse runtime %.4f\n', sumtimes_t1 - sumtimes_t0);
|
||||
}
|
||||
|
||||
@@ -110,9 +106,9 @@ define timelistreverse(N) {
|
||||
|
||||
sumtimes_A = makelist(N);
|
||||
for (n = 0; n < N; n++) sumtimes_A[n] = rand(N);
|
||||
sumtimes_t0 = runtime();
|
||||
sumtimes_t0 = usertime();
|
||||
reverse(sumtimes_A);
|
||||
sumtimes_t1 = runtime();
|
||||
sumtimes_t1 = usertime();
|
||||
printf('\tList reverse runtime:\t\t%.4f\n', sumtimes_t1 - sumtimes_t0);
|
||||
}
|
||||
|
||||
@@ -124,11 +120,11 @@ define timematssq(N) {
|
||||
for (n = 0; n < N; n++) sumtimes_A[n] = rand(N);
|
||||
|
||||
ptop = &sumtimes_A[n-1];
|
||||
sumtimes_t0 = runtime();
|
||||
sumtimes_t0 = usertime();
|
||||
for (s = n = 0; n < N; n++) s += sumtimes_A[n]^2;
|
||||
sumtimes_t1 = runtime();
|
||||
sumtimes_t1 = usertime();
|
||||
for (s = 0, p = &sumtimes_A[0]; p <= ptop; p++) s += (*p)^2;
|
||||
sumtimes_t2 = runtime();
|
||||
sumtimes_t2 = usertime();
|
||||
|
||||
print "Matrix sum of squares runtimes";
|
||||
printf('\tStandard "for" loop:\t\t%.4f\n', sumtimes_t1 - sumtimes_t0);
|
||||
@@ -141,11 +137,11 @@ define timelistssq(N) {
|
||||
sumtimes_A = makelist(N);
|
||||
for (n = 0; n < N; n++) sumtimes_A[n] = rand(N);
|
||||
|
||||
sumtimes_t0 = runtime();
|
||||
sumtimes_t0 = usertime();
|
||||
for (s = n = 0; n < N; n++) s += sumtimes_A[n]^2;
|
||||
sumtimes_t1 = runtime();
|
||||
sumtimes_t1 = usertime();
|
||||
s = ssq(sumtimes_A);
|
||||
sumtimes_t2 = runtime();
|
||||
sumtimes_t2 = usertime();
|
||||
print "List sum of squares runtimes";
|
||||
printf('\tStandard "for" loop:\t\t%.4f\n', sumtimes_t1 - sumtimes_t0);
|
||||
printf('\tUsing builtin "ssq":\t\t%.4f\n', sumtimes_t2 - sumtimes_t1);
|
||||
@@ -157,14 +153,14 @@ define timehmean(N, M = 10) {
|
||||
sumtimes_A = makelist(N);
|
||||
for (n = 0; n < N; n++) sumtimes_A[n] = rand(1, M);
|
||||
|
||||
sumtimes_t0 = runtime();
|
||||
sumtimes_t0 = usertime();
|
||||
for (s = n = 0; n < N; n++) s += 1/sumtimes_A[n];
|
||||
v1 = N/s;
|
||||
sumtimes_t1 = runtime();
|
||||
sumtimes_t1 = usertime();
|
||||
v2 = hmean(sumtimes_A);
|
||||
sumtimes_t2 = runtime();
|
||||
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);
|
||||
}
|
||||
|
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: surd.cal,v 29.2 2000/06/07 14:02:25 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/surd.cal,v $
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Under source code control: 1990/02/15 01:50:38
|
||||
* File existed as early as: before 1990
|
||||
|
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: test1700.cal,v 29.2 2000/06/07 14:02:25 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/test1700.cal,v $
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Under source code control: 1994/03/14 23:12:51
|
||||
* File existed as early as: 1994
|
||||
|
@@ -15,11 +15,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: test2300.cal,v 29.2 2000/06/07 14:02:25 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/test2300.cal,v $
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Under source code control: 1995/07/09 06:12:13
|
||||
* File existed as early as: 1995
|
||||
|
119
cal/test2600.cal
119
cal/test2600.cal
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* test2600 - 2600 series of the regress.cal test suite
|
||||
*
|
||||
* Copyright (C) 1999 Ernest Bowen and Landon Curt Noll
|
||||
* Copyright (C) 1999,2021 Ernest Bowen and Landon Curt Noll
|
||||
*
|
||||
* Primary author: Ernest Bowen
|
||||
*
|
||||
@@ -17,11 +17,7 @@
|
||||
* 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.
|
||||
*
|
||||
* @(#) $Revision: 29.2 $
|
||||
* @(#) $Id: test2600.cal,v 29.2 2000/06/07 14:02:25 chongo Exp $
|
||||
* @(#) $Source: /usr/local/src/cmd/calc/cal/RCS/test2600.cal,v $
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Under source code control: 1995/10/13 00:13:14
|
||||
* File existed as early as: 1995
|
||||
@@ -54,7 +50,7 @@
|
||||
* of b in power(a, b, eps) is large, the computation required for
|
||||
* a test may be very heavy.
|
||||
*
|
||||
* Test funcations are called as:
|
||||
* Test functions are called as:
|
||||
*
|
||||
* testabc(str, ..., verbose)
|
||||
*
|
||||
@@ -91,7 +87,8 @@ define testismult(str, n, verbose)
|
||||
if (!ismult(c,a)) {
|
||||
m++;
|
||||
if (verbose > 1) {
|
||||
printf("*** Failure with:\na = %d\nb = %d\n", a,b);
|
||||
printf("*** Failure with:\na = %d\nb = %d\n",
|
||||
a,b);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -133,7 +130,8 @@ define testsqrt(str, n, eps, verbose)
|
||||
if (abs(c) > 1) {
|
||||
m++;
|
||||
if (verbose > 1) {
|
||||
printf("*** Failure with:\na = %d\neps = %d\n", a,eps);
|
||||
printf("*** Failure with:\na = %d\neps = %d\n",
|
||||
a,eps);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -178,7 +176,8 @@ define testexp(str, n, eps, verbose)
|
||||
if (abs(c) > 0.02) {
|
||||
m++;
|
||||
if (verbose > 1) {
|
||||
printf("*** Failure with:\na = %d\neps = %d\n", a,eps);
|
||||
printf("*** Failure with:\na = %d\neps = %d\n",
|
||||
a,eps);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -235,7 +234,8 @@ define testln(str, n, eps, verbose)
|
||||
if (abs(c) > 0.5) {
|
||||
m++;
|
||||
if (verbose > 1) {
|
||||
printf("*** Failure with:\na = %d\neps = %d\n", a,eps);
|
||||
printf("*** Failure with:\na = %d\neps = %d\n",
|
||||
a,eps);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -313,6 +313,102 @@ define testpower(str, n, b, eps, verbose)
|
||||
}
|
||||
|
||||
|
||||
define testpower2(str, n, eps, verbose)
|
||||
{
|
||||
local i, a, c, m, min, max;
|
||||
local b;
|
||||
local num;
|
||||
local c2;
|
||||
local oldeps;
|
||||
|
||||
if (isnull(verbose)) verbose = 2;
|
||||
if (verbose > 0) {
|
||||
print str:":",:;
|
||||
}
|
||||
if (isnull(eps))
|
||||
eps = epsilon();
|
||||
oldeps = epsilon(eps);
|
||||
epsilon(eps),;
|
||||
if (!isnum(b))
|
||||
quit "Second argument (exponent) to be a number";
|
||||
min = 1000;
|
||||
max = -1000;
|
||||
for (i = 1; i <= n; i++) {
|
||||
if (verbose > 2) print i,:;
|
||||
|
||||
/* real ^ real */
|
||||
a = rand(1,1e20);
|
||||
a = a / (int(a/2)+rand(1,1e20));
|
||||
b = rand(1,1e20);
|
||||
b = b / (int(b/2)+rand(1,1e20));
|
||||
c = a ^ b;
|
||||
c2 = power(a, b);
|
||||
if (c != c2) {
|
||||
m++;
|
||||
if (verbose > 1) {
|
||||
printf("*** real^real failure for a = %d\n", a);
|
||||
}
|
||||
}
|
||||
|
||||
/* complex ^ real */
|
||||
a = rand(1,1e20);
|
||||
a = a / (int(a/2)+rand(1,1e20));
|
||||
b = rand(1,1e20);
|
||||
b = b / (int(b/2)+rand(1,1e20));
|
||||
c = (a*1i) ^ b;
|
||||
c2 = power(a*1i, b);
|
||||
if (c != c2) {
|
||||
m++;
|
||||
if (verbose > 1) {
|
||||
printf("*** comp^real failure for a = %d\n", a);
|
||||
}
|
||||
}
|
||||
|
||||
/* real ^ complex */
|
||||
a = rand(1,1e20);
|
||||
a = a / (int(a/2)+rand(1,1e20));
|
||||
b = rand(1,1e20);
|
||||
b = b / (int(b/2)+rand(1,1e20));
|
||||
c = a ^ (b*1i);
|
||||
c2 = power(a, b*1i);
|
||||
if (c != c2) {
|
||||
m++;
|
||||
if (verbose > 1) {
|
||||
printf("*** real^comp failure for a = %d\n", a);
|
||||
}
|
||||
}
|
||||
|
||||
/* complex ^ complex */
|
||||
a = rand(1,1e20);
|
||||
a = a / (int(a/2)+rand(1,1e20));
|
||||
b = rand(1,1e20);
|
||||
b = b / (int(b/2)+rand(1,1e20));
|
||||
c = (a*1i) ^ (b*1i);
|
||||
c2 = power(a*1i, b*1i);
|
||||
if (c != c2) {
|
||||
m++;
|
||||
if (verbose > 1) {
|
||||
printf("*** comp^comp failure for a = %d\n", a);
|
||||
}
|
||||
}
|
||||
}
|
||||
epsilon(oldeps),;
|
||||
if (verbose > 0) {
|
||||
if (m) {
|
||||
printf("*** %d error(s)\n", m);
|
||||
printf(" %s: rem/eps min=%d, max=%d\n",
|
||||
str, min, max);
|
||||
} else {
|
||||
printf("no errors\n");
|
||||
}
|
||||
}
|
||||
if (verbose > 1) {
|
||||
printf(" %s: rem/eps min=%0.4d, max=%0.4d\n", str, min, max);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
define cpow(a, b, eps) /* Find rem/eps for power(a,b,eps) */
|
||||
{
|
||||
local v, v1, c, n, d, h;
|
||||
@@ -504,6 +600,7 @@ define test2600(verbose, tnum)
|
||||
err += testsqrt(strcat(str(tnum++),": sqrt",str(i)), n*10,
|
||||
ep, verbose);
|
||||
}
|
||||
err += testpower2(strcat(str(tnum++),": power"), n*4, ep, verbose);
|
||||
if (verbose > 1) {
|
||||
if (err) {
|
||||
print "***", err, "error(s) found in test2600";
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user