add config("triground") to trigonometric function rounding

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

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

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

    exp, polar

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

    config("triground", 24)

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

    config("triground")

Improved "SEE ALSO" for the hyperbolic function help files.
This commit is contained in:
Landon Curt Noll
2023-10-03 20:31:13 -07:00
parent fec9712b9a
commit db582d6e34
22 changed files with 177 additions and 63 deletions

33
CHANGES
View File

@@ -204,6 +204,8 @@ The following are the changes from calc version 2.14.3.5 to date:
and made consistent, where applicable, across the trigonometric and made consistent, where applicable, across the trigonometric
help files. Documented libcalc functions in the SEE ALSO sections. help files. Documented libcalc functions in the SEE ALSO sections.
Improved "SEE ALSO" for the hyperbolic function help files.
Expanded the calc regression test suite test 34dd to test various Expanded the calc regression test suite test 34dd to test various
real and complex values for trigonometric functions. real and complex values for trigonometric functions.
@@ -386,6 +388,37 @@ The following are the changes from calc version 2.14.3.4 to 2.14.3.5:
The libcalc shared library is now linked with libcustcalc. The libcalc shared library is now linked with libcustcalc.
The config("triground") controls rounding for the following
trigonometric and hyperbolic functions:
sin, cos, tan, cot, sec, csc
asin, acos, atan, acot, asec, acsc
versin, coversin, vercos, covercos
aversin, acoversin, avercos, acovercos
haversin, hacoversin, havercos, hacovercos
ahaversin, hacoversin, havercos, ahacovercos
exsec, aexsec, excsc, aexcsc
crd, acrd
cas, cis
sinh, cosh, tanh, coth, sech, csch
asinh, acosh, atanh, acoth, asech, acsch
In addition to taking a complex root (such as via the power
function on a complex value), "triground" is used for:
exp, polar
For the above mentioned functions, the rounding mode used to
round the result to the nearest epsilon value is controlled by,
and defaults to:
config("triground", 24)
As with other config options, the call returns the previous mode,
without a 2nd argument, returns the current mode without changing it:
config("triground")
The following are the changes from calc version 2.14.3.0 to 2.14.3.4: The following are the changes from calc version 2.14.3.0 to 2.14.3.4:

View File

@@ -5251,6 +5251,7 @@ qtrans.o: banned.h
qtrans.o: bool.h qtrans.o: bool.h
qtrans.o: byteswap.h qtrans.o: byteswap.h
qtrans.o: charbit.h qtrans.o: charbit.h
qtrans.o: config.h
qtrans.o: decl.h qtrans.o: decl.h
qtrans.o: endian_calc.h qtrans.o: endian_calc.h
qtrans.o: errsym.h qtrans.o: errsym.h
@@ -5264,6 +5265,7 @@ qtrans.o: have_stdbool.h
qtrans.o: have_stdlib.h qtrans.o: have_stdlib.h
qtrans.o: have_string.h qtrans.o: have_string.h
qtrans.o: longbits.h qtrans.o: longbits.h
qtrans.o: nametype.h
qtrans.o: qmath.h qtrans.o: qmath.h
qtrans.o: qtrans.c qtrans.o: qtrans.c
qtrans.o: zmath.h qtrans.o: zmath.h

View File

@@ -391,7 +391,7 @@ c_root(COMPLEX *c, NUMBER *q, NUMBER *epsilon)
if (cisone(c) || qisone(q)) if (cisone(c) || qisone(q))
return clink(c); return clink(c);
if (qistwo(q)) if (qistwo(q))
return c_sqrt(c, epsilon, 24L); return c_sqrt(c, epsilon, conf->triground);
if (cisreal(c) && !qisneg(c->real)) { if (cisreal(c) && !qisneg(c->real)) {
tmp1 = qroot(c->real, q, epsilon); tmp1 = qroot(c->real, q, epsilon);
if (tmp1 == NULL) if (tmp1 == NULL)
@@ -482,13 +482,13 @@ c_exp(COMPLEX *c, NUMBER *epsilon)
qfree(cos); qfree(cos);
r = comalloc(); r = comalloc();
qfree(r->real); qfree(r->real);
r->real = qmappr(tmp2, epsilon, 24L); r->real = qmappr(tmp2, epsilon, conf->triground);
qfree(tmp2); qfree(tmp2);
tmp2 = qmul(tmp1, sin); tmp2 = qmul(tmp1, sin);
qfree(tmp1); qfree(tmp1);
qfree(sin); qfree(sin);
qfree(r->imag); qfree(r->imag);
r->imag = qmappr(tmp2, epsilon, 24L); r->imag = qmappr(tmp2, epsilon, conf->triground);
qfree(tmp2); qfree(tmp2);
return r; return r;
} }
@@ -687,9 +687,9 @@ c_cos(COMPLEX *c, NUMBER *epsilon)
comfree(ctmp3); comfree(ctmp3);
r = comalloc(); r = comalloc();
qfree(r->real); qfree(r->real);
r->real = qmappr(ctmp1->real, epsilon, 24L); r->real = qmappr(ctmp1->real, epsilon, conf->triground);
qfree(r->imag); qfree(r->imag);
r->imag = qmappr(ctmp1->imag, epsilon, 24L); r->imag = qmappr(ctmp1->imag, epsilon, conf->triground);
comfree(ctmp1); comfree(ctmp1);
return r; return r;
} }
@@ -742,11 +742,11 @@ c_sin(COMPLEX *c, NUMBER *epsilon)
r = comalloc(); r = comalloc();
qtmp = neg ? qlink(ctmp1->imag) : qneg(ctmp1->imag); qtmp = neg ? qlink(ctmp1->imag) : qneg(ctmp1->imag);
qfree(r->real); qfree(r->real);
r->real = qmappr(qtmp, epsilon, 24L); r->real = qmappr(qtmp, epsilon, conf->triground);
qfree(qtmp); qfree(qtmp);
qtmp = neg ? qneg(ctmp1->real) : qlink(ctmp1->real); qtmp = neg ? qneg(ctmp1->real) : qlink(ctmp1->real);
qfree(r->imag); qfree(r->imag);
r->imag = qmappr(qtmp, epsilon, 24L); r->imag = qmappr(qtmp, epsilon, conf->triground);
qfree(qtmp); qfree(qtmp);
comfree(ctmp1); comfree(ctmp1);
return r; return r;
@@ -819,7 +819,7 @@ c_acos(COMPLEX *c, NUMBER *epsilon)
tmp1 = c_square(c); tmp1 = c_square(c);
tmp2 = c_sub(&_cone_, tmp1); tmp2 = c_sub(&_cone_, tmp1);
comfree(tmp1); comfree(tmp1);
tmp1 = c_sqrt(tmp2, epsilon, 24); tmp1 = c_sqrt(tmp2, epsilon, conf->triground);
comfree(tmp2); comfree(tmp2);
tmp2 = c_mul(&_conei_, tmp1); tmp2 = c_mul(&_conei_, tmp1);
comfree(tmp1); comfree(tmp1);
@@ -844,7 +844,7 @@ c_asinh(COMPLEX *c, NUMBER *epsilon)
tmp2 = c_square(tmp1); tmp2 = c_square(tmp1);
tmp3 = c_add(&_cone_, tmp2); tmp3 = c_add(&_cone_, tmp2);
comfree(tmp2); comfree(tmp2);
tmp2 = c_sqrt(tmp3, epsilon, 24); tmp2 = c_sqrt(tmp3, epsilon, conf->triground);
comfree(tmp3); comfree(tmp3);
tmp3 = c_add(tmp2, tmp1); tmp3 = c_add(tmp2, tmp1);
comfree(tmp1); comfree(tmp1);
@@ -868,7 +868,7 @@ c_acosh(COMPLEX *c, NUMBER *epsilon)
tmp1 = c_square(c); tmp1 = c_square(c);
tmp2 = c_sub(tmp1, &_cone_); tmp2 = c_sub(tmp1, &_cone_);
comfree(tmp1); comfree(tmp1);
tmp1 = c_sqrt(tmp2, epsilon, 24); tmp1 = c_sqrt(tmp2, epsilon, conf->triground);
comfree(tmp2); comfree(tmp2);
tmp2 = c_add(c, tmp1); tmp2 = c_add(c, tmp1);
comfree(tmp1); comfree(tmp1);
@@ -1473,12 +1473,12 @@ c_polar(NUMBER *q1, NUMBER *q2, NUMBER *epsilon)
tmp = qmul(q1, cos); tmp = qmul(q1, cos);
qfree(cos); qfree(cos);
qfree(r->real); qfree(r->real);
r->real = qmappr(tmp, epsilon, 24L); r->real = qmappr(tmp, epsilon, conf->triground);
qfree(tmp); qfree(tmp);
tmp = qmul(q1, sin); tmp = qmul(q1, sin);
qfree(sin); qfree(sin);
qfree(r->imag); qfree(r->imag);
r->imag = qmappr(tmp, epsilon, 24L); r->imag = qmappr(tmp, epsilon, conf->triground);
qfree(tmp); qfree(tmp);
return r; return r;
} }

View File

@@ -106,6 +106,7 @@ NAMETYPE configs[] = {
{"cfsim", CONFIG_CFSIM}, {"cfsim", CONFIG_CFSIM},
{"outround", CONFIG_OUTROUND}, {"outround", CONFIG_OUTROUND},
{"round", CONFIG_ROUND}, {"round", CONFIG_ROUND},
{"triground", CONFIG_TRIGROUND},
{"leadzero", CONFIG_LEADZERO}, {"leadzero", CONFIG_LEADZERO},
{"fullzero", CONFIG_FULLZERO}, {"fullzero", CONFIG_FULLZERO},
{"maxscan", CONFIG_MAXSCAN}, {"maxscan", CONFIG_MAXSCAN},
@@ -167,6 +168,7 @@ CONFIG oldstd = { /* backward compatible standard configuration */
8, /* cfsim() default rounding mode */ 8, /* cfsim() default rounding mode */
2, /* output default rounding mode */ 2, /* output default rounding mode */
24, /* round()/bround() default rounding mode */ 24, /* round()/bround() default rounding mode */
24, /* trigonometric and hyperbolic function rounding mode */
false, /* true ==> print leading 0 before decimal pt */ false, /* true ==> print leading 0 before decimal pt */
0, /* true ==> print trailing 0's */ 0, /* true ==> print trailing 0's */
MAXSCANCOUNT, /* max scan errors before abort */ MAXSCANCOUNT, /* max scan errors before abort */
@@ -230,6 +232,7 @@ CONFIG newstd = { /* new non-backward compatible configuration */
8, /* cfsim() default rounding mode */ 8, /* cfsim() default rounding mode */
24, /* output default rounding mode */ 24, /* output default rounding mode */
24, /* round()/bround() default rounding mode */ 24, /* round()/bround() default rounding mode */
24, /* trigonometric and hyperbolic function rounding mode */
true, /* true ==> print leading 0 before decimal pt */ true, /* true ==> print leading 0 before decimal pt */
0, /* true ==> print trailing 0's */ 0, /* true ==> print trailing 0's */
MAXSCANCOUNT, /* max scan errors before abort */ MAXSCANCOUNT, /* max scan errors before abort */
@@ -761,6 +764,14 @@ setconfig(int type, VALUE *vp)
conf->round = len; conf->round = len;
break; break;
case CONFIG_TRIGROUND:
if (getlen(vp, &len)) {
math_error("Illegal value for triground");
not_reached();
}
conf->triground = len;
break;
case CONFIG_LEADZERO: case CONFIG_LEADZERO:
if (vp->v_type == V_NUM) { if (vp->v_type == V_NUM) {
q = vp->v_num; q = vp->v_num;
@@ -1308,6 +1319,10 @@ config_value(CONFIG *cfg, int type, VALUE *vp)
i = cfg->round; i = cfg->round;
break; break;
case CONFIG_TRIGROUND:
i = cfg->triground;
break;
case CONFIG_LEADZERO: case CONFIG_LEADZERO:
i = (cfg->leadzero ? 1 : 0); i = (cfg->leadzero ? 1 : 0);
break; break;
@@ -1512,6 +1527,7 @@ config_cmp(CONFIG *cfg1, CONFIG *cfg2)
cfg1->cfsim != cfg2->cfsim || cfg1->cfsim != cfg2->cfsim ||
cfg1->outround != cfg2->outround || cfg1->outround != cfg2->outround ||
cfg1->round != cfg2->round || cfg1->round != cfg2->round ||
cfg1->triground != cfg2->triground ||
cfg1->leadzero != cfg2->leadzero || cfg1->leadzero != cfg2->leadzero ||
cfg1->fullzero != cfg2->fullzero || cfg1->fullzero != cfg2->fullzero ||
cfg1->maxscancount != cfg2->maxscancount || cfg1->maxscancount != cfg2->maxscancount ||

View File

@@ -97,6 +97,7 @@
#define CONFIG_TILDE_SPACE 47 #define CONFIG_TILDE_SPACE 47
#define CONFIG_FRACTION_SPACE 48 #define CONFIG_FRACTION_SPACE 48
#define CONFIG_COMPLEX_SPACE 49 #define CONFIG_COMPLEX_SPACE 49
#define CONFIG_TRIGROUND 50
/* /*
@@ -120,6 +121,7 @@
* config_value(), config_cmp(), * config_value(), config_cmp(),
* and perhaps config_copy(), config_free() * and perhaps config_copy(), config_free()
* config.h - CONFIG_XYZ_SYMBOL (see above) * config.h - CONFIG_XYZ_SYMBOL (see above)
* help/config - document new config option
*/ */
struct config { struct config {
int outmode; /* current output mode */ int outmode; /* current output mode */
@@ -147,6 +149,7 @@ struct config {
LEN cfsim; /* cfsim() default rounding mode */ LEN cfsim; /* cfsim() default rounding mode */
LEN outround; /* output default rounding mode */ LEN outround; /* output default rounding mode */
LEN round; /* round()/bround() default rounding mode */ LEN round; /* round()/bround() default rounding mode */
LEN triground; /* trigonometric and hyperbolic function rounding mode */
bool leadzero; /* OK to print leading 0 before decimal pt */ bool leadzero; /* OK to print leading 0 before decimal pt */
bool fullzero; /* OK to print trailing 0's */ bool fullzero; /* OK to print trailing 0's */
long maxscancount; /* max scan errors before abort */ long maxscancount; /* max scan errors before abort */

1
hash.c
View File

@@ -967,6 +967,7 @@ hash_value(int type, void *v, HASH *state)
state = hash_long(type, (long)value->v_config->cfsim, state); state = hash_long(type, (long)value->v_config->cfsim, state);
state = hash_long(type, (long)value->v_config->outround, state); state = hash_long(type, (long)value->v_config->outround, state);
state = hash_long(type, (long)value->v_config->round, state); state = hash_long(type, (long)value->v_config->round, state);
state = hash_long(type, (long)value->v_config->triground, state);
state = hash_bool(type, value->v_config->leadzero, state); state = hash_bool(type, value->v_config->leadzero, state);
state = hash_bool(type, value->v_config->fullzero, state); state = hash_bool(type, value->v_config->fullzero, state);
state = hash_long(type, state = hash_long(type,

View File

@@ -30,7 +30,9 @@ LINK LIBRARY
NUMBER *qacosh(NUMBER *x, NUMBER *eps) NUMBER *qacosh(NUMBER *x, NUMBER *eps)
SEE ALSO SEE ALSO
asinh, atanh, asech, acsch, acoth, epsilon sinh, cosh, tanh, coth, sech, csch
asinh, atanh, acoth, asech, acsch
epsilon
## Copyright (C) 1999,2023 Landon Curt Noll ## Copyright (C) 1999,2023 Landon Curt Noll
## ##

View File

@@ -29,7 +29,9 @@ LINK LIBRARY
NUMBER *qacoth(NUMBER *x, NUMBER *eps) NUMBER *qacoth(NUMBER *x, NUMBER *eps)
SEE ALSO SEE ALSO
asinh, acosh, atanh, asech, acsch, epsilon sinh, cosh, tanh, coth, sech, csch
asinh, acosh, atanh, asech, acsch
epsilon
## Copyright (C) 1999,2021,2023 Landon Curt Noll ## Copyright (C) 1999,2021,2023 Landon Curt Noll
## ##

View File

@@ -29,7 +29,9 @@ LINK LIBRARY
NUMBER *qacsch(NUMBER *x, NUMBER *eps) NUMBER *qacsch(NUMBER *x, NUMBER *eps)
SEE ALSO SEE ALSO
asinh, acosh, atanh, asech, acoth, epsilon sinh, cosh, tanh, coth, sech, csch
asinh, acosh, atanh, acoth, asech
epsilon
## Copyright (C) 1999,2021,2023 Landon Curt Noll ## Copyright (C) 1999,2021,2023 Landon Curt Noll
## ##

View File

@@ -29,7 +29,9 @@ LINK LIBRARY
NUMBER *qasech(NUMBER *x, NUMBER *eps) NUMBER *qasech(NUMBER *x, NUMBER *eps)
SEE ALSO SEE ALSO
asinh, acosh, atanh, acsch, acoth, epsilon sinh, cosh, tanh, coth, sech, csch
asinh, acosh, atanh, acoth, acsch
epsilon
## Copyright (C) 1999,2023 Landon Curt Noll ## Copyright (C) 1999,2023 Landon Curt Noll
## ##

View File

@@ -29,7 +29,9 @@ LINK LIBRARY
NUMBER *qasinh(NUMBER *x, NUMBER *eps) NUMBER *qasinh(NUMBER *x, NUMBER *eps)
SEE ALSO SEE ALSO
acosh, atanh, asech, acsch, acoth, epsilon sinh, cosh, tanh, coth, sech, csch
acosh, atanh, acoth, asech, acsch
epsilon
## Copyright (C) 1999,2023 Landon Curt Noll ## Copyright (C) 1999,2023 Landon Curt Noll
## ##

View File

@@ -29,7 +29,9 @@ LINK LIBRARY
NUMBER *qatanh(NUMBER *x, NUMBER *eps) NUMBER *qatanh(NUMBER *x, NUMBER *eps)
SEE ALSO SEE ALSO
asinh, acosh, asech, acsch, acoth, epsilon sinh, cosh, tanh, coth, sech, csch
asinh, acosh, acoth, asech, acsch
epsilon
## Copyright (C) 1999,2021,2023 Landon Curt Noll ## Copyright (C) 1999,2021,2023 Landon Curt Noll
## ##

View File

@@ -44,6 +44,7 @@ DESCRIPTION
"cfappr" sets rounding mode for cfappr "cfappr" sets rounding mode for cfappr
"cfsim" sets rounding mode for cfsim "cfsim" sets rounding mode for cfsim
"round" sets rounding mode for round and bround "round" sets rounding mode for round and bround
"triground" sets rounding mode for trigonometric and hyperbolic functions
"outround" sets rounding mode for printing of numbers "outround" sets rounding mode for printing of numbers
"leadzero" enables/disables printing of 0 as in 0.5 "leadzero" enables/disables printing of 0 as in 0.5
"fullzero" enables/disables padding zeros as in 0.5000 "fullzero" enables/disables padding zeros as in 0.5000
@@ -422,6 +423,7 @@ DESCRIPTION
config("cfsim", bitflag) config("cfsim", bitflag)
config("outround", bitflag) config("outround", bitflag)
config("round", bitflag) config("round", bitflag)
config("triground", bitflag)
The "quomod", "quo", "mod", "sqrt", "appr", "cfappr", "cfsim", and The "quomod", "quo", "mod", "sqrt", "appr", "cfappr", "cfsim", and
"round" control the way in which any necessary rounding occurs. "round" control the way in which any necessary rounding occurs.
@@ -474,6 +476,37 @@ DESCRIPTION
config("quo", 2) config("quo", 2)
config("mod", 2) config("mod", 2)
The config("triground") controls rounding for the following
trigonometric and hyperbolic functions:
sin, cos, tan, cot, sec, csc
asin, acos, atan, acot, asec, acsc
versin, coversin, vercos, covercos
aversin, acoversin, avercos, acovercos
haversin, hacoversin, havercos, hacovercos
ahaversin, hacoversin, havercos, ahacovercos
exsec, aexsec, excsc, aexcsc
crd, acrd
cas, cis
sinh, cosh, tanh, coth, sech, csch
asinh, acosh, atanh, acoth, asech, acsch
In addition to taking a complex root (such as via the power
function on a complex value), "triground" is used for:
exp, polar
For the above mentioned functions, the rounding mode used to
round the result to the nearest epsilon value is controlled by,
and defaults to:
config("triground", 24)
As with other config options, the call returns the previous mode,
without a 2nd argument, returns the current mode without changing it:
config("triground")
=-= =-=
config("leadzero", boolean) config("leadzero", boolean)

View File

@@ -27,7 +27,9 @@ LINK LIBRARY
NUMBER *qcosh(NUMBER *x, NUMBER *eps) NUMBER *qcosh(NUMBER *x, NUMBER *eps)
SEE ALSO SEE ALSO
sinh, tanh, sech, csch, coth, epsilon sinh, tanh, coth, sech, csch
asinh, acosh, atanh, acoth, asech, acsch
epsilon
## Copyright (C) 1999,2023 Landon Curt Noll ## Copyright (C) 1999,2023 Landon Curt Noll
## ##

View File

@@ -27,7 +27,9 @@ LINK LIBRARY
NUMBER *qcoth(NUMBER *x, NUMBER *eps) NUMBER *qcoth(NUMBER *x, NUMBER *eps)
SEE ALSO SEE ALSO
sinh, cosh, tanh, sech, csch, epsilon sinh, cosh, tanh, sech, csch
asinh, acosh, atanh, acoth, asech, acsch
epsilon
## Copyright (C) 1999,2023 Landon Curt Noll ## Copyright (C) 1999,2023 Landon Curt Noll
## ##

View File

@@ -27,7 +27,9 @@ LINK LIBRARY
NUMBER *qcsch(NUMBER *x, NUMBER *eps) NUMBER *qcsch(NUMBER *x, NUMBER *eps)
SEE ALSO SEE ALSO
sinh, cosh, tanh, sech, coth, epsilon sinh, cosh, tanh, coth, sech
asinh, acosh, atanh, acoth, asech, acsch
epsilon
## Copyright (C) 1999,2021,2023 Landon Curt Noll ## Copyright (C) 1999,2021,2023 Landon Curt Noll
## ##

View File

@@ -28,7 +28,9 @@ LINK LIBRARY
NUMBER *qsech(NUMBER *x, NUMBER *eps) NUMBER *qsech(NUMBER *x, NUMBER *eps)
SEE ALSO SEE ALSO
sinh, cosh, tanh, csch, coth, epsilon sinh, cosh, tanh, coth, csch
asinh, acosh, atanh, acoth, asech, acsch
epsilon
## Copyright (C) 1999,2021,2023 Landon Curt Noll ## Copyright (C) 1999,2021,2023 Landon Curt Noll
## ##

View File

@@ -28,7 +28,9 @@ LINK LIBRARY
NUMBER *qsinh(NUMBER *x, NUMBER *eps) NUMBER *qsinh(NUMBER *x, NUMBER *eps)
SEE ALSO SEE ALSO
cosh, tanh, sech, csch, coth, epsilon cosh, tanh, coth, sech, csch
asinh, acosh, atanh, acoth, asech, acsch
epsilon
## Copyright (C) 1999,2023 Landon Curt Noll ## Copyright (C) 1999,2023 Landon Curt Noll
## ##

View File

@@ -28,7 +28,9 @@ LINK LIBRARY
NUMBER *qtanh(NUMBER *x, NUMBER *eps) NUMBER *qtanh(NUMBER *x, NUMBER *eps)
SEE ALSO SEE ALSO
sinh, cosh, sech, csch, coth, epsilon sinh, cosh, coth, sech, csch
asinh, acosh, atanh, acoth, asech, acsch
epsilon
## Copyright (C) 1999,2021,2023 Landon Curt Noll ## Copyright (C) 1999,2021,2023 Landon Curt Noll
## ##

View File

@@ -293,7 +293,7 @@ qhypot(NUMBER *q1, NUMBER *q2, NUMBER *epsilon)
tmp3 = qqadd(tmp1, tmp2); tmp3 = qqadd(tmp1, tmp2);
qfree(tmp1); qfree(tmp1);
qfree(tmp2); qfree(tmp2);
tmp1 = qsqrt(tmp3, epsilon, 24L); tmp1 = qsqrt(tmp3, epsilon, conf->triground);
qfree(tmp3); qfree(tmp3);
return tmp1; return tmp1;
} }
@@ -330,7 +330,7 @@ qlegtoleg(NUMBER *q, NUMBER *epsilon, bool wantneg)
qtmp1 = qsquare(q); qtmp1 = qsquare(q);
qtmp2 = qsub(&_qone_, qtmp1); qtmp2 = qsub(&_qone_, qtmp1);
qfree(qtmp1); qfree(qtmp1);
res = qsqrt(qtmp2, epsilon, 24L); res = qsqrt(qtmp2, epsilon, conf->triground);
qfree(qtmp2); qfree(qtmp2);
if (wantneg) { if (wantneg) {
qtmp1 = qneg(res); qtmp1 = qneg(res);

View File

@@ -32,6 +32,7 @@
#include "qmath.h" #include "qmath.h"
#include "config.h"
#include "errtbl.h" #include "errtbl.h"
@@ -126,7 +127,7 @@ qsincos(NUMBER *q, long bitnum, NUMBER **vs, NUMBER **vc)
m++; m++;
} /* m is working number of bits */ } /* m is working number of bits */
qtmp1 = qscale(q, m - n); qtmp1 = qscale(q, m - n);
zquo(qtmp1->num, qtmp1->den, &X, 24); zquo(qtmp1->num, qtmp1->den, &X, conf->triground);
qfree(qtmp1); qfree(qtmp1);
if (ziszero(X)) { if (ziszero(X)) {
zfree(X); zfree(X);
@@ -224,7 +225,7 @@ qcos(NUMBER *q, NUMBER *epsilon)
return qlink(&_qzero_); return qlink(&_qzero_);
qsincos(q, n + 2, &sin, &cos); qsincos(q, n + 2, &sin, &cos);
qfree(sin); qfree(sin);
res = qmappr(cos, epsilon, 24); res = qmappr(cos, epsilon, conf->triground);
qfree(cos); qfree(cos);
return res; return res;
} }
@@ -248,7 +249,7 @@ qsin(NUMBER *q, NUMBER *epsilon)
return qlink(&_qzero_); return qlink(&_qzero_);
qsincos(q, n + 2, &sin, &cos); qsincos(q, n + 2, &sin, &cos);
qfree(cos); qfree(cos);
res = qmappr(sin, epsilon, 24); res = qmappr(sin, epsilon, conf->triground);
qfree(sin); qfree(sin);
return res; return res;
} }
@@ -289,7 +290,7 @@ qtan(NUMBER *q, NUMBER *epsilon)
tan = qqdiv(sin, cos); tan = qqdiv(sin, cos);
qfree(sin); qfree(sin);
qfree(cos); qfree(cos);
res = qmappr(tan, epsilon, 24); res = qmappr(tan, epsilon, conf->triground);
qfree(tan); qfree(tan);
return res; return res;
} }
@@ -335,7 +336,7 @@ qcot(NUMBER *q, NUMBER *epsilon)
cot = qqdiv(cos, sin); cot = qqdiv(cos, sin);
qfree(sin); qfree(sin);
qfree(cos); qfree(cos);
res = qmappr(cot, epsilon, 24); res = qmappr(cot, epsilon, conf->triground);
qfree(cot); qfree(cot);
return res; return res;
} }
@@ -374,7 +375,7 @@ qsec(NUMBER *q, NUMBER *epsilon)
} }
sec = qinv(cos); sec = qinv(cos);
qfree(cos); qfree(cos);
res = qmappr(sec, epsilon, 24); res = qmappr(sec, epsilon, conf->triground);
qfree(sec); qfree(sec);
return res; return res;
} }
@@ -418,7 +419,7 @@ qcsc(NUMBER *q, NUMBER *epsilon)
} }
csc = qinv(sin); csc = qinv(sin);
qfree(sin); qfree(sin);
res = qmappr(csc, epsilon, 24); res = qmappr(csc, epsilon, conf->triground);
qfree(csc); qfree(csc);
return res; return res;
} }
@@ -461,7 +462,7 @@ qasin(NUMBER *q, NUMBER *epsilon)
zsquare(q->den, &ztmp); zsquare(q->den, &ztmp);
zsub(ztmp, qtmp1->num, &qtmp1->den); zsub(ztmp, qtmp1->num, &qtmp1->den);
zfree(ztmp); zfree(ztmp);
qtmp2 = qsqrt(qtmp1, epsilon1, 24); qtmp2 = qsqrt(qtmp1, epsilon1, conf->triground);
qfree(qtmp1); qfree(qtmp1);
qtmp1 = qatan(qtmp2, epsilon); qtmp1 = qatan(qtmp2, epsilon);
} }
@@ -504,7 +505,7 @@ qacos(NUMBER *q, NUMBER *epsilon)
q1 = qalloc(); q1 = qalloc();
zsub(q->den, q->num, &q1->num); zsub(q->den, q->num, &q1->num);
zadd(q->den, q->num, &q1->den); zadd(q->den, q->num, &q1->den);
q2 = qsqrt(q1, epsilon1, 24L); q2 = qsqrt(q1, epsilon1, conf->triground);
qfree(q1); qfree(q1);
qfree(epsilon1); qfree(epsilon1);
epsilon1 = qscale(epsilon, -1L); epsilon1 = qscale(epsilon, -1L);
@@ -544,7 +545,7 @@ qatan(NUMBER *q, NUMBER *epsilon)
if (m < 8) if (m < 8)
m = 8; /* m is number of working binary digits */ m = 8; /* m is number of working binary digits */
qtmp = qscale(q, m); qtmp = qscale(q, m);
zquo(qtmp->num, qtmp->den, &X, 24); zquo(qtmp->num, qtmp->den, &X, conf->triground);
qfree(qtmp); qfree(qtmp);
zbitvalue(m, &D); /* q has become X/D */ zbitvalue(m, &D); /* q has become X/D */
zsquare(D, &DD); zsquare(D, &DD);
@@ -553,13 +554,13 @@ qatan(NUMBER *q, NUMBER *epsilon)
zsquare(X, &ztmp1); zsquare(X, &ztmp1);
zadd(ztmp1, DD, &ztmp2); zadd(ztmp1, DD, &ztmp2);
zfree(ztmp1); zfree(ztmp1);
zsqrt(ztmp2, &ztmp1, 24L); zsqrt(ztmp2, &ztmp1, conf->triground);
zfree(ztmp2); zfree(ztmp2);
zadd(ztmp1, D, &ztmp2); zadd(ztmp1, D, &ztmp2);
zfree(ztmp1); zfree(ztmp1);
zshift(X, m, &ztmp1); zshift(X, m, &ztmp1);
zfree(X); zfree(X);
zquo(ztmp1, ztmp2, &X, 24L); zquo(ztmp1, ztmp2, &X, conf->triground);
zfree(ztmp1); zfree(ztmp1);
zfree(ztmp2); zfree(ztmp2);
} }
@@ -608,7 +609,7 @@ qatan(NUMBER *q, NUMBER *epsilon)
qtmp->num = sum; qtmp->num = sum;
} }
zbitvalue(m - 4 - k, &qtmp->den); zbitvalue(m - 4 - k, &qtmp->den);
res = qmappr(qtmp, epsilon, 24L); res = qmappr(qtmp, epsilon, conf->triground);
qfree(qtmp); qfree(qtmp);
return res; return res;
} }
@@ -677,7 +678,7 @@ qacot(NUMBER *q, NUMBER *epsilon)
tmp3 = qqadd(tmp1, tmp2); tmp3 = qqadd(tmp1, tmp2);
qfree(tmp1); qfree(tmp1);
qfree(tmp2); qfree(tmp2);
tmp1 = qmappr(tmp3, epsilon, 24L); tmp1 = qmappr(tmp3, epsilon, conf->triground);
qfree(tmp3); qfree(tmp3);
return tmp1; return tmp1;
} }
@@ -817,7 +818,7 @@ qpi(NUMBER *epsilon)
qtmp.den = sum; qtmp.den = sum;
t1 = qscale(&qtmp, shift); t1 = qscale(&qtmp, shift);
zfree(sum); zfree(sum);
r = qmappr(t1, epsilon, 24L); r = qmappr(t1, epsilon, conf->triground);
qfree(t1); qfree(t1);
pivalue[LAST_PI_EPSILON] = qlink(epsilon); pivalue[LAST_PI_EPSILON] = qlink(epsilon);
pivalue[LAST_PI_VALUE] = qlink(r); pivalue[LAST_PI_VALUE] = qlink(r);
@@ -949,7 +950,7 @@ qexp(NUMBER *q, NUMBER *epsilon)
qfree(tmp2); qfree(tmp2);
tmp2 = tmp1; tmp2 = tmp1;
} }
tmp1 = qmappr(tmp2, epsilon, 24L); tmp1 = qmappr(tmp2, epsilon, conf->triground);
qfree(tmp2); qfree(tmp2);
return tmp1; return tmp1;
} }
@@ -992,7 +993,7 @@ qexprel(NUMBER *q, long bitnum)
m++; m++;
} /* m is working number of bits */ } /* m is working number of bits */
qtmp1 = qscale(q, m - n); qtmp1 = qscale(q, m - n);
zquo(qtmp1->num, qtmp1->den, &X, 24); zquo(qtmp1->num, qtmp1->den, &X, conf->triground);
qfree(qtmp1); qfree(qtmp1);
if (ziszero(X)) { if (ziszero(X)) {
zfree(X); zfree(X);
@@ -1083,7 +1084,7 @@ qln(NUMBER *q, NUMBER *epsilon)
} }
m += 18; /* 8 more sqrts, 8 for rounding, 2 for epsilon/4 */ m += 18; /* 8 more sqrts, 8 for rounding, 2 for epsilon/4 */
qtmp = qscale(q, m - k); qtmp = qscale(q, m - k);
zquo(qtmp->num, qtmp->den, &X, 24L); zquo(qtmp->num, qtmp->den, &X, conf->triground);
qfree(q); qfree(q);
qfree(qtmp); qfree(qtmp);
@@ -1098,7 +1099,7 @@ qln(NUMBER *q, NUMBER *epsilon)
n++; n++;
zshift(X, m + (k & 1), &ztmp); zshift(X, m + (k & 1), &ztmp);
zfree(X); zfree(X);
zsqrt(ztmp, &X, 24); zsqrt(ztmp, &X, conf->triground);
zfree(ztmp) zfree(ztmp)
k /= 2; k /= 2;
} }
@@ -1109,7 +1110,7 @@ qln(NUMBER *q, NUMBER *epsilon)
zfree(D); zfree(D);
zshift(pow, m, &ztmp); zshift(pow, m, &ztmp);
zfree(pow); zfree(pow);
zquo(ztmp, mul, &pow, 24); /* pow now (X - D)/(X + D) */ zquo(ztmp, mul, &pow, conf->triground); /* pow now (X - D)/(X + D) */
zfree(ztmp); zfree(ztmp);
zfree(mul); zfree(mul);
@@ -1152,7 +1153,7 @@ qln(NUMBER *q, NUMBER *epsilon)
} }
zbitvalue(m - k - n, &qtmp->den); zbitvalue(m - k - n, &qtmp->den);
} }
res = qmappr(qtmp, epsilon, 24L); res = qmappr(qtmp, epsilon, conf->triground);
qfree(qtmp); qfree(qtmp);
return res; return res;
} }
@@ -1425,7 +1426,7 @@ qpower(NUMBER *q1, NUMBER *q2, NUMBER *epsilon)
not_reached(); not_reached();
} }
if (qisone(q2)) if (qisone(q2))
return qmappr(q1, epsilon, 24); return qmappr(q1, epsilon, conf->triground);
if (zrel(q1->num, q1->den) < 0) { if (zrel(q1->num, q1->den) < 0) {
q1tmp = qinv(q1); q1tmp = qinv(q1);
q2tmp = qneg(q2); q2tmp = qneg(q2);
@@ -1435,7 +1436,7 @@ qpower(NUMBER *q1, NUMBER *q2, NUMBER *epsilon)
} }
if (qisone(q2tmp)) { if (qisone(q2tmp)) {
qfree(q2tmp); qfree(q2tmp);
q2tmp = qmappr(q1tmp, epsilon, 24); q2tmp = qmappr(q1tmp, epsilon, conf->triground);
qfree(q1tmp); qfree(q1tmp);
return q2tmp; return q2tmp;
} }
@@ -1510,7 +1511,7 @@ qpower(NUMBER *q1, NUMBER *q2, NUMBER *epsilon)
} }
} }
qfree(tmp2); qfree(tmp2);
tmp2 = qmappr(tmp1, epsilon, 24L); tmp2 = qmappr(tmp1, epsilon, conf->triground);
qfree(tmp1); qfree(tmp1);
return tmp2; return tmp2;
} }
@@ -1536,7 +1537,7 @@ qroot(NUMBER *q1, NUMBER *q2, NUMBER *epsilon)
if (qiszero(q1) || qisone(q1) || qisone(q2)) if (qiszero(q1) || qisone(q1) || qisone(q2))
return qlink(q1); return qlink(q1);
if (qistwo(q2)) if (qistwo(q2))
return qsqrt(q1, epsilon, 24L); return qsqrt(q1, epsilon, conf->triground);
neg = qisneg(q1); neg = qisneg(q1);
if (neg) { if (neg) {
if (ziseven(q2->num)) { if (ziseven(q2->num)) {
@@ -1581,7 +1582,7 @@ qcosh(NUMBER *q, NUMBER *epsilon)
qfree(tmp2) qfree(tmp2)
tmp1 = qscale(tmp3, -1); tmp1 = qscale(tmp3, -1);
qfree(tmp3); qfree(tmp3);
tmp2 = qmappr(tmp1, epsilon, 24L); tmp2 = qmappr(tmp1, epsilon, conf->triground);
qfree(tmp1); qfree(tmp1);
return tmp2; return tmp2;
} }
@@ -1612,7 +1613,7 @@ qsinh(NUMBER *q, NUMBER *epsilon)
qfree(tmp2) qfree(tmp2)
tmp1 = qscale(tmp3, -1); tmp1 = qscale(tmp3, -1);
qfree(tmp3); qfree(tmp3);
tmp2 = qmappr(tmp1, epsilon, 24L); tmp2 = qmappr(tmp1, epsilon, conf->triground);
qfree(tmp1); qfree(tmp1);
return tmp2; return tmp2;
} }
@@ -1661,7 +1662,7 @@ qtanh(NUMBER *q, NUMBER *epsilon)
qfree(tmp2); qfree(tmp2);
qfree(tmp3); qfree(tmp3);
} }
tmp2 = qmappr(tmp1, epsilon, 24L); tmp2 = qmappr(tmp1, epsilon, conf->triground);
qfree(tmp1); qfree(tmp1);
if (qisneg(q)) { if (qisneg(q)) {
tmp1 = qneg(tmp2); tmp1 = qneg(tmp2);
@@ -1724,7 +1725,7 @@ qcoth(NUMBER *q, NUMBER *epsilon)
qfree(tmp1); qfree(tmp1);
tmp1 = tmp2; tmp1 = tmp2;
} }
res = qmappr(tmp1, epsilon, 24L); res = qmappr(tmp1, epsilon, conf->triground);
qfree(tmp1); qfree(tmp1);
return res; return res;
} }
@@ -1765,7 +1766,7 @@ qsech(NUMBER *q, NUMBER *epsilon)
qfree(tmp3); qfree(tmp3);
tmp2 = qscale(tmp1, 1); tmp2 = qscale(tmp1, 1);
qfree(tmp1); qfree(tmp1);
res = qmappr(tmp2, epsilon, 24L); res = qmappr(tmp2, epsilon, conf->triground);
qfree(tmp2); qfree(tmp2);
return res; return res;
} }
@@ -1812,7 +1813,7 @@ qcsch(NUMBER *q, NUMBER *epsilon)
qfree(tmp3) qfree(tmp3)
tmp2 = qscale(tmp1, 1); tmp2 = qscale(tmp1, 1);
qfree(tmp1); qfree(tmp1);
res = qmappr(tmp2, epsilon, 24L); res = qmappr(tmp2, epsilon, conf->triground);
qfree(tmp2); qfree(tmp2);
return res; return res;
} }
@@ -1842,14 +1843,14 @@ qacosh(NUMBER *q, NUMBER *epsilon)
tmp1 = qsquare(q); tmp1 = qsquare(q);
tmp2 = qdec(tmp1); tmp2 = qdec(tmp1);
qfree(tmp1); qfree(tmp1);
tmp1 = qsqrt(tmp2, epsilon1, 24L); tmp1 = qsqrt(tmp2, epsilon1, conf->triground);
qfree(tmp2); qfree(tmp2);
tmp2 = qqadd(tmp1, q); tmp2 = qqadd(tmp1, q);
qfree(tmp1); qfree(tmp1);
tmp1 = qln(tmp2, epsilon1); tmp1 = qln(tmp2, epsilon1);
qfree(tmp2); qfree(tmp2);
qfree(epsilon1); qfree(epsilon1);
tmp2 = qmappr(tmp1, epsilon, 24L); tmp2 = qmappr(tmp1, epsilon, conf->triground);
qfree(tmp1); qfree(tmp1);
return tmp2; return tmp2;
} }
@@ -1880,7 +1881,7 @@ qasinh(NUMBER *q, NUMBER *epsilon)
tmp1 = qsquare(q); tmp1 = qsquare(q);
tmp2 = qinc(tmp1); tmp2 = qinc(tmp1);
qfree(tmp1); qfree(tmp1);
tmp1 = qsqrt(tmp2, epsilon1, 24L); tmp1 = qsqrt(tmp2, epsilon1, conf->triground);
qfree(tmp2); qfree(tmp2);
tmp2 = qqadd(tmp1, q); tmp2 = qqadd(tmp1, q);
qfree(tmp1); qfree(tmp1);
@@ -1888,7 +1889,7 @@ qasinh(NUMBER *q, NUMBER *epsilon)
qfree(tmp2); qfree(tmp2);
qfree(q); qfree(q);
qfree(epsilon1); qfree(epsilon1);
tmp2 = qmappr(tmp1, epsilon, 24L); tmp2 = qmappr(tmp1, epsilon, conf->triground);
if (neg) { if (neg) {
tmp1 = qneg(tmp2); tmp1 = qneg(tmp2);
qfree(tmp2); qfree(tmp2);
@@ -3677,9 +3678,9 @@ qcas(NUMBER *q, NUMBER *epsilon)
* compute cosine and sine * compute cosine and sine
*/ */
qsincos(q, n + 2, &sin, &cos); qsincos(q, n + 2, &sin, &cos);
tcos = qmappr(cos, epsilon, 24); tcos = qmappr(cos, epsilon, conf->triground);
qfree(cos); qfree(cos);
tsin = qmappr(sin, epsilon, 24); tsin = qmappr(sin, epsilon, conf->triground);
qfree(sin); qfree(sin);
res = qqadd(tcos, tsin); res = qqadd(tcos, tsin);
qfree(tcos); qfree(tcos);

View File

@@ -450,6 +450,7 @@ config_hash(CONFIG *cfg, QCKHASH val)
value = (((value>>5) | (value<<27)) ^ (USB32)cfg->cfsim); value = (((value>>5) | (value<<27)) ^ (USB32)cfg->cfsim);
value = (((value>>5) | (value<<27)) ^ (USB32)cfg->outround); value = (((value>>5) | (value<<27)) ^ (USB32)cfg->outround);
value = (((value>>5) | (value<<27)) ^ (USB32)cfg->round); value = (((value>>5) | (value<<27)) ^ (USB32)cfg->round);
value = (((value>>5) | (value<<27)) ^ (USB32)cfg->triground);
value = (((value>>5) | (value<<27)) ^ (USB32)cfg->leadzero); value = (((value>>5) | (value<<27)) ^ (USB32)cfg->leadzero);
value = (((value>>5) | (value<<27)) ^ (USB32)cfg->fullzero); value = (((value>>5) | (value<<27)) ^ (USB32)cfg->fullzero);
value = (((value>>5) | (value<<27)) ^ (USB32)cfg->maxscancount); value = (((value>>5) | (value<<27)) ^ (USB32)cfg->maxscancount);