From: Jorge G. <cl...@us...> - 2006-09-17 11:46:14
|
Update of /cvsroot/easycalc/easycalc/mlib In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv16404/mlib Modified Files: complex.c Log Message: fixed rounding errors in complex Index: complex.c =================================================================== RCS file: /cvsroot/easycalc/easycalc/mlib/complex.c,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** complex.c 12 Sep 2006 19:40:56 -0000 1.21 --- complex.c 17 Sep 2006 11:46:06 -0000 1.22 *************** *** 562,565 **** --- 562,566 ---- if ((err=stack_get_val2(stack,&arg1,&arg2,complex))) return err; + switch (func->num) { case FUNC_PLUS: *************** *** 592,601 **** return c_badfunc; } if (calcPrefs.reducePrecision) { result.real = reduce_precision(result.real); result.imag = reduce_precision(result.imag); } ! return stack_add_val(stack,&result,complex); } --- 593,612 ---- return c_badfunc; } + if (calcPrefs.reducePrecision) { + + if (fabs(result.real) < PRECISION_TO_ZERO) + result.real= 0.0; + else result.real = reduce_precision(result.real); + + if (fabs(result.imag) < PRECISION_TO_ZERO) + result.imag= 0.0; + else result.imag = reduce_precision(result.imag); } ! err=stack_add_val(stack,&result,complex); ! return err; } *************** *** 622,740 **** return err; ! if (func->num == FUNC_CONJ) { result.real = carg.real; result.imag = -carg.imag; return stack_add_val(stack,&result,complex); ! } ! if (func->num==MATH_ABS) { res = hypot(carg.real,carg.imag); return stack_add_val(stack,&res,real); ! } ! if (func->num==MATH_ANGLE) { res = atan2(carg.imag, carg.real); res = math_rad_to_user(res); ! return stack_add_val(stack,&res,real); ! } ! if (func->num==MATH_REAL) { res = carg.real; ! return stack_add_val(stack,&res,real); ! } ! if (func->num == MATH_IMAG) { res = carg.imag; ! return stack_add_val(stack,&res,real); ! } ! if (func->num==MATH_EXP) { // carg.imag = math_user_to_rad(carg.imag); result = cplx_exp(carg); ! return stack_add_val(stack,&result,complex); ! } ! if (func->num==MATH_SQRT) { result = cplx_sqrt(carg); ! return stack_add_val(stack,&result,complex); ! } ! if (func->num==MATH_LN || func->num==MATH_LOG || ! func->num==MATH_LOG2) { result = cplx_log(carg); result.imag = math_rad_to_user(result.imag); ! if (func->num==MATH_LOG) { ! result.real/=log(10); ! result.imag/=log(10); ! } ! else if (func->num==MATH_LOG2) { ! result.real/=log(2); ! result.imag/=log(2); ! } ! return stack_add_val(stack,&result,complex); ! } ! if (func->num==MATH_SIN || func->num==MATH_COS || ! func->num==MATH_TAN || func->num==MATH_SINH || ! func->num==MATH_COSH || func->num==MATH_TANH) { ! if (func->num == MATH_SIN || func->num == MATH_COS || ! func->num == MATH_TAN) ! carg.real = math_user_to_rad(carg.real); ! ! switch (func->num) { ! case MATH_SIN: ! result = cplx_sin(carg); ! break; ! case MATH_COS: ! result = cplx_cos(carg); ! break; ! case MATH_TAN: ! /* We really should have a separate function for this (and ! the hyperbolic tangent), but we're now weighing speed ! versus code size, and this is certainly smaller. */ ! result = cplx_div(cplx_sin(carg), cplx_cos(carg)); ! break; ! case MATH_SINH: ! result = cplx_sinh(carg); ! break; ! case MATH_COSH: ! result = cplx_cosh(carg); ! break; ! case MATH_TANH: ! result = cplx_div(cplx_sinh(carg),cplx_cosh(carg)); ! break; ! } ! return stack_add_val(stack,&result,complex); ! } ! if (func->num==MATH_ASIN || func->num==MATH_ACOS || ! func->num==MATH_ATAN || func->num==MATH_ASINH || ! func->num==MATH_ACOSH || func->num==MATH_ATANH) { ! /* These inverse trigonometric and hyperbolic functions only yield ! the value at the principal branch. */ ! ! switch(func->num) { ! case MATH_ASIN: ! result = cplx_asin(carg); ! break; ! case MATH_ACOS: ! result = cplx_acos(carg); ! break; ! case MATH_ATAN: ! result = cplx_atan(carg); ! break; ! case MATH_ASINH: ! result = cplx_asinh(carg); ! break; ! case MATH_ACOSH: ! result = cplx_acosh(carg); ! break; ! case MATH_ATANH: ! result = cplx_atanh(carg); ! break; ! default: ! return c_internal; ! break; ! } ! if (func->num == MATH_ASIN || func->num == MATH_ACOS || ! func->num == MATH_ATAN) ! result.real = math_rad_to_user(result.real); ! return stack_add_val(stack,&result,complex); } ! ! return c_internal; } --- 633,746 ---- return err; ! switch (func->num) { ! ! case FUNC_CONJ: result.real = carg.real; result.imag = -carg.imag; return stack_add_val(stack,&result,complex); ! case MATH_ABS: res = hypot(carg.real,carg.imag); return stack_add_val(stack,&res,real); ! case MATH_ANGLE: res = atan2(carg.imag, carg.real); res = math_rad_to_user(res); ! return stack_add_val(stack,&res,real); ! case MATH_REAL: res = carg.real; ! return stack_add_val(stack,&res,real); ! case MATH_IMAG: res = carg.imag; ! return stack_add_val(stack,&res,real); ! ! case MATH_EXP: // carg.imag = math_user_to_rad(carg.imag); result = cplx_exp(carg); ! break; ! case MATH_SQRT: result = cplx_sqrt(carg); ! break; ! ! case MATH_LN: result = cplx_log(carg); result.imag = math_rad_to_user(result.imag); + break; + case MATH_LOG: + result = cplx_log(carg); + result.imag = math_rad_to_user(result.imag); + result.real/=log(10); + result.imag/=log(10); + break; + case MATH_LOG2: + result = cplx_log(carg); + result.imag = math_rad_to_user(result.imag); + result.real/=log(2); + result.imag/=log(2); + break; ! case MATH_SIN: ! carg.real = math_user_to_rad(carg.real); ! result = cplx_sin(carg); ! break; ! case MATH_COS: ! carg.real = math_user_to_rad(carg.real); ! result = cplx_cos(carg); ! break; ! case MATH_TAN: ! carg.real = math_user_to_rad(carg.real); ! /* We really should have a separate function for this (and ! the hyperbolic tangent), but we're now weighing speed ! versus code size, and this is certainly smaller. */ ! result = cplx_div(cplx_sin(carg), cplx_cos(carg)); ! break; ! case MATH_SINH: ! result = cplx_sinh(carg); ! break; ! case MATH_COSH: ! result = cplx_cosh(carg); ! break; ! case MATH_TANH: ! result = cplx_div(cplx_sinh(carg),cplx_cosh(carg)); ! break; ! /* These inverse trigonometric and hyperbolic functions only yield ! the value at the principal branch. */ ! case MATH_ASIN: ! result = cplx_asin(carg); ! result.real = math_rad_to_user(result.real); ! break; ! case MATH_ACOS: ! result = cplx_acos(carg); ! result.real = math_rad_to_user(result.real); ! break; ! case MATH_ATAN: ! result = cplx_atan(carg); ! result.real = math_rad_to_user(result.real); ! break; ! case MATH_ASINH: ! result = cplx_asinh(carg); ! break; ! case MATH_ACOSH: ! result = cplx_acosh(carg); ! break; ! case MATH_ATANH: ! result = cplx_atanh(carg); ! break; ! default: ! return c_badfunc; ! } ! ! if (calcPrefs.reducePrecision) { ! if (fabs(result.real) < PRECISION_TO_ZERO) ! result.real= 0.0; ! else ! result.real = reduce_precision(result.real); ! if (fabs(result.imag) < PRECISION_TO_ZERO) ! result.imag= 0.0; ! else ! result.imag = reduce_precision(result.imag); } ! ! err=stack_add_val(stack,&result,complex); ! return err; } |