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
help files. Documented libcalc functions in the SEE ALSO sections.
Improved "SEE ALSO" for the hyperbolic function help files.
Expanded the calc regression test suite test 34dd to test various
real and complex values for trigonometric functions.
@@ -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 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:

View File

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

View File

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

View File

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

View File

@@ -97,6 +97,7 @@
#define CONFIG_TILDE_SPACE 47
#define CONFIG_FRACTION_SPACE 48
#define CONFIG_COMPLEX_SPACE 49
#define CONFIG_TRIGROUND 50
/*
@@ -120,6 +121,7 @@
* config_value(), config_cmp(),
* and perhaps config_copy(), config_free()
* config.h - CONFIG_XYZ_SYMBOL (see above)
* help/config - document new config option
*/
struct config {
int outmode; /* current output mode */
@@ -147,6 +149,7 @@ struct config {
LEN cfsim; /* cfsim() default rounding mode */
LEN outround; /* output 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 fullzero; /* OK to print trailing 0's */
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->outround, 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->fullzero, state);
state = hash_long(type,

View File

@@ -30,7 +30,9 @@ LINK LIBRARY
NUMBER *qacosh(NUMBER *x, NUMBER *eps)
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
##

View File

@@ -29,7 +29,9 @@ LINK LIBRARY
NUMBER *qacoth(NUMBER *x, NUMBER *eps)
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
##

View File

@@ -29,7 +29,9 @@ LINK LIBRARY
NUMBER *qacsch(NUMBER *x, NUMBER *eps)
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
##

View File

@@ -29,7 +29,9 @@ LINK LIBRARY
NUMBER *qasech(NUMBER *x, NUMBER *eps)
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
##

View File

@@ -29,7 +29,9 @@ LINK LIBRARY
NUMBER *qasinh(NUMBER *x, NUMBER *eps)
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
##

View File

@@ -29,7 +29,9 @@ LINK LIBRARY
NUMBER *qatanh(NUMBER *x, NUMBER *eps)
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
##

View File

@@ -44,6 +44,7 @@ DESCRIPTION
"cfappr" sets rounding mode for cfappr
"cfsim" sets rounding mode for cfsim
"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
"leadzero" enables/disables printing of 0 as in 0.5
"fullzero" enables/disables padding zeros as in 0.5000
@@ -422,6 +423,7 @@ DESCRIPTION
config("cfsim", bitflag)
config("outround", bitflag)
config("round", bitflag)
config("triground", bitflag)
The "quomod", "quo", "mod", "sqrt", "appr", "cfappr", "cfsim", and
"round" control the way in which any necessary rounding occurs.
@@ -474,6 +476,37 @@ DESCRIPTION
config("quo", 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)

View File

@@ -27,7 +27,9 @@ LINK LIBRARY
NUMBER *qcosh(NUMBER *x, NUMBER *eps)
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
##

View File

@@ -27,7 +27,9 @@ LINK LIBRARY
NUMBER *qcoth(NUMBER *x, NUMBER *eps)
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
##

View File

@@ -27,7 +27,9 @@ LINK LIBRARY
NUMBER *qcsch(NUMBER *x, NUMBER *eps)
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
##

View File

@@ -28,7 +28,9 @@ LINK LIBRARY
NUMBER *qsech(NUMBER *x, NUMBER *eps)
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
##

View File

@@ -28,7 +28,9 @@ LINK LIBRARY
NUMBER *qsinh(NUMBER *x, NUMBER *eps)
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
##

View File

@@ -28,7 +28,9 @@ LINK LIBRARY
NUMBER *qtanh(NUMBER *x, NUMBER *eps)
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
##

View File

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

View File

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