/* Returns the p-level of a study if:
- p-level < 5% AND
- number of observations was at least 30.
- Otherwise, NaN is returned. */
-
-IF(// Review the results from the analysis
- AND(P_LEVEL <.05, N_OBS >=30),
-// ...and return the p-level if acceptable
- P_LEVEL,
-// or NaN if not
- NAN)
+
/* Returns the p-level of a study if:
+ p-level < 5% AND
+ number of observations was at least 30.
+1 Otherwise, NaN is returned. */
+
+IF(// Review the results from the analysis
+ AND(P_LEVEL <.05, N_OBS >=30),
+// ...and return the p-level if acceptable
+2 P_LEVEL,
+// or NaN if not
+ NAN)
Binding to Cus
}constchar* expression = argv[1];
-double x{0}, y{0};// x and y are bound at eval-time.
+te_type x{0}, y{0};// x and y are bound at eval-time.// Store variable names and pointers. te_parser tep; tep.set_variables_and_functions({{"x",&x},{"y",&y}});
@@ -358,7 +358,7 @@
Binding to Cus
Binding to Custom Functions
TinyExpr++ can call custom functions also. Here is a short example:
-
double my_sum(double a,double b)
+
te_type my_sum(te_type a,te_type b){/* Example function that adds two numbers together. */return a + b;
@@ -376,7 +376,7 @@
Binding to Custo
public:explicit te_expr_array(const te_variable_flags type)noexcept: te_expr(type){}
-std::array<double,5>m_data={5,6,7,8,9};
+std::array<te_type,5>m_data={5,6,7,8,9};};
Next, create two functions that can accept this object and perform actions on it. (Note that proper error handling is not included for brevity.):
// Returns the value of a cell from the object's data.
-double cell(const te_expr* context,double a)
+te_type cell(const te_expr* context,te_type a){auto* c =dynamic_cast<const te_expr_array*>(context);
-returnstatic_cast<double>(c->m_data[static_cast<size_t>(a)]);
+returnstatic_cast<te_type>(c->m_data[static_cast<size_t>(a)]);}// Returns the max value of the object's data.
-double cell_max(const te_expr* context)
+te_type cell_max(const te_expr* context){auto* c =dynamic_cast<const te_expr_array*>(context);
-returnstatic_cast<double>(
+returnstatic_cast<te_type>(*std::max_element(c->m_data.cbegin(), c->m_data.cend()));}
Finally, create an instance of the class and connect the custom functions to it, while also adding them to the parser:
Logical checks can also be nested, creating a “case”-like statement:
-
IF(AND(smartMeter1.power >1900, sensor1.temperature <52), TRUE,
-// First logical check failed, so now check another scenario
-// and return false if it meets our criteria.
- IF(AND(smartMeter1.power <300, sensor1.temperature >55), FALSE,
-// Neither scenario checked out, so the values are in an
-// unaccounted for scenario. Return NaN to indicate a failure.
- NAN))
+First logical check failed, so now check another scenario and return false if it meets our criteria.
+
+
2
+
+Neither scenario passed; return NaN because the values are in an unaccounted for scenario.
+
+
The same can be accomplished using the IFS() function:
-
IFS(AND(smartMeter1.power >1900, sensor1.temperature <52), TRUE,
-// First logical check failed, so now check another scenarios
-// and return false either meets our criteria.
- AND(smartMeter1.power <0), FALSE,
- AND(smartMeter1.power <300, sensor1.temperature >55), FALSE)
-
-// NaN is returned if no conditions were met and we are
-// in an unknown state.