fix aversin() and acoversin()

In cases where the real value to the inverse versed sine and the
inverse coversed sine function produces a complex value, the
conversion from real to complex was incorrect.

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

The func.c code now uses c_to_q().

NOTE: There is a XXX bug marked in the f_aversin() and f_acoversin()
that still needs to be fixed.
This commit is contained in:
Landon Curt Noll
2023-09-05 16:09:22 -07:00
parent ed112997a7
commit 3abedd6713
8 changed files with 125 additions and 98 deletions

View File

@@ -126,6 +126,10 @@ The following are the changes from calc version 2.14.3.5 to date:
builtin functions are listed by "show builtin" and the help/builtin builtin functions are listed by "show builtin" and the help/builtin
to match the sorting of "LANG=C LC_ALL=C sort -d -u". to match the sorting of "LANG=C LC_ALL=C sort -d -u".
Added c_to_q(COMPLEX *c, bool cfree) to make is easier to convert
a COMPLEX value that is real (imag part is 0) into a NUMBER and
optionally free the COMPLEX value.
The following are the changes from calc version 2.14.3.4 to 2.14.3.5: The following are the changes from calc version 2.14.3.4 to 2.14.3.5:

17
LIBRARY
View File

@@ -636,6 +636,23 @@ only used for complex numbers. Examples of macros are:
There is only one comparison you can make for COMPLEX values, and that is There is only one comparison you can make for COMPLEX values, and that is
for equality. The ccmp function returns true if two complex numbers differ. for equality. The ccmp function returns true if two complex numbers differ.
Sometimes to results of a COMPLEX based calculation is a real number.
That is, the imaginary part of the COMPLEX is 0. You may convert the
COMPLEX into a new allocated NUMBER that is real part of the COMPLEX value.
For example:
COMPLEX *c;
NUMBER *q;
bool ok_to_free; /* true ==> free COMPLEX value, false ==> do not */
if (cisreal(c)) {
q = c_to_q(c, ok_to_free);
}
The 2nd argument to c_to_q() determines if the complex argument should be freed
or not. Pass a false value as the 2nd arg if you wish to continue to use the
COMPLEX value.
There are three predefined values for complex numbers. You should clink There are three predefined values for complex numbers. You should clink
them when you want to use them. They are _czero_, _cone_, and _conei_. them when you want to use them. They are _czero_, _cone_, and _conei_.
These have the values 0, 1, and i. These have the values 0, 1, and i.

View File

@@ -3565,9 +3565,9 @@ define test_trig()
': round(aversin(0.5, 1e-10), 10) == 1.0471975512')); ': round(aversin(0.5, 1e-10), 10) == 1.0471975512'));
vrfy(aversin(0) == 0, vrfy(aversin(0) == 0,
strcat(str(tnum++), ': aversin(0) == 0')); strcat(str(tnum++), ': aversin(0) == 0'));
vrfy(round(aversin(-5, 1e-10), 10) == 0.1673829554+2.4921599676i, vrfy(round(aversin(-5, 1e-10), 10) == 2.4778887303i,
strcat(str(tnum++), strcat(str(tnum++),
': round(aversin(0.5, 1e-10), 10) == 0.1673829554+2.4921599676i')); ': round(aversin(-5, 1e-10), 10) == 2.4778887303i'));
vrfy(round(aversin(2 + 3i, 1e-10), 10) == 1.8783999763+1.8641615439i, vrfy(round(aversin(2 + 3i, 1e-10), 10) == 1.8783999763+1.8641615439i,
strcat(str(tnum++), strcat(str(tnum++),
': round(aversin(2 + 3i, 1e-10), 10) == 1.8783999763+1.8641615439i')); ': round(aversin(2 + 3i, 1e-10), 10) == 1.8783999763+1.8641615439i'));
@@ -3578,9 +3578,9 @@ define test_trig()
': round(acoversin(0.5, 1e-10), 10) == 0.5235987756')); ': round(acoversin(0.5, 1e-10), 10) == 0.5235987756'));
vrfy(acoversin(1) == 0, vrfy(acoversin(1) == 0,
strcat(str(tnum++), ': acoversin(1) == 0')); strcat(str(tnum++), ': acoversin(1) == 0'));
vrfy(round(acoversin(-5, 1e-10), 10) == 1.4034133718-2.4921599681i, vrfy(round(acoversin(-5, 1e-10), 10) == 1.5707963268-2.4778887303i,
strcat(str(tnum++), strcat(str(tnum++),
': round(acoversin(0.5, 1e-10), 10) == 1.4034133718-2.4921599681i')); ': round(acoversin(-5, 1e-10), 10) == 1.5707963268-2.4778887303i'));
vrfy(round(acoversin(2 + 3i, 1e-10), 10) == -0.3076036495-1.8641615442i, vrfy(round(acoversin(2 + 3i, 1e-10), 10) == -0.3076036495-1.8641615442i,
strcat(str(tnum++), strcat(str(tnum++),
': round(acoversin(2 + 3i, 1e-10), 10) == -0.3076036495-1.8641615442i')); ': round(acoversin(2 + 3i, 1e-10), 10) == -0.3076036495-1.8641615442i'));

View File

@@ -72,6 +72,7 @@ E_FUNC COMPLEX *c_shift(COMPLEX *c, long i);
E_FUNC COMPLEX *c_square(COMPLEX *c); E_FUNC COMPLEX *c_square(COMPLEX *c);
E_FUNC COMPLEX *c_conj(COMPLEX *c); E_FUNC COMPLEX *c_conj(COMPLEX *c);
E_FUNC COMPLEX *c_real(COMPLEX *c); E_FUNC COMPLEX *c_real(COMPLEX *c);
E_FUNC NUMBER *c_to_q(COMPLEX *c, bool cfree);
E_FUNC COMPLEX *c_imag(COMPLEX *c); E_FUNC COMPLEX *c_imag(COMPLEX *c);
E_FUNC COMPLEX *c_neg(COMPLEX *c); E_FUNC COMPLEX *c_neg(COMPLEX *c);
E_FUNC COMPLEX *c_inv(COMPLEX *c); E_FUNC COMPLEX *c_inv(COMPLEX *c);

View File

@@ -396,6 +396,65 @@ c_real(COMPLEX *c)
} }
/*
* c_to_q - convert a real part of a COMPLEX to a NUMBER
*
* given:
* c complex number for which the real part will be used
* cfree true ==> free c, false ==> do not free c
*
* returns:
* allocated NUMBER that the equivalent of the real part of a complex number
*
* NOTE: Any imaginary part of the COMPLEX value is ignored.
*
* NOTE: To avoid a loss of value, test with cisreal(c) first:
*
* COMPLEX *c;
* NUMBER *q;
* bool ok_to_free;
*
* if (cisreal(c)) {
* q = c_to_q(c, ok_to_free);
* }
*/
NUMBER *
c_to_q(COMPLEX *c, bool cfree)
{
NUMBER *r; /* allocated NUMBER equivalent to return */
/*
* firewall
*/
if (c == NULL) {
math_error("%s: c is NULL", __func__);
not_reached();
}
/*
* allocate a new NUMBER
*/
r = qalloc();
/*
* link in the real part of the COMPLEX value
*/
r = qlink(c->real);
/*
* free c if requested
*/
if (cfree == true) {
comfree(c);
}
/*
* return the allocated equivalent NUMBER
*/
return r;
}
/* /*
* Return the imaginary part of a complex number as a real. * Return the imaginary part of a complex number as a real.
*/ */

130
func.c
View File

@@ -2140,9 +2140,8 @@ f_exp(int count, VALUE **vals)
result.v_com = c; result.v_com = c;
result.v_type = V_COM; result.v_type = V_COM;
if (cisreal(c)) { if (cisreal(c)) {
result.v_num = qlink(c->real); result.v_num = c_to_q(c, true);
result.v_type = V_NUM; result.v_type = V_NUM;
comfree(c);
} }
break; break;
default: default:
@@ -2202,9 +2201,8 @@ f_ln(int count, VALUE **vals)
result.v_type = V_COM; result.v_type = V_COM;
result.v_com = c; result.v_com = c;
if (cisreal(c)) { if (cisreal(c)) {
result.v_num = qlink(c->real); result.v_num = c_to_q(c, true);
result.v_type = V_NUM; result.v_type = V_NUM;
comfree(c);
} }
return result; return result;
} }
@@ -2263,9 +2261,8 @@ f_log(int count, VALUE **vals)
result.v_type = V_COM; result.v_type = V_COM;
result.v_com = c; result.v_com = c;
if (cisreal(c)) { if (cisreal(c)) {
result.v_num = qlink(c->real); result.v_num = c_to_q(c, true);
result.v_type = V_NUM; result.v_type = V_NUM;
comfree(c);
} }
return result; return result;
} }
@@ -2324,9 +2321,8 @@ f_log2(int count, VALUE **vals)
result.v_type = V_COM; result.v_type = V_COM;
result.v_com = c; result.v_com = c;
if (cisreal(c)) { if (cisreal(c)) {
result.v_num = qlink(c->real); result.v_num = c_to_q(c, true);
result.v_type = V_NUM; result.v_type = V_NUM;
comfree(c);
} }
return result; return result;
} }
@@ -2409,8 +2405,7 @@ f_logn(int count, VALUE **vals)
return error_value(E_LOGN_3); return error_value(E_LOGN_3);
} }
if (cisreal(ln_x_c)) { if (cisreal(ln_x_c)) {
ln_x_r = qcopy(ln_x_c->real); ln_x_r = c_to_q(ln_x_c, true);
comfree(ln_x_c);
} else { } else {
ln_of_x_is_complex = true; ln_of_x_is_complex = true;
} }
@@ -2430,8 +2425,7 @@ f_logn(int count, VALUE **vals)
return error_value(E_LOGN_3); return error_value(E_LOGN_3);
} }
if (cisreal(ln_x_c)) { if (cisreal(ln_x_c)) {
ln_x_r = qcopy(ln_x_c->real); ln_x_r = c_to_q(ln_x_c, true);
comfree(ln_x_c);
} else { } else {
ln_of_x_is_complex = true; ln_of_x_is_complex = true;
} }
@@ -2464,8 +2458,7 @@ f_logn(int count, VALUE **vals)
return error_value(E_LOGN_4); return error_value(E_LOGN_4);
} }
if (cisreal(ln_n_c)) { if (cisreal(ln_n_c)) {
ln_n_r = qcopy(ln_n_c->real); ln_n_r = c_to_q(ln_n_c, true);
comfree(ln_n_c);
} else { } else {
ln_of_n_is_complex = true; ln_of_n_is_complex = true;
} }
@@ -2493,8 +2486,7 @@ f_logn(int count, VALUE **vals)
return error_value(E_LOGN_4); return error_value(E_LOGN_4);
} }
if (cisreal(ln_n_c)) { if (cisreal(ln_n_c)) {
ln_n_r = qcopy(ln_n_c->real); ln_n_r = c_to_q(ln_n_c, true);
comfree(ln_n_c);
} else { } else {
ln_of_n_is_complex = true; ln_of_n_is_complex = true;
} }
@@ -2519,9 +2511,8 @@ f_logn(int count, VALUE **vals)
/* check if division is COMPLEX or NUMBER */ /* check if division is COMPLEX or NUMBER */
if (cisreal(p_cval)) { if (cisreal(p_cval)) {
/* ln(x) / ln(n) was NUMBER, not COMPLEX */ /* ln(x) / ln(n) was NUMBER, not COMPLEX */
result.v_num = qlink(p_cval->real); result.v_num = c_to_q(p_cval, true);
result.v_type = V_NUM; result.v_type = V_NUM;
comfree(p_cval);
} else { } else {
/* ln(x) / ln(n) is COMPLEX */ /* ln(x) / ln(n) is COMPLEX */
result.v_type = V_COM; result.v_type = V_COM;
@@ -2540,9 +2531,8 @@ f_logn(int count, VALUE **vals)
/* check if division is COMPLEX or NUMBER */ /* check if division is COMPLEX or NUMBER */
if (cisreal(p_cval)) { if (cisreal(p_cval)) {
/* ln(x) / ln(n) was NUMBER, not COMPLEX */ /* ln(x) / ln(n) was NUMBER, not COMPLEX */
result.v_num = qlink(p_cval->real); result.v_num = c_to_q(p_cval, true);
result.v_type = V_NUM; result.v_type = V_NUM;
comfree(p_cval);
} else { } else {
/* ln(x) / ln(n) is COMPLEX */ /* ln(x) / ln(n) is COMPLEX */
result.v_type = V_COM; result.v_type = V_COM;
@@ -2567,9 +2557,8 @@ f_logn(int count, VALUE **vals)
/* check if division is COMPLEX or NUMBER */ /* check if division is COMPLEX or NUMBER */
if (cisreal(p_cval)) { if (cisreal(p_cval)) {
/* ln(x) / ln(n) was NUMBER, not COMPLEX */ /* ln(x) / ln(n) was NUMBER, not COMPLEX */
result.v_num = qlink(p_cval->real); result.v_num = c_to_q(p_cval, true);
result.v_type = V_NUM; result.v_type = V_NUM;
comfree(p_cval);
} else { } else {
/* ln(x) / ln(n) is COMPLEX */ /* ln(x) / ln(n) is COMPLEX */
result.v_type = V_COM; result.v_type = V_COM;
@@ -2633,9 +2622,8 @@ f_cos(int count, VALUE **vals)
result.v_com = c; result.v_com = c;
result.v_type = V_COM; result.v_type = V_COM;
if (cisreal(c)) { if (cisreal(c)) {
result.v_num = qlink(c->real); result.v_num = c_to_q(c, true);
result.v_type = V_NUM; result.v_type = V_NUM;
comfree(c);
} }
break; break;
default: default:
@@ -2945,9 +2933,8 @@ f_sin(int count, VALUE **vals)
result.v_com = c; result.v_com = c;
result.v_type = V_COM; result.v_type = V_COM;
if (cisreal(c)) { if (cisreal(c)) {
result.v_num = qlink(c->real); result.v_num = c_to_q(c, true);
result.v_type = V_NUM; result.v_type = V_NUM;
comfree(c);
} }
break; break;
default: default:
@@ -3208,8 +3195,7 @@ f_sinh(int count, VALUE **vals)
result.v_com = c; result.v_com = c;
result.v_type = V_COM; result.v_type = V_COM;
if (cisreal(c)) { if (cisreal(c)) {
result.v_num = qlink(c->real); result.v_num = c_to_q(c, true);
comfree(c);
result.v_type = V_NUM; result.v_type = V_NUM;
} }
break; break;
@@ -3262,8 +3248,7 @@ f_cosh(int count, VALUE **vals)
result.v_com = c; result.v_com = c;
result.v_type = V_COM; result.v_type = V_COM;
if (cisreal(c)) { if (cisreal(c)) {
result.v_num = qlink(c->real); result.v_num = c_to_q(c, true);
comfree(c);
result.v_type = V_NUM; result.v_type = V_NUM;
} }
break; break;
@@ -3524,9 +3509,8 @@ f_atan(int count, VALUE **vals)
result.v_type = V_COM; result.v_type = V_COM;
result.v_com = tmp; result.v_com = tmp;
if (cisreal(tmp)) { if (cisreal(tmp)) {
result.v_num = qlink(tmp->real); result.v_num = c_to_q(tmp, true);
result.v_type = V_NUM; result.v_type = V_NUM;
comfree(tmp);
} }
break; break;
default: default:
@@ -3574,9 +3558,8 @@ f_acot(int count, VALUE **vals)
result.v_type = V_COM; result.v_type = V_COM;
result.v_com = tmp; result.v_com = tmp;
if (cisreal(tmp)) { if (cisreal(tmp)) {
result.v_num = qlink(tmp->real); result.v_num = c_to_q(tmp, true);
result.v_type = V_NUM; result.v_type = V_NUM;
comfree(tmp);
} }
break; break;
default: default:
@@ -3591,7 +3574,6 @@ f_asin(int count, VALUE **vals)
VALUE result; VALUE result;
COMPLEX *tmp; COMPLEX *tmp;
NUMBER *err; NUMBER *err;
NUMBER *q;
/* initialize VALUE */ /* initialize VALUE */
result.v_subtype = V_NOSUBTYPE; result.v_subtype = V_NOSUBTYPE;
@@ -3636,10 +3618,8 @@ f_asin(int count, VALUE **vals)
return error_value(E_ASIN3); return error_value(E_ASIN3);
} }
if (result.v_type == V_COM && cisreal(result.v_com)) { if (result.v_type == V_COM && cisreal(result.v_com)) {
q = qlink(result.v_com->real); result.v_num = c_to_q(result.v_com, true);
comfree(result.v_com);
result.v_type = V_NUM; result.v_type = V_NUM;
result.v_num = q;
} }
return result; return result;
} }
@@ -3650,7 +3630,6 @@ f_acos(int count, VALUE **vals)
VALUE result; VALUE result;
COMPLEX *tmp; COMPLEX *tmp;
NUMBER *err; NUMBER *err;
NUMBER *q;
/* initialize VALUE */ /* initialize VALUE */
result.v_subtype = V_NOSUBTYPE; result.v_subtype = V_NOSUBTYPE;
@@ -3695,10 +3674,8 @@ f_acos(int count, VALUE **vals)
return error_value(E_ACOS3); return error_value(E_ACOS3);
} }
if (result.v_type == V_COM && cisreal(result.v_com)) { if (result.v_type == V_COM && cisreal(result.v_com)) {
q = qlink(result.v_com->real); result.v_num = c_to_q(result.v_com, true);
comfree(result.v_com);
result.v_type = V_NUM; result.v_type = V_NUM;
result.v_num = q;
} }
return result; return result;
} }
@@ -3710,7 +3687,6 @@ f_asec(int count, VALUE **vals)
VALUE result; VALUE result;
COMPLEX *tmp; COMPLEX *tmp;
NUMBER *err; NUMBER *err;
NUMBER *q;
/* initialize VALUE */ /* initialize VALUE */
result.v_subtype = V_NOSUBTYPE; result.v_subtype = V_NOSUBTYPE;
@@ -3758,10 +3734,8 @@ f_asec(int count, VALUE **vals)
} }
if (result.v_type == V_COM) { if (result.v_type == V_COM) {
if (cisreal(result.v_com)) { if (cisreal(result.v_com)) {
q = qlink(result.v_com->real); result.v_num = c_to_q(result.v_com, true);
comfree(result.v_com);
result.v_type = V_NUM; result.v_type = V_NUM;
result.v_num = q;
} }
} }
return result; return result;
@@ -3774,7 +3748,6 @@ f_acsc(int count, VALUE **vals)
VALUE result; VALUE result;
COMPLEX *tmp; COMPLEX *tmp;
NUMBER *err; NUMBER *err;
NUMBER *q;
/* initialize VALUE */ /* initialize VALUE */
result.v_subtype = V_NOSUBTYPE; result.v_subtype = V_NOSUBTYPE;
@@ -3822,10 +3795,8 @@ f_acsc(int count, VALUE **vals)
} }
if (result.v_type == V_COM) { if (result.v_type == V_COM) {
if (cisreal(result.v_com)) { if (cisreal(result.v_com)) {
q = qlink(result.v_com->real); result.v_num = c_to_q(result.v_com, true);
comfree(result.v_com);
result.v_type = V_NUM; result.v_type = V_NUM;
result.v_num = q;
} }
} }
return result; return result;
@@ -3871,9 +3842,8 @@ f_asinh(int count, VALUE **vals)
result.v_type = V_COM; result.v_type = V_COM;
result.v_com = tmp; result.v_com = tmp;
if (cisreal(tmp)) { if (cisreal(tmp)) {
result.v_num = qlink(tmp->real); result.v_num = c_to_q(tmp, true);
result.v_type = V_NUM; result.v_type = V_NUM;
comfree(tmp);
} }
break; break;
default: default:
@@ -3889,7 +3859,6 @@ f_acosh(int count, VALUE **vals)
VALUE result; VALUE result;
COMPLEX *tmp; COMPLEX *tmp;
NUMBER *err; NUMBER *err;
NUMBER *q;
/* initialize VALUE */ /* initialize VALUE */
result.v_subtype = V_NOSUBTYPE; result.v_subtype = V_NOSUBTYPE;
@@ -3934,10 +3903,8 @@ f_acosh(int count, VALUE **vals)
return error_value(E_ACOSH3); return error_value(E_ACOSH3);
} }
if (result.v_type == V_COM && cisreal(result.v_com)) { if (result.v_type == V_COM && cisreal(result.v_com)) {
q = qlink(result.v_com->real); result.v_num = c_to_q(result.v_com, true);
comfree(result.v_com);
result.v_type = V_NUM; result.v_type = V_NUM;
result.v_num = q;
} }
return result; return result;
} }
@@ -3949,7 +3916,6 @@ f_atanh(int count, VALUE **vals)
VALUE result; VALUE result;
COMPLEX *tmp; COMPLEX *tmp;
NUMBER *err; NUMBER *err;
NUMBER *q;
/* initialize VALUE */ /* initialize VALUE */
result.v_subtype = V_NOSUBTYPE; result.v_subtype = V_NOSUBTYPE;
@@ -3995,10 +3961,8 @@ f_atanh(int count, VALUE **vals)
} }
if (result.v_type == V_COM) { if (result.v_type == V_COM) {
if (cisreal(result.v_com)) { if (cisreal(result.v_com)) {
q = qlink(result.v_com->real); result.v_num = c_to_q(result.v_com, true);
comfree(result.v_com);
result.v_type = V_NUM; result.v_type = V_NUM;
result.v_num = q;
} }
} }
return result; return result;
@@ -4011,7 +3975,6 @@ f_acoth(int count, VALUE **vals)
VALUE result; VALUE result;
COMPLEX *tmp; COMPLEX *tmp;
NUMBER *err; NUMBER *err;
NUMBER *q;
/* initialize VALUE */ /* initialize VALUE */
result.v_subtype = V_NOSUBTYPE; result.v_subtype = V_NOSUBTYPE;
@@ -4057,10 +4020,8 @@ f_acoth(int count, VALUE **vals)
} }
if (result.v_type == V_COM) { if (result.v_type == V_COM) {
if (cisreal(result.v_com)) { if (cisreal(result.v_com)) {
q = qlink(result.v_com->real); result.v_num = c_to_q(result.v_com, true);
comfree(result.v_com);
result.v_type = V_NUM; result.v_type = V_NUM;
result.v_num = q;
} }
} }
return result; return result;
@@ -4073,7 +4034,6 @@ f_asech(int count, VALUE **vals)
VALUE result; VALUE result;
COMPLEX *tmp; COMPLEX *tmp;
NUMBER *err; NUMBER *err;
NUMBER *q;
/* initialize VALUE */ /* initialize VALUE */
result.v_subtype = V_NOSUBTYPE; result.v_subtype = V_NOSUBTYPE;
@@ -4121,10 +4081,8 @@ f_asech(int count, VALUE **vals)
} }
if (result.v_type == V_COM) { if (result.v_type == V_COM) {
if (cisreal(result.v_com)) { if (cisreal(result.v_com)) {
q = qlink(result.v_com->real); result.v_num = c_to_q(result.v_com, true);
comfree(result.v_com);
result.v_type = V_NUM; result.v_type = V_NUM;
result.v_num = q;
} }
} }
return result; return result;
@@ -4137,7 +4095,6 @@ f_acsch(int count, VALUE **vals)
VALUE result; VALUE result;
COMPLEX *tmp; COMPLEX *tmp;
NUMBER *err; NUMBER *err;
NUMBER *q;
/* initialize VALUE */ /* initialize VALUE */
result.v_subtype = V_NOSUBTYPE; result.v_subtype = V_NOSUBTYPE;
@@ -4185,10 +4142,8 @@ f_acsch(int count, VALUE **vals)
} }
if (result.v_type == V_COM) { if (result.v_type == V_COM) {
if (cisreal(result.v_com)) { if (cisreal(result.v_com)) {
q = qlink(result.v_com->real); result.v_num = c_to_q(result.v_com, true);
comfree(result.v_com);
result.v_type = V_NUM; result.v_type = V_NUM;
result.v_num = q;
} }
} }
return result; return result;
@@ -4200,7 +4155,6 @@ f_gd(int count, VALUE **vals)
{ {
VALUE result; VALUE result;
NUMBER *eps; NUMBER *eps;
NUMBER *q;
COMPLEX *tmp; COMPLEX *tmp;
/* initialize VALUE */ /* initialize VALUE */
@@ -4245,9 +4199,7 @@ f_gd(int count, VALUE **vals)
if (result.v_com == NULL) if (result.v_com == NULL)
return error_value(E_GD3); return error_value(E_GD3);
if (cisreal(result.v_com)) { if (cisreal(result.v_com)) {
q = qlink(result.v_com->real); result.v_num = c_to_q(result.v_com, true);
comfree(result.v_com);
result.v_num = q;
result.v_type = V_NUM; result.v_type = V_NUM;
} }
return result; return result;
@@ -4259,7 +4211,6 @@ f_agd(int count, VALUE **vals)
{ {
VALUE result; VALUE result;
NUMBER *eps; NUMBER *eps;
NUMBER *q;
COMPLEX *tmp; COMPLEX *tmp;
/* initialize VALUE */ /* initialize VALUE */
@@ -4304,9 +4255,7 @@ f_agd(int count, VALUE **vals)
if (result.v_com == NULL) if (result.v_com == NULL)
return error_value(E_AGD3); return error_value(E_AGD3);
if (cisreal(result.v_com)) { if (cisreal(result.v_com)) {
q = qlink(result.v_com->real); result.v_num = c_to_q(result.v_com, true);
comfree(result.v_com);
result.v_num = q;
result.v_type = V_NUM; result.v_type = V_NUM;
} }
return result; return result;
@@ -5974,9 +5923,8 @@ f_polar(int count, VALUE **vals)
result.v_com = c; result.v_com = c;
result.v_type = V_COM; result.v_type = V_COM;
if (cisreal(c)) { if (cisreal(c)) {
result.v_num = qlink(c->real); result.v_num = c_to_q(c, true);
result.v_type = V_NUM; result.v_type = V_NUM;
comfree(c);
} }
return result; return result;
} }
@@ -10660,9 +10608,8 @@ f_versin(int count, VALUE **vals)
* case: complex trig function returned real, convert result to NUMBER * case: complex trig function returned real, convert result to NUMBER
*/ */
if (cisreal(c)) { if (cisreal(c)) {
result.v_num = qlink(c->real); result.v_num = c_to_q(c, true);
result.v_type = V_NUM; result.v_type = V_NUM;
comfree(c);
} }
break; break;
default: default:
@@ -10717,7 +10664,8 @@ f_aversin(int count, VALUE **vals)
*/ */
} else { } else {
/* convert NUMBER argument from NUMBER to COMPLEX */ /* convert NUMBER argument from NUMBER to COMPLEX */
vals[0]->v_com = qqtoc(vals[0]->v_num, &_qone_); /* XXX - WRONG - do not change the arg! */
vals[0]->v_com = qqtoc(vals[0]->v_num, &_qzero_);
vals[0]->v_type = V_COM; vals[0]->v_type = V_COM;
} }
} }
@@ -10738,9 +10686,8 @@ f_aversin(int count, VALUE **vals)
* case: complex trig function returned real, convert result to NUMBER * case: complex trig function returned real, convert result to NUMBER
*/ */
if (cisreal(c)) { if (cisreal(c)) {
result.v_num = qlink(c->real); result.v_num = c_to_q(c, true);
result.v_type = V_NUM; result.v_type = V_NUM;
comfree(c);
} }
} }
if (vals[0]->v_type != V_NUM && vals[0]->v_type != V_COM) { if (vals[0]->v_type != V_NUM && vals[0]->v_type != V_COM) {
@@ -10800,9 +10747,8 @@ f_coversin(int count, VALUE **vals)
* case: complex trig function returned real, convert result to NUMBER * case: complex trig function returned real, convert result to NUMBER
*/ */
if (cisreal(c)) { if (cisreal(c)) {
result.v_num = qlink(c->real); result.v_num = c_to_q(c, true);
result.v_type = V_NUM; result.v_type = V_NUM;
comfree(c);
} }
break; break;
default: default:
@@ -10857,7 +10803,8 @@ f_acoversin(int count, VALUE **vals)
*/ */
} else { } else {
/* convert NUMBER argument from NUMBER to COMPLEX */ /* convert NUMBER argument from NUMBER to COMPLEX */
vals[0]->v_com = qqtoc(vals[0]->v_num, &_qone_); /* XXX - WRONG - do not change the arg! */
vals[0]->v_com = qqtoc(vals[0]->v_num, &_qzero_);
vals[0]->v_type = V_COM; vals[0]->v_type = V_COM;
} }
} }
@@ -10878,9 +10825,8 @@ f_acoversin(int count, VALUE **vals)
* case: complex trig function returned real, convert result to NUMBER * case: complex trig function returned real, convert result to NUMBER
*/ */
if (cisreal(c)) { if (cisreal(c)) {
result.v_num = qlink(c->real); result.v_num = c_to_q(c, true);
result.v_type = V_NUM; result.v_type = V_NUM;
comfree(c);
} }
} }
if (vals[0]->v_type != V_NUM && vals[0]->v_type != V_COM) { if (vals[0]->v_type != V_NUM && vals[0]->v_type != V_COM) {

View File

@@ -24,7 +24,7 @@ EXAMPLE
0.5236 0.5235987756 0.523598775598299 0.52359877559829887308 0.5236 0.5235987756 0.523598775598299 0.52359877559829887308
; print acoversin(1), acoversin(-5), acoversin(2 + 3i) ; print acoversin(1), acoversin(-5), acoversin(2 + 3i)
0 1.40341337183925787843-2.49215996813383545614i -0.30760364953071124992-1.86416154415788242834i 0 1.57079632679489661923-2.47788873028847500481i -0.30760364953071124992-1.86416154415788242834i
LIMITS LIMITS
0 < eps < 1 0 < eps < 1

View File

@@ -24,7 +24,7 @@ EXAMPLE
1.0472 1.0471975512 1.047197551196598 1.04719755119659774615 1.0472 1.0471975512 1.047197551196598 1.04719755119659774615
; print aversin(0), aversin(-5), aversin(2 + 3i) ; print aversin(0), aversin(-5), aversin(2 + 3i)
0 0.16738295495563874081+2.49215996813383545614i 1.87839997632560786916+1.86416154415788242831i 0 2.47788873028847500485i 1.87839997632560786916+1.86416154415788242831i
LIMITS LIMITS
0 < eps < 1 0 < eps < 1