Compare commits

...

16 Commits

Author SHA1 Message Date
Landon Curt Noll
abf39b34b6 Release v2.14.0.2
The clean and clobber makefile rules no longer list custom/Makefile
as a dependency.

Unfortunately due to the complex dependency issues between
Makefile, Makefile.ship and custom/Makefile, parallel GNU make
is NOT recommended.  Sorry (tm Canada) :)

Fixed a few typos in CHANGES.

As a side note: We stayed v2.13.x was kept for only a short time.
The move to 2.14.x was motivated by non-compatible changes due to
the default order of CALCRC, plus some new builtin functions.

More changes are likely, so we might see another v2.14.0.x release
before things are declared "recommended stable".

Not that we wan to discourage people from trying v2.14.0, you should
try it.  We just want things to become stable and well field tested
before we reach the "recommended stable" release state.
2021-09-08 14:38:20 -07:00
Landon Curt Noll
552252371f Disable parallel GNU make for now
Unfortunately due to the complex dependency issues between
Makefile, Makefile.ship and custom/Makefile, parallel GNU make
is NOT recommended.  Sorry (tm Canada) :)
2021-09-07 16:35:45 -07:00
Landon Curt Noll
7570010a04 Removed custom/Makefile dependency on clean & clobber rules 2021-09-07 15:51:30 -07:00
Landon Curt Noll
a9ee753dc6 Fixed help detail_help_list rule and DETAIL_HELP
A .bak file was accicently put into the DETAIL_HELP list.
That bogus help file was removed.

Modified the help/Makefile detail_help_list rule to remove .bak files
when forming DETAIL_HELP.
2021-09-07 13:40:19 -07:00
Landon Curt Noll
ca5a81122a Completed degree, radian, gradian builtin conversions
Updated CHANGES.

Updated help/unexpected.

Added help files for d2g(), d2r(), g2d(), g2r(), r2d(), r2g().

Added regression test code for the same functions.

Fixed a few minor typos.
2021-09-07 13:28:03 -07:00
Landon Curt Noll
554cd97145 Initial code for g2d() & d2g() builtins
We still need to add:

    help files for g2d & d2g
    regression tests for g2d & d2g
    notes in related trig help files
    note in unexpected help file
    note in CHANGES
2021-09-07 07:59:51 -07:00
Landon Curt Noll
806606f284 Initial code for g2r() & r2g() builtins
We still need to add:

    help files for g2r & r2g
    regression tests for g2r & r2g
    notes in related trig help files
    note in unexpected help file
    note in CHANGES
2021-09-07 06:58:54 -07:00
Landon Curt Noll
7c0ebc5887 Improve pi cache
Explicitly initialize static pi cache.
Use enums to identify pi cache elements.
Verify pi cache elements used have useful values.
2021-09-07 06:30:21 -07:00
Landon Curt Noll
45665f94a7 Added initial code for d2r() & r2d() builtins
We still need to add:

    help files for d2r & r2d
    regression tests for d2r & r2d
    notes in related trig help files
    note in unexpected help file
    note in CHANGES
2021-09-07 04:49:54 -07:00
Landon Curt Noll
cd736fdbd4 Release v2.14.0.0
The :-separated default CALCRC value has been reversed.
The default CALCRC was:

    ${CALC_SHAREDIR}/startup:~/.calcrc:./.calcinit

The default CALCRC is now:

    ./.calcinit:~/.calcrc:${CALC_SHAREDIR}/startup

See "help environment" for details.

Added engineering mode as per a GitHub pull request from
<GitHub user heitzmann>.  Thank you!  For example:

    ; config("mode","eng"),
    ; 10^41
	    100e39

or for example:

    ; base(1000),
    ; 2^23209-1
	    ~402.87411577898877818187e6984

For more information see:

    help base

Added regression test code for engineering mode.  Improved and
expanded regression test code related to the base() and base2()
builtin functions.

Fixed a critical bug in the above mentioned pull request where
a call to base2(1000) would make calc unstable and likely to
dump core.
2021-09-06 23:30:06 -07:00
Landon Curt Noll
f753884008 Expanded regression test code for base() and base2()
Added regression test code for engineering mode.  Improved and
expanded regression test code related to the base() and base2()
builtin functions.
2021-09-06 19:22:57 -07:00
Landon Curt Noll
1d9a4941ce Fixed critical bug in base2(1000)
Pull request #31 introduced a critical bug that caused
calc to become unstable when base2(1000) was called.

This patch fixes that bug.
2021-09-06 19:08:05 -07:00
Landon Curt Noll
5bde797ba4 Merge pull request #31 from heitzmann/engineering_mode
Add engineering output mode
2021-09-06 16:54:47 -07:00
Landon Curt Noll
ecba35fc26 Reverse default CALCRC :-order
The :-separated default CALCRC value has been reversed.
The default CALCRC was:

    ${CALC_SHAREDIR}/startup:~/.calcrc:./.calcinit

The default CALCRC is now:

    ./.calcinit:~/.calcrc:${CALC_SHAREDIR}/startup

See "help environment" for details.
2021-09-06 16:52:03 -07:00
Lucas Heitzmann Gabrielli
a4f8f367c3 Skip printing exponent when 0. 2021-06-09 13:09:33 -03:00
Lucas Heitzmann Gabrielli
41b11ab785 Add engineering output mode
Similar to scientific mode, engineering mode also displays numbers in
base 10 exponential notation, with the difference that exponents are
always multiples of 3, to facilitate the interpretation in terms of
SI prefixes.

The mode is activated in config thru "engineering" or "eng. For base
and base2, it uses the special value 1000.
2021-06-07 14:11:07 -03:00
30 changed files with 1348 additions and 133 deletions

97
CHANGES
View File

@@ -1,4 +1,89 @@
The following are the changes from calc version 2.13.0.1 to date:
The following are the changes from calc version 2.14.0.0 to date:
The :-separated default CALCRC value has been reversed.
The default CALCRC was:
${CALC_SHAREDIR}/startup:~/.calcrc:./.calcinit
The default CALCRC is now:
./.calcinit:~/.calcrc:${CALC_SHAREDIR}/startup
See "help environment" for details.
Added engineering mode as per a GitHub pull request from
<GitHub user heitzmann>. Thank you! For example:
; config("mode","eng"),
; 10^41
100e39
or for example:
; base(1000),
; 2^23209-1
~402.87411577898877818187e6984
For more information see:
help base
Added regression test code for engineering mode. Improved and
expanded regression test code related to the base() and base2()
builtin functions.
Fixed a critical bug in the above mentioned pull request where
a call to base2(1000) would make calc unstable and likely to
dump core.
Added builtin functions to convert between degrees, radians
and gradians:
d2r(deg) - given degrees returns radians
g2r(grad) - given gradians returns radians
r2d(rad) - given radians returns degrees
g2d(grad) - given gradians returns degrees
r2g(rad) - given radians returns gradians
d2g(deg) - given degrees returns gradians
Add 6 functions take a 2nd optional epsilon argument.
For d2r(deg, ep), r2d(rad, ep), the optional 2nd epsilon argument controls
the precision of the internal constant pi/180.
For g2r(grad, ep), r2g(rad, ep), the optional 2nd epsilon argument controls
the precision of the internal constant pi/200.
The optional 2nd argument is ignored by g2d(grad, ep) and d2g(deg, ep).
The clean and clobber makefile rules no longer list custom/Makefile
as a dependecy.
Unfortunately due to the complex dependency issues between
Makefile, Makefile.ship and custom/Makefile, parallel GNU make
is NOT recommended. Sorry (tm Canada) :)
The clean and clobber makefile rules no longer list custom/Makefile
as a dependency.
Unfortunately due to the complex dependency issues between
Makefile, Makefile.ship and custom/Makefile, parallel GNU make
is NOT recommended. Sorry (tm Canada) :)
Fixed a few typos in CHANGES.
As a side note: We stayed v2.13.x was kept for only a short time.
The move to 2.14.x was motivated by non-compatible changes due to
the default order of CALCRC, plus some new builtin functions.
More changes are likely, so we might see another v2.14.0.x release
before things are declared "recommended stable".
Not that we wan to discourage people from trying v2.14.0, you should
try it. We just want things to become stable and well field tested
before we reach the "recommended stable" release state.
The following are the changes from calc version 2.13.0.1 to 2.13.0.1:
Replaced /usr/local with the use of ${PREFIX} in calc Makefiles.
@@ -31,11 +116,11 @@ The following are the changes from calc version 2.13.0.1 to date:
Updated HOWTO.INSTALL to mention Makefile.local.
The following are the changes from calc version 2.13.0.0 to date:
The following are the changes from calc version 2.13.0.0 to 2.13.0.0:
Fixed typo (missing quotes) in the env rule.
Fixed intendation problem in CHANGES.
Fixed indentation problem in CHANGES.
Combined 2.12.9.1 changes into the 2.12.8.2 to 2.12.9.0
range, and thus renamed the range to 2.12.8.2 to 2.12.9.1.
@@ -71,7 +156,7 @@ The following are the changes from calc version 2.13.0.0 to date:
#!/usr/local/bin/calc -f
...
It is common that -q be usde with a calc script, so assuming the
It is common that -q be used with a calc script, so assuming the
same /usr/local/bin/calc path:
#!/usr/local/bin/calc -q -f
@@ -1321,12 +1406,12 @@ The following are the changes from calc version 2.12.1.10 to 2.12.2:
The custom/Makefile is now constructed from 3 parts: custom/Makefile.head,
the host target section in Makefile, and the custom/Makefile.tail.
The top level Makefile and the custom/Makefile require a GNU Make
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
If your target system does not have GNU make (or equivalent), then
you should try using the Makefile.simple and custom/Makefile.simple
files:

View File

@@ -2,6 +2,14 @@
IMPORTANT: Please see the section at the bottom of this file for
some important information on Makefiles used in calc.
###################################################################
# IMPORTANT: DO NOT run GNU make in parallel mode!!! #
###################################################################
# Unfortunately due to the complex dependency issues between #
# Makefile, Makefile.ship and custom/Makefile, parallel GNU make #
# is NOT recommended. Sorry (tm Canada) :) #
###################################################################
Installing calc from the bzip2-ed tarball in 4 easy steps:
(0) If your platform supports i686 RPMs, you may want to go to:

View File

@@ -35,6 +35,12 @@
# calculator by David I. Bell with help/mods from others
# Makefile by Landon Curt Noll
# Unfortunately due to the complex dependency issues between
# Makefile, Makefile.ship and custom/Makefile, parallel GNU make
# is NOT recommended. Sorry.
#
.NOTPARALLEL:
# Try uname -s if the target was not already set on the make command line
#
ifeq ($(target),)

View File

@@ -59,6 +59,13 @@ SHELL= /bin/sh
#if 0 /* start of skip for non-Gnu makefiles */
# Unfortunately due to the complex dependency issues between
# Makefile, Makefile.ship and custom/Makefile, parallel GNU make
# is NOT recommended. Sorry.
#
.NOTPARALLEL:
##############################################################################
#-=-=-=-=-=-=-=-=- Identify the target machine, if possible -=-=-=-=-=-=-=-=-#
##############################################################################
@@ -1007,10 +1014,10 @@ endif
# If the $CALCRC environment variable is not defined, then the following
# path will be searched for calc resource files.
#
# Select CALCRC= ${CALC_SHAREDIR}/startup;~/.calcrc;./.calcinit for DJGPP.
# Select CALCRC= ./.calcinit:~/.calcrc:${CALC_SHAREDIR}/startup for DJGPP.
#
CALCRC= ${CALC_SHAREDIR}/startup:~/.calcrc:./.calcinit
#CALCRC= ${CALC_SHAREDIR}/startup;~/.calcrc;./.calcinit
CALCRC= ./.calcinit:~/.calcrc:${CALC_SHAREDIR}/startup
#CALCRC= ./.calcinit;~/.calcrc;${CALC_SHAREDIR}/startup
# Determine of the GNU-readline facility will be used instead of the
# builtin calc binding method.
@@ -1198,7 +1205,7 @@ EXT=
# The default calc versions
#
VERSION= 2.13.0.1
VERSION= 2.14.0.2
# Names of shared libraries with versions
#
@@ -1794,7 +1801,7 @@ CALCPATH= .;./cal;~/.cal;${T}${CALC_SHAREDIR};${T}${CUSTOMCALDIR}
else
CALCPATH= .;./cal;~/.cal;${T}${CALC_SHAREDIR}
endif
CALCRC= ${CALC_SHAREDIR}/startup;~/.calcrc;./.calcinit
CALCRC= ./.calcinit;~/.calcrc;${CALC_SHAREDIR}/startup
#
BLD_TYPE= calc-static-only
#
@@ -4831,7 +4838,7 @@ tags: ${CALCSRC} ${LIBSRC} ${H_SRC} ${BUILD_H_SRC} ${MAKE_FILE}
-${CTAGS} ${CALCSRC} ${LIBSRC} ${H_SRC} ${BUILD_H_SRC} 2>&1 | \
${GREP} -v 'Duplicate entry|Second entry ignored'
clean: custom/Makefile
clean:
${V} echo '=-=-=-=-= ${MAKE_FILE} start of $@ rule =-=-=-=-='
${RM} -f ${LIBOBJS}
${RM} -f ${CALCOBJS}
@@ -4852,6 +4859,7 @@ clean: custom/Makefile
cd custom; ${MAKE} -f Makefile ${CUSTOM_PASSDOWN} clean
${V} echo '=-=-=-=-= Back to the main Makefile for $@ rule =-=-=-=-='
${V} echo '=-=-=-=-= Invoking $@ rule for cscript =-=-=-=-='
${MAKE} custom/Makefile
cd cscript; ${MAKE} -f Makefile ${CSCRIPT_PASSDOWN} clean
${V} echo '=-=-=-=-= Back to the main Makefile for $@ rule =-=-=-=-='
${Q} echo remove files that are obsolete
@@ -4861,7 +4869,7 @@ clean: custom/Makefile
${RM} -f win32dll.h have_malloc.h math_error.h string.h string.c
${V} echo '=-=-=-=-= ${MAKE_FILE} end of $@ rule =-=-=-=-='
clobber: clean custom/Makefile
clobber: clean
${V} echo '=-=-=-=-= ${MAKE_FILE} start of $@ rule =-=-=-=-='
${RM} -f ${SAMPLE_TARGETS}
${RM} -f ${SAMPLE_STATIC_TARGETS}
@@ -4898,6 +4906,7 @@ clobber: clean custom/Makefile
${V} echo '=-=-=-=-= Back to the main Makefile for $@ rule =-=-=-=-='
${V} echo '=-=-=-=-= Invoking $@ rule for custom =-=-=-=-='
-${RM} -f custom/all; \
${MAKE} custom/Makefile; \
cd custom; ${MAKE} -f Makefile ${CUSTOM_PASSDOWN} $@
${V} echo '=-=-=-=-= Back to the main Makefile for $@ rule =-=-=-=-='
${V} echo '=-=-=-=-= Invoking $@ rule for cscript =-=-=-=-='

View File

@@ -126,7 +126,7 @@ 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+ -DWINDOZ

View File

@@ -1881,96 +1881,298 @@ define test_mode()
vrfy(tmp == "octal", '1620: tmp == "octal"');
vrfy(base() == 2, '1621: base() == 2');
tmp = config("mode", "real");
print '1622: tmp = config("mode", "real")';
tmp = config("mode", "eng");
print '1622: tmp = config("mode", "eng")';
vrfy(tmp == "binary", '1623: tmp == "binary"');
vrfy(base() == 1000, '1624: base() == 1000');
tmp = config("mode", "real");
print '1625: tmp = config("mode", "real")';
vrfy(tmp == "engineering", '1626: tmp == "engineering"');
tmp = base(1/3);
print '1624: tmp = base(1/3)';
print '1627: tmp = base(1/3)';
vrfy(config("mode") == "fraction",
'1625: config("mode") == "fraction"');
'1628: config("mode") == "fraction"');
tmp = base(-10);
print '1626: tmp = base(-10)';
print '1629: tmp = base(-10)';
vrfy(config("mode") == "integer",
'1627: config("mode") == "integer"');
'1630: config("mode") == "integer"');
tmp = base(10);
print '1628: tmp = base(10)';
vrfy(config("mode") == "real", '1629: config("mode") == "real"');
print '1631: tmp = base(10)';
vrfy(config("mode") == "real", '1632: config("mode") == "real"');
tmp = base(1e20);
print '1630: tmp = base(1e20)';
print '1633: tmp = base(1e20)';
vrfy(config("mode") == "scientific",
'1631: config("mode") == "scientific"');
'1634: config("mode") == "scientific"');
tmp = base(16);
print '1632: tmp = base(16)';
print '1635: tmp = base(16)';
vrfy(config("mode") == "hexadecimal", \
'1633: config("mode") == "hexadecimal"');
'1636: config("mode") == "hexadecimal"');
tmp = base(8);
print '1634: tmp = base(8)';
vrfy(config("mode") == "octal", '1635: config("mode") == "octal"');
print '1637: tmp = base(8)';
vrfy(config("mode") == "octal", '1638: config("mode") == "octal"');
tmp = base(2);
print '1636: tmp = base(2)';
vrfy(config("mode") == "binary",'1637: config("mode") == "binary"');
print '1639: tmp = base(2)';
vrfy(config("mode") == "binary",'1640: config("mode") == "binary"');
tmp = base(1000);
print '1641: tmp = base(1000)';
vrfy(config("mode") == "engineering",
'1642: config("mode") == "engineering"');
tmp = base(1/3);
print '1643: tmp = base(1/3)';
vrfy(str(0x80000000) == "2147483648", \
'1644: str(0x8000000) == \"2147483648\"');
vrfy(str(0xffffffff) == "4294967295", \
'1645: str(0xffffffff) == \"4294967295\"');
vrfy(str(3e9) == "3000000000", \
'1646: str(3e9) == \"3000000000\"');
vrfy(str(1/3) == "1/3", \
'1647: str(1/3) == \"1/3\"');
vrfy(str(2e8) == "200000000", \
'1648: str(2e8) == \"200000000"');
vrfy(str(200e6) == "200000000", \
'1649: str(200e6) == \"200000000"');
vrfy(str(0b100111) == "39", \
'1650: str(0b100111) == \"39"');
vrfy(str(07543) == "3939", \
'1651: str(07543) == \"3939"');
vrfy(str(7543) == "7543", \
'1652: str(7543) == \"7543"');
tmp = base(8);
print '1638: tmp = base(8)';
print '1653: tmp = base(8)';
vrfy(str(0x80000000) == "020000000000", \
'1639: str(0x8000000) == \"020000000000\"');
'1654: str(0x8000000) == \"020000000000\"');
vrfy(str(0xffffffff) == "037777777777", \
'1640: str(0xffffffff) == \"037777777777\"');
'1655: str(0xffffffff) == \"037777777777\"');
vrfy(str(3e9) == "026264057000", \
'1641: str(3e9) == \"026264057000\"');
'1656: str(3e9) == \"026264057000\"');
vrfy(str(1/3) == "1/3", \
'1657: str(1/3) == \"1/3\"');
vrfy(str(2e8) == "01372741000", \
'1658: str(2e8) == \"01372741000"');
vrfy(str(200e6) == "01372741000", \
'1659: str(200e6) == \"01372741000"');
vrfy(str(0b100111) == "047", \
'1660: str(0b100111) == \"047"');
vrfy(str(07543) == "07543", \
'1661: str(07543) == \"07543"');
vrfy(str(7543) == "016567", \
'1662: str(7543) == \"016567"');
tmp = base(16);
print '1642: tmp = base(16)';
print '1663: tmp = base(16)';
vrfy(str(0x80000000) == "0x80000000", \
'1643: str(0x8000000) == \"0x80000000\"');
'1664: str(0x8000000) == \"0x80000000\"');
vrfy(str(0xffffffff) == "0xffffffff", \
'1644: str(0xffffffff) == \"0xffffffff\"');
'1665: str(0xffffffff) == \"0xffffffff\"');
vrfy(str(3e9) == "0xb2d05e00", \
'1645: str(3e9) == \"0xb2d05e00\"');
'1666: str(3e9) == \"0xb2d05e00\"');
vrfy(str(1/3) == "1/3", \
'1667: str(1/3) == \"1/3\"');
vrfy(str(2e8) == "0xbebc200", \
'1668: str(2e8) == \"0xbebc200"');
vrfy(str(200e6) == "0xbebc200", \
'1669: str(200e6) == \"0xbebc200"');
vrfy(str(0b100111) == "0x27", \
'1670: str(0b100111) == \"0x27"');
vrfy(str(07543) == "0xf63", \
'1671: str(07543) == \"0xf63"');
vrfy(str(7543) == "0x1d77", \
'1672: str(7543) == \"0x1d77"');
tmp = base(2);
print '1673: tmp = base(2)';
vrfy(str(0x80000000) == "0b10000000000000000000000000000000", \
'1674: str(0x8000000) == \"0b10000000000000000000000000000000\"');
vrfy(str(0xffffffff) == "0b11111111111111111111111111111111", \
'1675: str(0xffffffff) == \"0b11111111111111111111111111111111\"');
vrfy(str(3e9) == "0b10110010110100000101111000000000", \
'1676: str(3e9) == \"0b10110010110100000101111000000000\"');
vrfy(str(1/3) == "1/0b11", \
'1677: str(1/3) == \"1/0b11\"');
vrfy(str(2e8) == "0b1011111010111100001000000000", \
'1678: str(2e8) == \"0b1011111010111100001000000000"');
vrfy(str(200e6) == "0b1011111010111100001000000000", \
'1679: str(200e6) == \"0b1011111010111100001000000000"');
vrfy(str(0b100111) == "0b100111", \
'1680: str(0b100111) == \"0b100111"');
vrfy(str(07543) == "0b111101100011", \
'1681: str(07543) == \"0b111101100011"');
vrfy(str(7543) == "0b1110101110111", \
'1682: str(7543) == \"0b1110101110111"');
tmp = base(1e20);
print '1683: tmp = base(1e20)';
vrfy(str(0x80000000) == "2.147483648e9", \
'1684: str(0x8000000) == \"2.147483648e9\"');
vrfy(str(0xffffffff) == "4.294967295e9", \
'1685: str(0xffffffff) == \"4.294967295e9\"');
vrfy(str(3e9) == "3e9", \
'1686: str(3e9) == \"3e9\"');
vrfy(str(1/3) == "~3.33333333333333333333e-1", \
'1687: str(1/3) == \"~3.33333333333333333333e-1\"');
vrfy(str(2e8) == "2e8", \
'1688: str(2e8) == \"2e8"');
vrfy(str(200e6) == "2e8", \
'1689: str(200e6) == \"2e8"');
vrfy(str(0b100111) == "3.9e1", \
'1690: str(0b100111) == \"3.9e1"');
vrfy(str(07543) == "3.939e3", \
'1691: str(07543) == \"3.939e3"');
vrfy(str(7543) == "7.543e3", \
'1692: str(7543) == \"7.543e3"');
tmp = base(1000);
print '1693: tmp = base(1000)';
vrfy(str(0x80000000) == "2.147483648e9", \
'1694: str(0x8000000) == \"2.147483648e9"');
vrfy(str(0xffffffff) == "4.294967295e9", \
'1695: str(0xffffffff) == \"4.294967295e9\"');
vrfy(str(3e9) == "3e9", \
'1696: str(3e9) == \"3e9\"');
vrfy(str(1/3) == "~333.33333333333333333333e-3", \
'1697: str(1/3) == \"~333.33333333333333333333e-3\"');
vrfy(str(2e8) == "200e6", \
'1698: str(2e8) == \"200e6"');
vrfy(str(200e6) == "200e6", \
'1699: str(200e6) == \"200e6"');
vrfy(str(0b100111) == "39", \
'1700: str(0b100111) == \"39"');
vrfy(str(07543) == "3.939e3", \
'1701: str(07543) == \"3.939e3"');
vrfy(str(7543) == "7.543e3", \
'1702: str(7543) == \"7.543e3"');
tmp = base(-10);
print '1703: tmp = base(-10)';
vrfy(str(0x80000000) == "2147483648", \
'1704: str(0x8000000) == \"2147483648\"');
vrfy(str(0xffffffff) == "4294967295", \
'1705: str(0xffffffff) == \"4294967295\"');
vrfy(str(3e9) == "3000000000", \
'1706: str(3e9) == \"3000000000\"');
vrfy(str(1/3) == "~0", \
'1707: str(1/3) == \"~0\"');
vrfy(str(2e8) == "200000000", \
'1708: str(2e8) == \"200000000"');
vrfy(str(200e6) == "200000000", \
'1709: str(200e6) == \"200000000"');
vrfy(str(0b100111) == "39", \
'1710: str(0b100111) == \"39"');
vrfy(str(07543) == "3939", \
'1711: str(07543) == \"3939"');
vrfy(str(7543) == "7543", \
'1712: str(7543) == \"7543"');
tmp = base(10);
print '1646: tmp = base(10)';
vrfy(config("mode") == "real", \
'1647: config("mode") == "real"');
print '1713: tmp = base(10)';
vrfy(str(0x80000000) == "2147483648", \
'1648: str(0x80000000) == \"2147483648\"');
'1714: str(0x8000000) == \"2147483648\"');
vrfy(str(0xffffffff) == "4294967295", \
'1649: str(0xffffffff) == \"4294967295\"');
'1715: str(0xffffffff) == \"4294967295\"');
vrfy(str(3e9) == "3000000000", \
'1650: str(3e9) == \"3000000000\"');
'1716: str(3e9) == \"3000000000\"');
vrfy(str(1/3) == "~0.33333333333333333333", \
'1717: str(1/3) == \"~0.33333333333333333333"');
vrfy(str(2e8) == "200000000", \
'1718: str(2e8) == \"200000000"');
vrfy(str(200e6) == "200000000", \
'1719: str(200e6) == \"200000000"');
vrfy(str(0b100111) == "39", \
'1720: str(0b100111) == \"39"');
vrfy(str(07543) == "3939", \
'1721: str(07543) == \"3939"');
vrfy(str(7543) == "7543", \
'1722: str(7543) == \"7543"');
/* test base2() functionality */
vrfy(base2() == 0, '1651: base2() == 0');
vrfy(base2(0) == 0, '1652: base2(0) == 0');
vrfy(base2() == 0, '1653: base2() == 0');
vrfy(base2(16) == 0, '1654: base2(16) == 0');
vrfy(base2() == 16, '1655: base2() == 16');
vrfy(str(3e9) == "3000000000 /* 0xb2d05e00 */",
'1656: str(3e9) == "3000000000 /* 0xb2d05e00 */"');
vrfy(base2(1/3) == 16, '1657: base2(16) == 16');
vrfy(str(23209) == "23209 /* 23209 */",
'1658: str(23209) == "23209 /* 23209 */"');
vrfy(str(3/2) == "1.5 /* 3/2 */",
'1659: str(3/2) == "1.5 /* 3/2 */"');
vrfy(base() == 10, '1660: base() == 10');
vrfy(base2(0) == 1/3, '1661: base2(0) == 1/3');
vrfy(base2() == 0, '1723: base2() == 0');
vrfy(base2(0) == 0, '1724: base2(0) == 0');
vrfy(base2() == 0, '1725: base2() == 0');
print '1662: Ending mode/base test';
vrfy(base2(16) == 0, '1726: base2(16) == 0');
vrfy(base2() == 16, '1727: base2() == 16');
vrfy(str(3e9) == "3000000000 /* 0xb2d05e00 */",
'1728: str(3e9) == "3000000000 /* 0xb2d05e00 */"');
vrfy(base2(1/3) == 16, '1728: base2(16) == 16');
vrfy(base2() == 1/3, '1729: base2() == 1/3');
vrfy(str(23209) == "23209 /* 23209 */",
'1730: str(23209) == "23209 /* 23209 */"');
vrfy(str(3/2) == "1.5 /* 3/2 */",
'1731: str(3/2) == "1.5 /* 3/2 */"');
vrfy(base2(8) == 1/3, '1732: base2(8) == 1/3');
vrfy(base2() == 8, '1733: base2() == 8');
vrfy(str(23209) == "23209 /* 055251 */",
'1734: str(23209) == "23209 /* 055251 */"');
vrfy(str(3/2) == "1.5 /* 3/2 */",
'1735: str(3/2) == "1.5 /* 3/2 */"');
vrfy(base2(2) == 8, '1736: base2(2) == 8');
vrfy(base2() == 2, '1737: base2() == 2');
vrfy(str(23209) == "23209 /* 0b101101010101001 */",
'1738: str(23209) == "23209 /* 0b101101010101001 */"');
vrfy(str(3/2) == "1.5 /* 0b11/0b10 */",
'1739: str(3/2) == "1.5 /* 0b11/0b10 */"');
vrfy(base2(1e20) == 2, '1740: base2(1e20) == 2');
vrfy(base2() == 1e20, '1741: base2() == 1e20');
vrfy(str(23209) == "23209 /* 2.3209e4 */",
'1742: str(23209) == "23209 /* 2.3209e4 */"');
vrfy(str(3/2) == "1.5 /* 1.5 */",
'1743: str(3/2) == "1.5 /* 1.5 */"');
vrfy(base2(-10) == 1e20, '1744: base2(-10) == 1e20');
vrfy(base2() == -10, '1745: base2() == -10');
vrfy(str(23209) == "23209 /* 23209 */",
'1746: str(23209) == "23209 /* 23209 */"');
vrfy(str(3/2) == "1.5 /* ~2 */",
'1747: str(3/2) == "1.5 /* ~2 */"');
vrfy(base2(1000) == -10, '1748: base2(1000) == -1000');
vrfy(base2() == 1000, '1749: base2() == 1000');
vrfy(str(23209) == "23209 /* 23.209e3 */",
'1750: str(23209) == "23209 /* 23.209e3 */"');
vrfy(str(3/2) == "1.5 /* 1.5 */",
'1751: str(3/2) == "1.5 /* 1.5 */"');
vrfy(base2(10) == 1000, '1752: base2(10) == 1000');
vrfy(base2() == 10, '1753: base2() == 10');
vrfy(str(23209) == "23209 /* 23209 */",
'1754: str(23209) == "23209 /* 23209 */"');
vrfy(str(3/2) == "1.5 /* 1.5 */",
'1755: str(3/2) == "1.5 /* 1.5 */"');
vrfy(base2(0) == 10, '1756: base2(0) == 10');
vrfy(base2() == 0, '1757: base2() == 0');
vrfy(str(23209) == "23209",
'1758: str(23209) == "23209"');
vrfy(str(3/2) == "1.5",
'1759: str(3/2) == "1.5"');
vrfy(base() == 10, '1760: base() == 10');
vrfy(base2() == 0, '1761: base2() == 0');
print '1762: Ending mode/base test';
}
print '026: parsed test_mode()';
/*
* The 1700's contain tests for reading resource files. These tests are
* done inline near the bottom.
* The 1780's and 1790's contain tests for reading resource files.
*
* These tests are done inline near the bottom.
*/
@@ -3198,9 +3400,79 @@ define test_trig()
print '3400: Beginning test_trig';
/* test 3401-3407 */
tnum = test3400(1, 3401);
vrfy(tnum == 3407, '3407: tnum == 3407');
print tnum: ': Ending test_trig';
/* d2r & r2d */
vrfy(d2r(180) == pi(),
'3408: d2r(180) == pi()');
vrfy(d2r(180, 1e-100) == pi(1e-100),
'3409: d2r(180, 1e-100) == pi(1e-100)');
vrfy(r2d(pi()/2) == 90,
'3410: r2d(pi()/2) == 90');
vrfy(r2d(pi(1e-15)/2) == 14137166941154068500000/157079632679489661923,
'3411: r2d(pi(1e-15)/2) == ' +
'14137166941154068500000/157079632679489661923');
vrfy(r2d(d2r(40)) == 40,
'3412: r2d(d2r(40)) == 40');
vrfy(r2d(d2r(40,1e-90),1e-90) == 40,
'3413: r2d(d2r(40,1e-90),1e-90) == 40');
vrfy(d2r(180i) == 1i*pi(),
'3414: d2r(1808) == 1i*pi()');
vrfy(d2r(180i+90) == 1i*pi() + pi()/2,
'3415: d2r(180i+90) == 1i*pi() + pi()/2');
vrfy(r2d(d2r(40+40i)) == 40+40i,
'3416: r2d(d2r(40+40i)) == 40+40i');
vrfy(r2d(d2r(40+40i,1e-60),1e-60) == 40+40i,
'3417: r2d(d2r(40+40i,1e-60),1e-60) == 40+40i');
/* g2r & r2g */
vrfy(g2r(200) == pi(),
'3418: g2r(200) == pi()');
vrfy(g2r(200, 1e-100) == pi(1e-100),
'3419: g2r(180, 1e-100) == pi(1e-100)');
vrfy(r2g(pi()/2) == 100,
'3420: r2g(pi()/2) == 100');
vrfy(r2g(pi(1e-15)/2) == 15707963267948965000000/157079632679489661923,
'3421: r2g(pi(1e-15)/2) == ' +
'15707963267948965000000/157079632679489661923');
vrfy(r2g(g2r(40)) == 40,
'3422: r2g(g2r(40)) == 40');
vrfy(r2g(g2r(40,1e-90),1e-90) == 40,
'3423: r2g(g2r(40,1e-90),1e-90) == 40');
vrfy(g2r(200i) == 1i*pi(),
'3424: g2r(200i) == 1i*pi()');
vrfy(g2r(200i+150) == pi()*0.75 + 1i*pi(),
'3425: g2r(200i+150) == pi()*0.75 + 1i*pi()');
vrfy(r2g(g2r(40+40i)) == 40+40i,
'3426: r2g(g2r(40+40i)) == 40+40i');
vrfy(r2g(g2r(40+40i,1e-60),1e-60) == 40+40i,
'3427: r2g(g2r(40+40i,1e-60),1e-60) == 40+40i');
/* g2d & d2g */
vrfy(g2d(200) == 180,
'3428: g2d(200) == 180');
vrfy(g2d(200, 1e-100) == 180,
'3429: g2d(180, 1e-100) == 180');
vrfy(d2g(81) == 90,
'3430: d2g(81) == 90');
vrfy(d2g(pi(1e-15)/2) == 3141592653589793/1800000000000000,
'3431: d2g(pi(1e-15)/2) == 3141592653589793/1800000000000000');
vrfy(d2g(g2d(40)) == 40,
'3432: d2g(g2d(40)) == 40');
vrfy(d2g(g2d(40,1e-90),1e-90) == 40,
'3433: d2g(g2d(40,1e-90),1e-90) == 40');
vrfy(g2d(200i) == 180i,
'3434: g2d(200i) == 180i');
vrfy(g2d(200i+47) == 42.3 + 180i,
'3435: g2d(200i+47) == 42.3 + 180i');
vrfy(d2g(g2d(40+40i)) == 40+40i,
'3436: d2g(g2d(40+40i)) == 40+40i');
vrfy(d2g(g2d(40+40i,1e-90),1e-90) == 40+40i,
'3437: d2g(g2d(40+40i,1e-90),1e-90) == 40+40i');
print '3438: Ending test_trig';
}
print '051: parsed test_trig()';
@@ -7635,31 +7907,31 @@ print;
return test_mode();
print;
print '1700: Beginning read test';
print '1780: Beginning read test';
value = 0;
vrfy(value == 0, '1701: value == 0');
vrfy(value == 0, '1781: value == 0');
read "test1700";
print '1702: read "test1700";';
vrfy(value == 1, '1703: value == 1');
print '1782: read "test1700";';
vrfy(value == 1, '1783: value == 1');
read -once "test1700";
print '1704: read -once "test1700";';
vrfy(value == 1, '1705: value == 1');
print '1784: read -once "test1700";';
vrfy(value == 1, '1785: value == 1');
read "test1700.cal";
print '1706: read "test1700.cal";';
vrfy(value == 2, '1707: value == 2');
read -once "test1700.cal";
print '1708: read -once "test1700.cal";';
vrfy(value == 2, '1709: value == 2');
print '1786: read "test1700.cal";';
vrfy(value == 2, '1787: value == 2');
read -once "test1700.cal"
print '1788: read -once "test1700.cal";';
vrfy(value == 2, '1789: value == 2');
read "test1700.cal";
print '1710: read "test1700.cal";';
vrfy(value == 3, '1711: value == 3');
print '1790: read "test1700.cal";';
vrfy(value == 3, '1791: value == 3');
{++value;} read "test1700.cal";
print '1712: {++value;} read "test1700.cal";';
vrfy(value == 5, '1713: value == 5');
print '1792: {++value;} read "test1700.cal";';
vrfy(value == 5, '1793: value == 5');
{++value;} read -once "test1700.cal";
print '1714: {++value;} read -once "test1700.cal";';
vrfy(value == 6, '1715: value == 6');
print '1716: Ending read test';
print '1794: {++value;} read -once "test1700.cal";';
vrfy(value == 6, '1795: value == 6');
print '1796: Ending read test';
print;
return test_obj();

View File

@@ -1,7 +1,7 @@
#
# calcerr - error codes and messages
#
# Copyright (C) 1999-2006 Ernest Bowen
# Copyright (C) 1999-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
@@ -496,3 +496,13 @@ E_ATANH3 Invalid value for calculating atan
E_ACOTH3 Invalid value for calculating acot
E_ASECH3 Invalid value for calculating asec
E_ACSCH3 Invalid value for calculating acsc
E_D2R1 Bad epsilon for converting degrees to radians
E_D2R2 Bad first argument converting degrees to radians
E_R2D1 Bad epsilon for converting radians to degrees
E_R2D2 Bad first argument converting radians to degrees
E_G2R1 Bad epsilon for converting gradians to radians
E_G2R2 Bad first argument converting gradians to radians
E_R2G1 Bad epsilon for converting radians to gradians
E_R2G2 Bad first argument converting radians to gradians
E_D2G1 Bad first argument converting degrees to gradians
E_G2D1 Bad first argument converting gradians to degrees

View File

@@ -274,6 +274,8 @@ STATIC NAMETYPE modes[] = {
{"scientific", MODE_EXP},
{"sci", MODE_EXP},
{"exp", MODE_EXP},
{"engineering", MODE_ENG},
{"eng", MODE_ENG},
{"hexadecimal", MODE_HEX},
{"hex", MODE_HEX},
{"octal", MODE_OCTAL},

View File

@@ -145,6 +145,13 @@ CCBAN= -UUNBAN
#if 0 /* start of skip for non-Gnu makefiles */
# Unfortunately due to the complex dependency issues between
# Makefile, Makefile.ship and custom/Makefile, parallel GNU make
# is NOT recommended. Sorry.
#
.NOTPARALLEL:
##############################################################################
#-=-=-=-=-=-=-=-=- Identify the target machine, if possible -=-=-=-=-=-=-=-=-#
##############################################################################
@@ -489,7 +496,7 @@ EXT=
# The default calc versions
#
VERSION= 2.13.0.1
VERSION= 2.14.0.2
# Names of shared libraries with versions
#
@@ -1077,7 +1084,7 @@ CALCPATH= .;./cal;~/.cal;${T}${CALC_SHAREDIR};${T}${CUSTOMCALDIR}
else
CALCPATH= .;./cal;~/.cal;${T}${CALC_SHAREDIR}
endif
CALCRC= ${CALC_SHAREDIR}/startup;~/.calcrc;./.calcinit
CALCRC= ./.calcinit;~/.calcrc;${CALC_SHAREDIR}/startup
#
BLD_TYPE= calc-static-only
#

View File

@@ -145,6 +145,13 @@ CCBAN= -UUNBAN
#if 0 /* start of skip for non-Gnu makefiles */
# Unfortunately due to the complex dependency issues between
# Makefile, Makefile.ship and custom/Makefile, parallel GNU make
# is NOT recommended. Sorry.
#
.NOTPARALLEL:
##############################################################################
#-=-=-=-=-=-=-=-=- Identify the target machine, if possible -=-=-=-=-=-=-=-=-#
##############################################################################
@@ -489,7 +496,7 @@ EXT=
# The default calc versions
#
VERSION= 2.13.0.1
VERSION= 2.14.0.2
# Names of shared libraries with versions
#

3
file.c
View File

@@ -1048,6 +1048,9 @@ idprintf(FILEID id, char *fmt, int count, VALUE **vals)
case 'e':
newmode = MODE_EXP;
break;
case 'n':
newmode = MODE_ENG;
break;
case 'g':
newmode = MODE_REAL_AUTO;
break;

258
func.c
View File

@@ -2181,6 +2181,240 @@ f_cos(int count, VALUE **vals)
}
/*
* f_d2r - convert degrees to radians
*/
S_FUNC VALUE
f_d2r(int count, VALUE **vals)
{
VALUE result;
NUMBER *eps;
NUMBER *pidiv180;
/* initialize VALUE */
result.v_subtype = V_NOSUBTYPE;
/* firewall */
eps = conf->epsilon;
if (count == 2) {
if (vals[1]->v_type != V_NUM || qiszero(vals[1]->v_num))
return error_value(E_D2R1);
eps = vals[1]->v_num;
}
/* calculate argument * (pi/180) */
switch (vals[0]->v_type) {
case V_NUM:
pidiv180 = qpidiv180(eps);
result.v_num = qmul(vals[0]->v_num, pidiv180);
result.v_type = V_NUM;
qfree(pidiv180);
break;
case V_COM:
pidiv180 = qpidiv180(eps);
result.v_com = c_mulq(vals[0]->v_com, pidiv180);
result.v_type = V_COM;
qfree(pidiv180);
break;
default:
return error_value(E_D2R2);
}
return result;
}
/*
* f_r2d - convert radians to degrees
*/
S_FUNC VALUE
f_r2d(int count, VALUE **vals)
{
VALUE result;
NUMBER *eps;
NUMBER *pidiv180;
/* initialize VALUE */
result.v_subtype = V_NOSUBTYPE;
/* firewall */
eps = conf->epsilon;
if (count == 2) {
if (vals[1]->v_type != V_NUM || qiszero(vals[1]->v_num))
return error_value(E_R2D1);
eps = vals[1]->v_num;
}
/* calculate argument / (pi/180) */
switch (vals[0]->v_type) {
case V_NUM:
pidiv180 = qpidiv180(eps);
result.v_num = qqdiv(vals[0]->v_num, pidiv180);
result.v_type = V_NUM;
qfree(pidiv180);
break;
case V_COM:
pidiv180 = qpidiv180(eps);
result.v_com = c_divq(vals[0]->v_com, pidiv180);
result.v_type = V_COM;
qfree(pidiv180);
break;
default:
return error_value(E_R2D2);
}
return result;
}
/*
* f_d2r - convert gradians to radians
*/
S_FUNC VALUE
f_g2r(int count, VALUE **vals)
{
VALUE result;
NUMBER *eps;
NUMBER *pidiv200;
/* initialize VALUE */
result.v_subtype = V_NOSUBTYPE;
/* firewall */
eps = conf->epsilon;
if (count == 2) {
if (vals[1]->v_type != V_NUM || qiszero(vals[1]->v_num))
return error_value(E_G2R1);
eps = vals[1]->v_num;
}
/* calculate argument * (pi/200) */
switch (vals[0]->v_type) {
case V_NUM:
pidiv200 = qpidiv200(eps);
result.v_num = qmul(vals[0]->v_num, pidiv200);
result.v_type = V_NUM;
qfree(pidiv200);
break;
case V_COM:
pidiv200 = qpidiv200(eps);
result.v_com = c_mulq(vals[0]->v_com, pidiv200);
result.v_type = V_COM;
qfree(pidiv200);
break;
default:
return error_value(E_G2R2);
}
return result;
}
/*
* f_r2g - convert radians to gradians
*/
S_FUNC VALUE
f_r2g(int count, VALUE **vals)
{
VALUE result;
NUMBER *eps;
NUMBER *pidiv200;
/* initialize VALUE */
result.v_subtype = V_NOSUBTYPE;
/* firewall */
eps = conf->epsilon;
if (count == 2) {
if (vals[1]->v_type != V_NUM || qiszero(vals[1]->v_num))
return error_value(E_R2G1);
eps = vals[1]->v_num;
}
/* calculate argument / (pi/200) */
switch (vals[0]->v_type) {
case V_NUM:
pidiv200 = qpidiv200(eps);
result.v_num = qqdiv(vals[0]->v_num, pidiv200);
result.v_type = V_NUM;
qfree(pidiv200);
break;
case V_COM:
pidiv200 = qpidiv200(eps);
result.v_com = c_divq(vals[0]->v_com, pidiv200);
result.v_type = V_COM;
qfree(pidiv200);
break;
default:
return error_value(E_R2G2);
}
return result;
}
/*
* f_d2g - convert degrees to gradians
*
* NOTE: The epsilon (vals[1]->v_num) argument is ignored.
*/
/*ARGSUSED*/
S_FUNC VALUE
f_d2g(int UNUSED(count), VALUE **vals)
{
VALUE result;
/* initialize VALUE */
result.v_subtype = V_NOSUBTYPE;
/* NOTE: the epsilon (vals[1]->v_num) argument is ignored */
/* calculate argument * (10/9) */
switch (vals[0]->v_type) {
case V_NUM:
result.v_num = qmul(vals[0]->v_num, &_qtendivnine_);
result.v_type = V_NUM;
break;
case V_COM:
result.v_com = c_mulq(vals[0]->v_com, &_qtendivnine_);
result.v_type = V_COM;
break;
default:
return error_value(E_D2G1);
}
return result;
}
/*
* f_g2d - convert gradians to degrees
*
* NOTE: The epsilon (vals[1]->v_num) argument is ignored.
*/
/*ARGSUSED*/
S_FUNC VALUE
f_g2d(int UNUSED(count), VALUE **vals)
{
VALUE result;
/* initialize VALUE */
result.v_subtype = V_NOSUBTYPE;
/* NOTE: the epsilon (vals[1]->v_num) argument is ignored */
/* calculate argument * (9/10) */
switch (vals[0]->v_type) {
case V_NUM:
result.v_num = qmul(vals[0]->v_num, &_qninedivten_);
result.v_type = V_NUM;
break;
case V_COM:
result.v_com = c_mulq(vals[0]->v_com, &_qninedivten_);
result.v_type = V_COM;
break;
default:
return error_value(E_G2D1);
}
return result;
}
S_FUNC VALUE
f_sin(int count, VALUE **vals)
{
@@ -7839,6 +8073,9 @@ f_base(int count, NUMBER **vals)
case 16:
oldbase = math_setmode(MODE_HEX);
break;
case 1000:
oldbase = math_setmode(MODE_ENG);
break;
default:
math_error("Unsupported base");
/*NOTREACHED*/
@@ -7893,6 +8130,9 @@ f_base2(int count, NUMBER **vals)
case 16:
oldbase = math_setmode2(MODE_HEX);
break;
case 1000:
oldbase = math_setmode2(MODE_ENG);
break;
default:
math_error("Unsupported base");
/*NOTREACHED*/
@@ -7933,6 +8173,9 @@ base_value(long mode, int defval)
result = qalloc();
ztenpow(20, &result->num);
break;
case MODE_ENG:
result = itoq(1000);
break;
case MODE_HEX:
result = itoq(16);
break;
@@ -7964,6 +8207,9 @@ base_value(long mode, int defval)
result = qalloc();
ztenpow(20, &result->num);
break;
case MODE_ENG:
result = itoq(1000);
break;
case MODE_HEX:
result = itoq(16);
break;
@@ -8658,6 +8904,10 @@ STATIC CONST struct builtin builtins[] = {
"date and time as string"},
{"custom", 0, IN, 0, OP_NOP, 0, f_custom,
"custom builtin function interface"},
{"d2g", 1, 2, 0, OP_NOP, 0, f_d2g,
"convert degrees to gradians"},
{"d2r", 1, 2, 0, OP_NOP, 0, f_d2r,
"convert degrees to radians"},
{"delete", 2, 2, FA, OP_NOP, 0, f_listdelete,
"delete element from list a at position b"},
{"den", 1, 1, 0, OP_DENOMINATOR, qden, 0,
@@ -8768,6 +9018,10 @@ STATIC CONST struct builtin builtins[] = {
"return the file position"},
{"frac", 1, 1, 0, OP_FRAC, qfrac, 0,
"fractional part of value"},
{"g2d", 1, 2, 0, OP_NOP, 0, f_g2d,
"convert gradians to degrees"},
{"g2r", 1, 2, 0, OP_NOP, 0, f_g2r,
"convert gradians to radians"},
{"gcd", 1, IN, 0, OP_NOP, f_gcd, 0,
"greatest common divisor"},
{"gcdrem", 2, 2, 0, OP_NOP, qgcdrem, 0,
@@ -9015,6 +9269,10 @@ STATIC CONST struct builtin builtins[] = {
{"quomod", 4, 5, FA, OP_NOP, 0, f_quomod,
"set c and d to quotient and remainder of a\n"
"\t\t\tdivided by b"},
{"r2d", 1, 2, 0, OP_NOP, 0, f_r2d,
"convert radians to degrees"},
{"r2g", 1, 2, 0, OP_NOP, 0, f_r2g,
"convert radians to gradians"},
{"rand", 0, 2, 0, OP_NOP, f_rand, 0,
"additive 55 random number [0,2^64), [0,a), or [a,b)"},
{"randbit", 0, 1, 0, OP_NOP, f_randbit, 0,

View File

@@ -356,7 +356,7 @@ BLT_HELP_FILES= ${BLT_HELP_FILES_3} ${BLT_HELP_FILES_5} \
#
# Please use:
#
# make detail_help_list
# make clobber >/dev/null && make detail_help_list
#
# to keep this list in nice sorted order.
#
@@ -364,32 +364,32 @@ DETAIL_HELP= abs access acos acosh acot acoth acsc acsch address agd \
append appr arg argv arrow asec asech asin asinh assign atan atan2 \
atanh avg base base2 bernoulli bit blk blkcpy blkfree blocks bround \
btrunc calc_tty calclevel calcpath catalan ceil cfappr cfsim char \
cmdbuf cmp comb conj cos cosh cot coth count cp csc csch ctime delete \
den dereference det digit digits display dp epsilon errcount errmax \
errno error estr euler eval exp fact factor fclose fcnt feof ferror \
fflush fgetc fgetfield fgetfile fgetline fgets fgetstr fib files floor \
fopen forall fpathopen fprintf fputc fputs fputstr frac free \
freebernoulli freeeuler freeglobals freeredc freestatics frem freopen \
fscan fscanf fseek fsize ftell gcd gcdrem gd getenv hash head highbit \
hmean hnrmod hypot ilog ilog10 ilog2 im indices inputlevel insert int \
inverse iroot isalnum isalpha isassoc isatty isblk iscntrl isconfig \
isdefined isdigit iserror iseven isfile isgraph ishash isident isint \
islist islower ismat ismult isnull isnum isobj isobjtype isodd isprime \
isprint isptr ispunct isqrt isrand israndom isreal isrel issimple \
isspace issq isstr istype isupper isxdigit jacobi join lcm lcmfact \
lfactor ln log lowbit ltol makelist matdim matfill matmax matmin \
matsum mattrace mattrans max memsize meq min minv mmin mne mod modify \
name near newerror nextcand nextprime norm null num oldvalue ord param \
perm pfact pi pix places pmod polar poly pop popcnt pound power \
prevcand prevprime printf prompt protect ptest push putenv questions \
quo quomod rand randbit random randombit randperm rcin rcmul rcout \
rcpow rcsq re remove reverse rewind rm root round rsearch runtime \
saveval scale scan scanf search sec sech seed segment select sgn sha1 \
sin sinh size sizeof sleep sort sqrt srand srandom ssq stoponerror str \
strcasecmp strcat strcmp strcpy strerror strlen strncasecmp strncmp \
strncpy strpos strprintf strscan strscanf strtolower strtoupper substr \
sum swap system systime tail tan tanh test time trunc usertime version \
xor
cmdbuf cmp comb conj cos cosh cot coth count cp csc csch ctime d2g d2r \
delete den dereference det digit digits display dp epsilon errcount \
errmax errno error estr euler eval exp fact factor fclose fcnt feof \
ferror fflush fgetc fgetfield fgetfile fgetline fgets fgetstr fib \
files floor fopen forall fpathopen fprintf fputc fputs fputstr frac \
free freebernoulli freeeuler freeglobals freeredc freestatics frem \
freopen fscan fscanf fseek fsize ftell g2d g2r gcd gcdrem gd \
getenv hash head highbit hmean hnrmod hypot ilog ilog10 ilog2 im \
indices inputlevel insert int inverse iroot isalnum isalpha isassoc \
isatty isblk iscntrl isconfig isdefined isdigit iserror iseven isfile \
isgraph ishash isident isint islist islower ismat ismult isnull isnum \
isobj isobjtype isodd isprime isprint isptr ispunct isqrt isrand \
israndom isreal isrel issimple isspace issq isstr istype isupper \
isxdigit jacobi join lcm lcmfact lfactor ln log lowbit ltol makelist \
matdim matfill matmax matmin matsum mattrace mattrans max memsize meq \
min minv mmin mne mod modify name near newerror nextcand nextprime \
norm null num oldvalue ord param perm pfact pi pix places pmod polar \
poly pop popcnt pound power prevcand prevprime printf prompt protect \
ptest push putenv quo quomod r2d r2g rand randbit random randombit \
randperm rcin rcmul rcout rcpow rcsq re remove reverse rewind rm root \
round rsearch runtime saveval scale scan scanf search sec sech seed \
segment select sgn sha1 sin sinh size sizeof sleep sort sqrt srand \
srandom ssq stoponerror str strcasecmp strcat strcmp strcpy strerror \
strlen strncasecmp strncmp strncpy strpos strprintf strscan strscanf \
strtolower strtoupper substr sum swap system systime tail tan tanh \
test time trunc usertime version xor
# This list is of files that are clones of DETAIL_HELP files. They are
# built from DETAIL_HELP files.
@@ -730,7 +730,7 @@ distlist: ${DISTLIST}
if [ X"$$i" != X"/dev/null" ]; then \
echo help/$$i; \
fi; \
done | LANG=C ${SORT}
done | fgrep -v '.bak' | LANG=C ${SORT}
distdir:
${Q} echo help

View File

@@ -44,6 +44,9 @@ DESCRIPTION
"sci"
"exp"
1000 "engineering" base 10 notation with exponent
"eng" multiple of 3
For convenience, any non-integer value is assumed to mean base 10
fractions and any integer >= 2^64 is assumed to mean base 10
scientific notation.
@@ -76,7 +79,7 @@ LINK LIBRARY
int math_setmode(int newmode)
NOTE: newmode must be one of MODE_DEFAULT, MODE_FRAC, MODE_INT,
MODE_REAL, MODE_EXP, MODE_HEX, MODE_OCTAL, MODE_BINARY
MODE_REAL, MODE_EXP, MODE_ENG, MODE_HEX, MODE_OCTAL, MODE_BINARY
SEE ALSO
base2, config, str

View File

@@ -50,6 +50,9 @@ DESCRIPTION
"sci"
"exp"
1000 "engineering" base 10 notation with exponent
"eng" multiple of 3
0 "off" disable double base output
For convenience, any non-integer non-zero value is assumed to mean
@@ -87,7 +90,7 @@ LINK LIBRARY
int math_setmode2(int newmode)
NOTE: newmode must be one of MODE_DEFAULT, MODE_FRAC, MODE_INT,
MODE_REAL, MODE_EXP, MODE_HEX, MODE_OCTAL, MODE_BINARY,
MODE_REAL, MODE_EXP, MODE_ENG, MODE_HEX, MODE_OCTAL, MODE_BINARY,
MODE2_OFF
SEE ALSO

View File

@@ -165,8 +165,8 @@ DESCRIPTION
config("display", int)
The "display" parameter specifies the maximum number of digits after
the decimal point to be printed in real or exponential mode in
normal unformatted printing (print, strprint, fprint) or in
the decimal point to be printed in real, exponential or engineering
mode in normal unformatted printing (print, strprint, fprint) or in
formatted printing (printf, strprintf, fprintf) when precision is not
specified. The initial value for oldstd is 20, for newstd 10.
The parameter may be changed to the value d by either
@@ -234,6 +234,9 @@ DESCRIPTION
"sci"
"exp"
"engineering" base 10 notation with exponent base(10e6)
"eng" multiple of 3
Where multiple strings are given, the first string listed is what
config("mode") will return.

55
help/d2g Normal file
View File

@@ -0,0 +1,55 @@
NAME
d2g - convert degrees to gradians
SYNOPSIS
d2g(x [,eps])
TYPES
x number (real or complex)
eps nonzero real, defaults to epsilon()
return number
DESCRIPTION
Given x degrees, return the equivalent number of gradians.
The eps argument is ignored.
EXAMPLE
; print d2g(45), d2g(180), d2g(30)
50 200 ~33.33333333333333333333
; print d2g(3i+2)
~2.22222222222222222222+~3.33333333333333333333i
LIMITS
none
LINK LIBRARY
none
SEE ALSO
d2r, r2d, g2r, r2g, g2d,
sin, cos, tan, sec, csc, cot, epsilon
## 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/09/07 12:04:28
## 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/

59
help/d2r Normal file
View File

@@ -0,0 +1,59 @@
NAME
d2r - convert degrees to radians
SYNOPSIS
d2r(x [,eps])
TYPES
x number (real or complex)
eps nonzero real, defaults to epsilon()
return number
DESCRIPTION
Given x degrees, return the equivalent number of radians.
The eps controls the precision of the calculated internal
constant pi / 180.
EXAMPLE
; print d2r(45), d2r(180), d2r(30)
~0.78539816339744830962 3.14159265358979323846 ~0.52359877559829887308
; print d2r(3i+2)
~0.03490658503988659154+~0.05235987755982988731i
; print sin(d2r(30)), cos(d2r(60)), tan(d2r(45))
0.5 0.5 1
LIMITS
eps > 0
LINK LIBRARY
NUMBER *qpidiv180(NUMBER *eps)
SEE ALSO
r2d, g2r, r2g, d2g, g2d,
sin, cos, tan, sec, csc, cot, epsilon
## 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/09/07 12:04:28
## 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/

55
help/g2d Normal file
View File

@@ -0,0 +1,55 @@
NAME
g2d - convert gradians to degrees
SYNOPSIS
g2d(x [,eps])
TYPES
x number (real or complex)
eps nonzero real, defaults to epsilon()
return number
DESCRIPTION
Given x gradians, return the equivalent number of degrees.
The eps argument is ignored.
EXAMPLE
; print g2d(50), g2d(200), g2d(30)
45 180 27
; print g2d(3i+2)
1.8+2.7i
LIMITS
none
LINK LIBRARY
none
SEE ALSO
d2r, r2d, g2r, r2g, d2g,
sin, cos, tan, sec, csc, cot, epsilon
## 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/09/07 12:04:28
## 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/

59
help/g2r Normal file
View File

@@ -0,0 +1,59 @@
NAME
g2r - convert gradians to radians
SYNOPSIS
g2r(x [,eps])
TYPES
x number (real or complex)
eps nonzero real, defaults to epsilon()
return number
DESCRIPTION
Given x gradians, return the equivalent number of radians.
The eps controls the precision of the calculated internal
constant pi / 200.
EXAMPLE
; print g2r(50), g2r(200), g2r(50)
~0.78539816339744830962 3.14159265358979323846 ~0.78539816339744830962
; print g2r(3i+2)
~0.03141592653589793238+~0.04712388980384689858i
; print sin(g2r(100/3)), cos(g2r(200/3)), tan(g2r(50))
0.5 0.5 1
LIMITS
eps > 0
LINK LIBRARY
NUMBER *qpidiv200(NUMBER *eps)
SEE ALSO
d2r, r2d, r2g, d2g, g2d,
sin, cos, tan, sec, csc, cot, epsilon
## 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/09/07 12:04:28
## 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/

57
help/r2d Normal file
View File

@@ -0,0 +1,57 @@
NAME
r2d - convert radians to degrees
SYNOPSIS
r2d(x [,eps])
TYPES
x number (real or complex)
eps nonzero real, defaults to epsilon()
return number
DESCRIPTION
Given x radians, return the equivalent number of degrees.
The eps controls the precision of the calculated internal
constant pi / 180.
EXAMPLE
; pi = pi(1e-20)
; print r2d(pi), r2d(pi/3), r2d(2*pi)
180 60 360
; print r2d(pi+4i), r2d(pi/3 + 1i*pi), r2d(pi/5 + 5i*pi)
180+~229.18311805232928350739i 60+180, 36+900i
LIMITS
eps > 0
LINK LIBRARY
NUMBER *qpidiv180(NUMBER *eps)
SEE ALSO
d2r, g2r, r2g, d2g, g2d,
sin, cos, tan, sec, csc, cot, epsilon
## 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/09/07 12:04:28
## 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/

57
help/r2g Normal file
View File

@@ -0,0 +1,57 @@
NAME
r2g - convert radians to gradians
SYNOPSIS
r2g(x [,eps])
TYPES
x number (real or complex)
eps nonzero real, defaults to epsilon()
return number
DESCRIPTION
Given x radians, return the equivalent number of gradians.
The eps controls the precision of the calculated internal
constant pi / 200.
EXAMPLE
; pi = pi()
; print r2g(pi), r2g(pi/3), r2g(2*pi)
200 ~66.66666666666666666667 400
; print r2g(pi+4i), r2g(pi/4 + 1i*pi), r2g(pi/5 + 5i*pi)
200+~254.64790894703253723043i 50+200i 40+1000i
LIMITS
eps > 0
LINK LIBRARY
NUMBER *qpidiv200(NUMBER *eps)
SEE ALSO
d2r, r2d, g2r, d2g, g2d,
sin, cos, tan, sec, csc, cot, epsilon
## 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/09/07 12:04:28
## File existed as early as: 2021
##
## chongo <was here> /\oo/\ http://www.isthe.com/chongo/
## Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/

View File

@@ -228,7 +228,7 @@ Unexpected
1<<8/2
evalues to 128, not 16, because <<8 is performed before the /2.
evaluates to 128, not 16, because <<8 is performed before the /2.
&A[0] and A are different things in calc
@@ -529,6 +529,34 @@ Unexpected
; help fclose
trig functions use only radians
===============================
Some might be surprised to discover that all of the trigonometric in calc:
sin, cos, tan, sec, csc, cot
asin, acos, atan, asec, acsc, acot
work in only radians.
Calc as builtin functions to convert between degrees, radians and gradians:
d2r(deg) - given degrees returns radians
g2r(grad) - given gradians returns radians
r2d(rad) - given radians returns degrees
g2d(grad) - given gradians returns degrees
r2g(rad) - given radians returns gradians
d2g(deg) - given degrees returns gradians
For example, if you want to take the sin of 30 degrees, convert
the 30 degrees into radians and pass the result to sin():
; print sin(d2r(30))
0.5
## Copyright (C) 1999-2007,2014,2017,2021 Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under

31
qio.c
View File

@@ -247,6 +247,37 @@ qprintnum(NUMBER *q, int outmode, LEN outdigits)
PRINTF1("e%ld", exp);
break;
case MODE_ENG:
if (qiszero(q)) {
PUTCHAR('0');
return;
}
tmpval = *q;
tmpval.num.sign = 0;
exp = qilog10(&tmpval);
if (exp == 0) { /* in range to output as real */
qprintnum(q, MODE_REAL, outdigits);
return;
}
tmpval.num = _one_;
tmpval.den = _one_;
if (exp > 0) {
exp -= exp % 3;
ztenpow(exp, &tmpval.den);
} else {
long remainder = exp % 3;
if (remainder)
exp -= remainder + 3;
ztenpow(-exp, &tmpval.num);
}
q = qmul(q, &tmpval);
zfree(tmpval.num);
zfree(tmpval.den);
qprintnum(q, MODE_REAL, outdigits);
qfree(q);
if (exp) PRINTF1("e%ld", exp);
break;
case MODE_REAL_AUTO:
{
const int P = conf->outdigits ? conf->outdigits : 1;

View File

@@ -44,9 +44,12 @@ NUMBER _qnegone_ = { { _oneval_, 1, 1 }, { _oneval_, 1, 0 }, 1, NULL };
NUMBER _qonehalf_ = { { _oneval_, 1, 0 }, { _twoval_, 1, 0 }, 1, NULL };
NUMBER _qneghalf_ = { { _oneval_, 1, 1 }, { _twoval_, 1, 0 }, 1, NULL };
NUMBER _qonesqbase_ = { { _oneval_, 1, 0 }, { _sqbaseval_, 2, 0 }, 1, NULL };
NUMBER _qtendivnine_ = { { _tenval_, 1, 0 }, { _nineval_, 1, 0 }, 1, NULL };
NUMBER _qninedivten_ = { { _nineval_, 1, 0 }, { _tenval_, 1, 0 }, 1, NULL };
NUMBER * initnumbs[INITCONSTCOUNT] = {&_qzero_, &_qone_, &_qtwo_, &_qthree_,
&_qfour_, &_qten_, &_qnegone_, &_qonehalf_, &_qneghalf_};
&_qfour_, &_qten_, &_qnegone_, &_qonehalf_, &_qneghalf_,
&_qonesqbase_, &_qtendivnine_, &_qninedivten_ };
/*

View File

@@ -1,7 +1,7 @@
/*
* qmath - declarations for extended precision rational arithmetic
*
* Copyright (C) 1999-2007,2014 David I. Bell
* Copyright (C) 1999-2007,2014,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
@@ -35,7 +35,7 @@
#endif
#define INITCONSTCOUNT 9 /* number of initnumbs[] pre-defined constants */
#define INITCONSTCOUNT 12 /* number of initnumbs[] pre-defined constants */
/*
* Rational arithmetic definitions.
@@ -213,6 +213,8 @@ E_FUNC NUMBER *qacsch(NUMBER *q, NUMBER *epsilon);
E_FUNC NUMBER *qacoth(NUMBER *q, NUMBER *epsilon);
E_FUNC NUMBER *qlegtoleg(NUMBER *q, NUMBER *epsilon, BOOL wantneg);
E_FUNC NUMBER *qpi(NUMBER *epsilon);
E_FUNC NUMBER *qpidiv180(NUMBER *epsilon);
E_FUNC NUMBER *qpidiv200(NUMBER *epsilon);
E_FUNC NUMBER *qcatalan(NUMBER *);
E_FUNC NUMBER *qbern(ZVALUE z);
E_FUNC void qfreebern(void);
@@ -273,6 +275,7 @@ static inline NUMBER* qlink(NUMBER* q) { if(q) { (q)->links++; } return q; }
*/
EXTERN NUMBER _qzero_, _qone_, _qnegone_, _qonehalf_, _qneghalf_, _qonesqbase_;
EXTERN NUMBER _qtwo_, _qthree_, _qfour_, _qten_;
EXTERN NUMBER _qtendivnine_, _qninedivten_;
EXTERN NUMBER * initnumbs[];

147
qtrans.c
View File

@@ -47,7 +47,40 @@ NUMBER _qlge_ = { { _qlgenum_, 1, 0 }, { _qlgeden_, 1, 0 }, 1, NULL };
STATIC NUMBER *ln_10 = NULL;
STATIC NUMBER *ln_10_epsilon = NULL;
STATIC NUMBER *pivalue[2];
/*
* cache pi
*
* pivalue[LAST_PI_EPSILON] - last epsilon used to calculate pi
* pivalue[LAST_PI_VALUE] - last calculated pi
* given pivalue[LAST_PI_EPSILON] epsilon
* pivalue[LAST_PI_DIV_180_EPSILON] - last epsilon used to calculate pi/180
* pivalue[LAST_PI_DIV_180_VALUE] - last calculated pi/180 given
* pivalue[LAST_PI_DIV_180_EPSILON] epsilon
* pivalue[LAST_PI_DIV_200_EPSILON] - last epsilon used to calculate pi/200
* pivalue[LAST_PI_DIV_200_VALUE] - last calculated pi/200 given
* pivalue[LAST_PI_DIV_200_EPSILON] epsilon
*/
enum pi_cache {
LAST_PI_EPSILON = 0,
LAST_PI_VALUE,
LAST_PI_DIV_180_EPSILON,
LAST_PI_DIV_180_VALUE,
LAST_PI_DIV_200_EPSILON,
LAST_PI_DIV_200_VALUE,
PI_CACHE_LEN /* must be last */
};
STATIC NUMBER *pivalue[PI_CACHE_LEN] = {
NULL, /* LAST_PI_EPSILON */
NULL, /* LAST_PI_VALUE */
NULL, /* LAST_PI_DIV_180_EPSILON */
NULL, /* LAST_PI_DIV_180_VALUE */
NULL, /* LAST_PI_DIV_200_EPSILON */
NULL, /* LAST_PI_DIV_200_VALUE */
};
/*
* other static function decls
*/
STATIC NUMBER *qexprel(NUMBER *q, long bitnum);
/*
@@ -725,16 +758,25 @@ qpi(NUMBER *epsilon)
long bits; /* needed number of bits of precision */
long t;
/* firewall */
if (qiszero(epsilon)) {
math_error("zero epsilon value for pi");
/*NOTREACHED*/
}
if (epsilon == pivalue[0])
return qlink(pivalue[1]);
if (pivalue[0]) {
qfree(pivalue[0]);
qfree(pivalue[1]);
/* use pi cache if epsilon marches, else flush if needed */
if (pivalue[LAST_PI_EPSILON] != NULL &&
pivalue[LAST_PI_VALUE] != NULL &&
epsilon == pivalue[LAST_PI_EPSILON]) {
return qlink(pivalue[LAST_PI_VALUE]);
}
if (pivalue[LAST_PI_EPSILON] != NULL) {
qfree(pivalue[LAST_PI_EPSILON]);
}
if (pivalue[LAST_PI_VALUE] != NULL) {
qfree(pivalue[LAST_PI_VALUE]);
}
bits = -qilog2(epsilon) + 4;
if (bits < 4)
bits = 4;
@@ -768,11 +810,100 @@ qpi(NUMBER *epsilon)
zfree(sum);
r = qmappr(t1, epsilon, 24L);
qfree(t1);
pivalue[0] = qlink(epsilon);
pivalue[1] = qlink(r);
pivalue[LAST_PI_EPSILON] = qlink(epsilon);
pivalue[LAST_PI_VALUE] = qlink(r);
return r;
}
/*
* qpidiv180 - calcucalte pi / 180
*
* This function returns pi/180 as used to covert between radians and degrees.
*/
NUMBER *
qpidiv180(NUMBER *epsilon)
{
NUMBER *pi, *pidiv180;
/* firewall */
if (qiszero(epsilon)) {
math_error("zero epsilon value for qpidiv180");
/*NOTREACHED*/
}
/* use pi/180 cache if epsilon marches, else flush if needed */
if (pivalue[LAST_PI_DIV_180_EPSILON] != NULL &&
pivalue[LAST_PI_DIV_180_VALUE] != NULL &&
epsilon == pivalue[LAST_PI_DIV_180_EPSILON]) {
return qlink(pivalue[LAST_PI_DIV_180_VALUE]);
}
if (pivalue[LAST_PI_DIV_180_EPSILON] != NULL) {
qfree(pivalue[LAST_PI_DIV_180_EPSILON]);
}
if (pivalue[LAST_PI_DIV_180_VALUE] != NULL) {
qfree(pivalue[LAST_PI_DIV_180_VALUE]);
}
/* let qpi() returned cached pi or calculate new as needed */
pi = qpi(epsilon);
/* calculate pi/180 */
pidiv180 = qdivi(pi, 180);
/* cache epsilon and pi/180 */
pivalue[LAST_PI_DIV_180_EPSILON] = qlink(epsilon);
pivalue[LAST_PI_DIV_180_VALUE] = qlink(pidiv180);
/* return pi/180 */
return pidiv180;
}
/*
* qpidiv200 - calcucalte pi / 200
*
* This function returns pi/200 as used to covert between radians and gradians.
*/
NUMBER *
qpidiv200(NUMBER *epsilon)
{
NUMBER *pi, *pidiv200;
/* firewall */
if (qiszero(epsilon)) {
math_error("zero epsilon value for qpidiv200");
/*NOTREACHED*/
}
/* use pi/200 cache if epsilon marches, else flush if needed */
if (pivalue[LAST_PI_DIV_200_EPSILON] != NULL &&
pivalue[LAST_PI_DIV_200_VALUE] != NULL &&
epsilon == pivalue[LAST_PI_DIV_200_EPSILON]) {
return qlink(pivalue[LAST_PI_DIV_200_VALUE]);
}
if (pivalue[LAST_PI_DIV_200_EPSILON] != NULL) {
qfree(pivalue[LAST_PI_DIV_200_EPSILON]);
}
if (pivalue[LAST_PI_DIV_200_VALUE] != NULL) {
qfree(pivalue[LAST_PI_DIV_200_VALUE]);
}
/* let qpi() returned cached pi or calculate new as needed */
pi = qpi(epsilon);
/* calculate pi/200 */
pidiv200 = qdivi(pi, 200);
/* cache epsilon and pi/200 */
pivalue[LAST_PI_DIV_200_EPSILON] = qlink(epsilon);
pivalue[LAST_PI_DIV_200_VALUE] = qlink(pidiv200);
/* return pi/200 */
return pidiv200;
}
/*
* Calculate the exponential function to the nearest or next to nearest
* multiple of the positive number epsilon.

View File

@@ -52,9 +52,9 @@ static char *program;
#define MAJOR_VER 2 /* major library version */
#define MINOR_VER 13 /* minor library version */
#define MINOR_VER 14 /* minor library version */
#define MAJOR_PATCH 0 /* major software version level */
#define MINOR_PATCH 1 /* minor software version level */
#define MINOR_PATCH 2 /* minor software version level */
/*

View File

@@ -49,7 +49,7 @@ NROFF_ARG=
MANMAKE=
MANMODE=
CALCPATH=./cal
CALCRC='/lib/calc/startup:~/.calcrc:./.calcinit'
CALCRC='./.calcinit:~/.calcrc:/lib/calc/startup'
USE_READLINE=-DUSE_READLINE
READLINE_LIB=
READLINE_INCLUDE=

View File

@@ -594,7 +594,8 @@ E_FUNC void zredcpower(REDC *rp, ZVALUE z1, ZVALUE z2, ZVALUE *res);
#define MODE_OCTAL 6
#define MODE_BINARY 7
#define MODE_REAL_AUTO 8
#define MODE_MAX 8
#define MODE_ENG 9
#define MODE_MAX 9
#define MODE2_OFF (MODE_MAX+1)
/* XXX - perhaps we need the MODE_REAL_AUTO vs MODE_REAL as a config mode? */