diff options
author | Steve Bennett <steveb@workware.net.au> | 2016-04-18 19:55:01 +1000 |
---|---|---|
committer | Steve Bennett <steveb@workware.net.au> | 2016-08-17 15:58:07 +1000 |
commit | a4f2aef246668e2d33f379093157d872d2db07f2 (patch) | |
tree | 2c11505b8270192ccab820a9ded82db648cdf3c7 | |
parent | ba16ea3bdd9c8d22a99a9a354327f2b5593822c4 (diff) | |
download | jimtcl-a4f2aef246668e2d33f379093157d872d2db07f2.zip jimtcl-a4f2aef246668e2d33f379093157d872d2db07f2.tar.gz jimtcl-a4f2aef246668e2d33f379093157d872d2db07f2.tar.bz2 |
expr: add support for atan2, hypot and fmod
And enable some more math tests
Signed-off-by: Steve Bennett <steveb@workware.net.au>
-rw-r--r-- | jim.c | 121 | ||||
-rw-r--r-- | tests/expr-old.test | 59 |
2 files changed, 96 insertions, 84 deletions
@@ -7617,6 +7617,7 @@ enum JIM_EXPROP_FUNC_ASIN, JIM_EXPROP_FUNC_ACOS, JIM_EXPROP_FUNC_ATAN, + JIM_EXPROP_FUNC_ATAN2, JIM_EXPROP_FUNC_SINH, JIM_EXPROP_FUNC_COSH, JIM_EXPROP_FUNC_TANH, @@ -7627,6 +7628,8 @@ enum JIM_EXPROP_FUNC_LOG10, JIM_EXPROP_FUNC_SQRT, JIM_EXPROP_FUNC_POW, + JIM_EXPROP_FUNC_HYPOT, + JIM_EXPROP_FUNC_FMOD, }; struct JimExprState @@ -7938,7 +7941,6 @@ static int JimExprOpIntBin(Jim_Interp *interp, struct JimExprState *e) /* A binary operation on two ints or two doubles (or two strings for some ops) */ static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e) { - int intresult = 1; int rc = JIM_OK; double dA, dB, dC = 0; jim_wide wA, wB, wC = 0; @@ -7956,20 +7958,21 @@ static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e) case JIM_EXPROP_POW: case JIM_EXPROP_FUNC_POW: wC = JimPowWide(wA, wB); - break; + goto intresult; case JIM_EXPROP_ADD: wC = wA + wB; - break; + goto intresult; case JIM_EXPROP_SUB: wC = wA - wB; - break; + goto intresult; case JIM_EXPROP_MUL: wC = wA * wB; - break; + goto intresult; case JIM_EXPROP_DIV: if (wB == 0) { Jim_SetResultString(interp, "Division by zero", -1); rc = JIM_ERR; + goto done; } else { /* @@ -7988,51 +7991,63 @@ static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e) if (wA % wB < 0) { wC--; } + goto intresult; } - break; case JIM_EXPROP_LT: wC = wA < wB; - break; + goto intresult; case JIM_EXPROP_GT: wC = wA > wB; - break; + goto intresult; case JIM_EXPROP_LTE: wC = wA <= wB; - break; + goto intresult; case JIM_EXPROP_GTE: wC = wA >= wB; - break; + goto intresult; case JIM_EXPROP_NUMEQ: wC = wA == wB; - break; + goto intresult; case JIM_EXPROP_NUMNE: wC = wA != wB; - break; - default: - abort(); + goto intresult; } } - else if (Jim_GetDouble(interp, A, &dA) == JIM_OK && Jim_GetDouble(interp, B, &dB) == JIM_OK) { - intresult = 0; + if (Jim_GetDouble(interp, A, &dA) == JIM_OK && Jim_GetDouble(interp, B, &dB) == JIM_OK) { switch (e->opcode) { +#ifndef JIM_MATH_FUNCTIONS case JIM_EXPROP_POW: case JIM_EXPROP_FUNC_POW: -#ifdef JIM_MATH_FUNCTIONS - dC = pow(dA, dB); -#else + case JIM_EXPROP_FUNC_ATAN2: + case JIM_EXPROP_FUNC_HYPOT: + case JIM_EXPROP_FUNC_FMOD: Jim_SetResultString(interp, "unsupported", -1); rc = JIM_ERR; + goto done; +#else + case JIM_EXPROP_POW: + case JIM_EXPROP_FUNC_POW: + dC = pow(dA, dB); + goto doubleresult; + case JIM_EXPROP_FUNC_ATAN2: + dC = atan2(dA, dB); + goto doubleresult; + case JIM_EXPROP_FUNC_HYPOT: + dC = hypot(dA, dB); + goto doubleresult; + case JIM_EXPROP_FUNC_FMOD: + dC = fmod(dA, dB); + goto doubleresult; #endif - break; case JIM_EXPROP_ADD: dC = dA + dB; - break; + goto doubleresult; case JIM_EXPROP_SUB: dC = dA - dB; - break; + goto doubleresult; case JIM_EXPROP_MUL: dC = dA * dB; - break; + goto doubleresult; case JIM_EXPROP_DIV: if (dB == 0) { #ifdef INFINITY @@ -8044,33 +8059,25 @@ static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e) else { dC = dA / dB; } - break; + goto doubleresult; case JIM_EXPROP_LT: wC = dA < dB; - intresult = 1; - break; + goto intresult; case JIM_EXPROP_GT: wC = dA > dB; - intresult = 1; - break; + goto intresult; case JIM_EXPROP_LTE: wC = dA <= dB; - intresult = 1; - break; + goto intresult; case JIM_EXPROP_GTE: wC = dA >= dB; - intresult = 1; - break; + goto intresult; case JIM_EXPROP_NUMEQ: wC = dA == dB; - intresult = 1; - break; + goto intresult; case JIM_EXPROP_NUMNE: wC = dA != dB; - intresult = 1; - break; - default: - abort(); + goto intresult; } } else { @@ -8082,41 +8089,36 @@ static int JimExprOpBin(Jim_Interp *interp, struct JimExprState *e) switch (e->opcode) { case JIM_EXPROP_LT: wC = i < 0; - break; + goto intresult; case JIM_EXPROP_GT: wC = i > 0; - break; + goto intresult; case JIM_EXPROP_LTE: wC = i <= 0; - break; + goto intresult; case JIM_EXPROP_GTE: wC = i >= 0; - break; + goto intresult; case JIM_EXPROP_NUMEQ: wC = i == 0; - break; + goto intresult; case JIM_EXPROP_NUMNE: wC = i != 0; - break; - default: - rc = JIM_ERR; - break; - } - } - - if (rc == JIM_OK) { - if (intresult) { - ExprPush(e, Jim_NewIntObj(interp, wC)); - } - else { - ExprPush(e, Jim_NewDoubleObj(interp, dC)); + goto intresult; } } - + /* If we get here, it is an error */ + rc = JIM_ERR; +done: Jim_DecrRefCount(interp, A); Jim_DecrRefCount(interp, B); - return rc; +intresult: + ExprPush(e, Jim_NewIntObj(interp, wC)); + goto done; +doubleresult: + ExprPush(e, Jim_NewDoubleObj(interp, dC)); + goto done; } static int JimSearchList(Jim_Interp *interp, Jim_Obj *listObjPtr, Jim_Obj *valObj) @@ -8408,6 +8410,7 @@ static const struct Jim_ExprOperator Jim_ExprOperators[] = { OPRINIT("asin", 200, 1, JimExprOpDoubleUnary), OPRINIT("acos", 200, 1, JimExprOpDoubleUnary), OPRINIT("atan", 200, 1, JimExprOpDoubleUnary), + OPRINIT("atan2", 200, 2, JimExprOpBin), OPRINIT("sinh", 200, 1, JimExprOpDoubleUnary), OPRINIT("cosh", 200, 1, JimExprOpDoubleUnary), OPRINIT("tanh", 200, 1, JimExprOpDoubleUnary), @@ -8418,6 +8421,8 @@ static const struct Jim_ExprOperator Jim_ExprOperators[] = { OPRINIT("log10", 200, 1, JimExprOpDoubleUnary), OPRINIT("sqrt", 200, 1, JimExprOpDoubleUnary), OPRINIT("pow", 200, 2, JimExprOpBin), + OPRINIT("hypot", 200, 2, JimExprOpBin), + OPRINIT("fmod", 200, 2, JimExprOpBin), #endif }; #undef OPRINIT diff --git a/tests/expr-old.test b/tests/expr-old.test index b1d722d..1021041 100644 --- a/tests/expr-old.test +++ b/tests/expr-old.test @@ -17,6 +17,15 @@ source [file dirname [info script]]/testing.tcl +# Jim Tcl may have no math functions, and may not have specific math functions +foreach {expr constraint} {sin(0) mathfunc fmod(0,1) expr_fmod hypot(0,1) expr_hypot} { + if {[catch {expr $expr} msg]} { + testConstraint $constraint 0 + } else { + testConstraint $constraint 1 + } +} + # First, test all of the integer operators individually. test expr-old-1.1 {integer operators} {expr -4} -4 @@ -556,72 +565,70 @@ test expr-old-31.4 {multiple arguments to expr command} { # Math functions -if {0} { -test expr-old-32.1 {math functions in expressions} { +test expr-old-32.1 {math functions in expressions} mathfunc { format %.6g [expr acos(0.5)] } {1.0472} -test expr-old-32.2 {math functions in expressions} { +test expr-old-32.2 {math functions in expressions} mathfunc { format %.6g [expr asin(0.5)] } {0.523599} -test expr-old-32.3 {math functions in expressions} { +test expr-old-32.3 {math functions in expressions} mathfunc { format %.6g [expr atan(1.0)] } {0.785398} -test expr-old-32.4 {math functions in expressions} { +test expr-old-32.4 {math functions in expressions} mathfunc { format %.6g [expr atan2(2.0, 2.0)] } {0.785398} -test expr-old-32.5 {math functions in expressions} { +test expr-old-32.5 {math functions in expressions} mathfunc { format %.6g [expr ceil(1.999)] } {2} -test expr-old-32.6 {math functions in expressions} { +test expr-old-32.6 {math functions in expressions} mathfunc { format %.6g [expr cos(.1)] } {0.995004} -test expr-old-32.7 {math functions in expressions} { +test expr-old-32.7 {math functions in expressions} mathfunc { format %.6g [expr cosh(.1)] } {1.005} -test expr-old-32.8 {math functions in expressions} { +test expr-old-32.8 {math functions in expressions} mathfunc { format %.6g [expr exp(1.0)] } {2.71828} -test expr-old-32.9 {math functions in expressions} { +test expr-old-32.9 {math functions in expressions} mathfunc { format %.6g [expr floor(2.000)] } {2} -test expr-old-32.10 {math functions in expressions} { +test expr-old-32.10 {math functions in expressions} mathfunc { format %.6g [expr floor(2.001)] } {2} -test expr-old-32.11 {math functions in expressions} { +test expr-old-32.11 {math functions in expressions} expr_fmod { format %.6g [expr fmod(7.3, 3.2)] } {0.9} -test expr-old-32.12 {math functions in expressions} { +test expr-old-32.12 {math functions in expressions} expr_hypot { format %.6g [expr hypot(3.0, 4.0)] } {5} -test expr-old-32.13 {math functions in expressions} { +test expr-old-32.13 {math functions in expressions} mathfunc { format %.6g [expr log(2.8)] } {1.02962} -test expr-old-32.14 {math functions in expressions} { +test expr-old-32.14 {math functions in expressions} mathfunc { format %.6g [expr log10(2.8)] } {0.447158} -test expr-old-32.15 {math functions in expressions} { +test expr-old-32.15 {math functions in expressions} mathfunc { format %.6g [expr pow(2.1, 3.1)] } {9.97424} -test expr-old-32.16 {math functions in expressions} { +test expr-old-32.16 {math functions in expressions} mathfunc { format %.6g [expr sin(.1)] } {0.0998334} -test expr-old-32.17 {math functions in expressions} { +test expr-old-32.17 {math functions in expressions} mathfunc { format %.6g [expr sinh(.1)] } {0.100167} -test expr-old-32.18 {math functions in expressions} { +test expr-old-32.18 {math functions in expressions} mathfunc { format %.6g [expr sqrt(2.0)] } {1.41421} -test expr-old-32.19 {math functions in expressions} { +test expr-old-32.19 {math functions in expressions} mathfunc { format %.6g [expr tan(0.8)] } {1.02964} -test expr-old-32.20 {math functions in expressions} { +test expr-old-32.20 {math functions in expressions} mathfunc { format %.6g [expr tanh(0.8)] } {0.664037} -} -test expr-old-32.21 {math functions in expressions} { +test expr-old-32.21 {math functions in expressions} mathfunc { format %.6g [expr abs(-1.8)] } {1.8} -test expr-old-32.22 {math functions in expressions} { +test expr-old-32.22 {math functions in expressions} mathfunc { expr abs(10.0) } {10.0} test expr-old-32.23 {math functions in expressions} { @@ -808,10 +815,10 @@ test expr-old-36.8 {ExprLooksLikeInt procedure} { test expr-old-36.9 {ExprLooksLikeInt procedure} { list [catch {expr 24E1} msg] $msg } {0 240.0} +} test expr-old-36.10 {ExprLooksLikeInt procedure} { list [catch {expr 78e} msg] $msg -} {1 {syntax error in expression "78e"}} -} +} {1 {syntax error in expression: "78e"}} # test for [Bug #542588] # XXX: Can't rely on overflow checking |