roundm function

This commit is contained in:
John Kerl 2015-08-03 22:35:33 -04:00
parent 4d82aa42c8
commit 2162a6d439
3 changed files with 31 additions and 20 deletions

View file

@ -715,7 +715,8 @@ static function_lookup_t FUNCTION_LOOKUP_TABLE[] = {
{ FUNC_CLASS_MATH, "min", 2 , "min of two numbers; null loses"},
{ FUNC_CLASS_MATH, "pow", 2 , "Exponentiation; same as **."},
{ FUNC_CLASS_MATH, "qnorm", 1 , "Normal cumulative distribution function."},
{ FUNC_CLASS_MATH, "round", 1 , "Nearest integer."},
{ FUNC_CLASS_MATH, "round", 1 , "Round to nearest integer."},
{ FUNC_CLASS_MATH, "roundm", 2 , "Round to nearest multiple of m: roundm($x,$m) is the same as round($x/$m)*$m"},
{ FUNC_CLASS_MATH, "sin", 1 , "Trigonometric sine."},
{ FUNC_CLASS_MATH, "sinh", 1 , "Hyperbolic sine."},
{ FUNC_CLASS_MATH, "sqrt", 1 , "Square root."},
@ -918,25 +919,26 @@ lrec_evaluator_t* lrec_evaluator_alloc_from_unary_func_name(char* fnnm, lrec_eva
lrec_evaluator_t* lrec_evaluator_alloc_from_binary_func_name(char* fnnm,
lrec_evaluator_t* parg1, lrec_evaluator_t* parg2)
{
if (streq(fnnm, "&&")) { return lrec_evaluator_alloc_from_b_bb_func(b_bb_and_func, parg1, parg2);
} else if (streq(fnnm, "||")) { return lrec_evaluator_alloc_from_b_bb_func(b_bb_or_func, parg1, parg2);
} else if (streq(fnnm, "==")) { return lrec_evaluator_alloc_from_b_xx_func(eq_op_func, parg1, parg2);
} else if (streq(fnnm, "!=")) { return lrec_evaluator_alloc_from_b_xx_func(ne_op_func, parg1, parg2);
} else if (streq(fnnm, ">")) { return lrec_evaluator_alloc_from_b_xx_func(gt_op_func, parg1, parg2);
} else if (streq(fnnm, ">=")) { return lrec_evaluator_alloc_from_b_xx_func(ge_op_func, parg1, parg2);
} else if (streq(fnnm, "<")) { return lrec_evaluator_alloc_from_b_xx_func(lt_op_func, parg1, parg2);
} else if (streq(fnnm, "<=")) { return lrec_evaluator_alloc_from_b_xx_func(le_op_func, parg1, parg2);
} else if (streq(fnnm, ".")) { return lrec_evaluator_alloc_from_s_ss_func(s_ss_dot_func, parg1, parg2);
} else if (streq(fnnm, "+")) { return lrec_evaluator_alloc_from_f_ff_func(f_ff_plus_func, parg1, parg2);
} else if (streq(fnnm, "-")) { return lrec_evaluator_alloc_from_f_ff_func(f_ff_minus_func, parg1, parg2);
} else if (streq(fnnm, "*")) { return lrec_evaluator_alloc_from_f_ff_func(f_ff_times_func, parg1, parg2);
} else if (streq(fnnm, "/")) { return lrec_evaluator_alloc_from_f_ff_func(f_ff_divide_func, parg1, parg2);
} else if (streq(fnnm, "**")) { return lrec_evaluator_alloc_from_f_ff_func(f_ff_pow_func, parg1, parg2);
} else if (streq(fnnm, "pow")) { return lrec_evaluator_alloc_from_f_ff_func(f_ff_pow_func, parg1, parg2);
} else if (streq(fnnm, "%")) { return lrec_evaluator_alloc_from_f_ff_func(f_ff_mod_func, parg1, parg2);
} else if (streq(fnnm, "atan2")) { return lrec_evaluator_alloc_from_f_ff_func(f_ff_atan2_func, parg1, parg2);
} else if (streq(fnnm, "max")) { return lrec_evaluator_alloc_from_f_ff_nullable_func(f_ff_max_func, parg1, parg2);
} else if (streq(fnnm, "min")) { return lrec_evaluator_alloc_from_f_ff_nullable_func(f_ff_min_func, parg1, parg2);
if (streq(fnnm, "&&")) { return lrec_evaluator_alloc_from_b_bb_func(b_bb_and_func, parg1, parg2);
} else if (streq(fnnm, "||")) { return lrec_evaluator_alloc_from_b_bb_func(b_bb_or_func, parg1, parg2);
} else if (streq(fnnm, "==")) { return lrec_evaluator_alloc_from_b_xx_func(eq_op_func, parg1, parg2);
} else if (streq(fnnm, "!=")) { return lrec_evaluator_alloc_from_b_xx_func(ne_op_func, parg1, parg2);
} else if (streq(fnnm, ">")) { return lrec_evaluator_alloc_from_b_xx_func(gt_op_func, parg1, parg2);
} else if (streq(fnnm, ">=")) { return lrec_evaluator_alloc_from_b_xx_func(ge_op_func, parg1, parg2);
} else if (streq(fnnm, "<")) { return lrec_evaluator_alloc_from_b_xx_func(lt_op_func, parg1, parg2);
} else if (streq(fnnm, "<=")) { return lrec_evaluator_alloc_from_b_xx_func(le_op_func, parg1, parg2);
} else if (streq(fnnm, ".")) { return lrec_evaluator_alloc_from_s_ss_func(s_ss_dot_func, parg1, parg2);
} else if (streq(fnnm, "+")) { return lrec_evaluator_alloc_from_f_ff_func(f_ff_plus_func, parg1, parg2);
} else if (streq(fnnm, "-")) { return lrec_evaluator_alloc_from_f_ff_func(f_ff_minus_func, parg1, parg2);
} else if (streq(fnnm, "*")) { return lrec_evaluator_alloc_from_f_ff_func(f_ff_times_func, parg1, parg2);
} else if (streq(fnnm, "/")) { return lrec_evaluator_alloc_from_f_ff_func(f_ff_divide_func, parg1, parg2);
} else if (streq(fnnm, "**")) { return lrec_evaluator_alloc_from_f_ff_func(f_ff_pow_func, parg1, parg2);
} else if (streq(fnnm, "pow")) { return lrec_evaluator_alloc_from_f_ff_func(f_ff_pow_func, parg1, parg2);
} else if (streq(fnnm, "%")) { return lrec_evaluator_alloc_from_f_ff_func(f_ff_mod_func, parg1, parg2);
} else if (streq(fnnm, "atan2")) { return lrec_evaluator_alloc_from_f_ff_func(f_ff_atan2_func, parg1, parg2);
} else if (streq(fnnm, "max")) { return lrec_evaluator_alloc_from_f_ff_nullable_func(f_ff_max_func, parg1, parg2);
} else if (streq(fnnm, "min")) { return lrec_evaluator_alloc_from_f_ff_nullable_func(f_ff_min_func, parg1, parg2);
} else if (streq(fnnm, "roundm")) { return lrec_evaluator_alloc_from_f_ff_nullable_func(f_ff_roundm_func, parg1, parg2);
} else { return NULL; /* xxx handle me better */ }
}

View file

@ -179,11 +179,19 @@ static inline mv_t f_ff_mod_func(mv_t* pval1, mv_t* pval2) {
mv_t rv = {.type = MT_DOUBLE, .u.dblv = (double)i3};
return rv;
}
static inline mv_t f_ff_atan2_func(mv_t* pval1, mv_t* pval2) {
mv_t rv = {.type = MT_DOUBLE, .u.dblv = atan2(pval1->u.dblv, pval2->u.dblv)};
return rv;
}
static inline mv_t f_ff_roundm_func(mv_t* pval1, mv_t* pval2) {
double x = pval1->u.dblv;
double m = pval2->u.dblv;
mv_t rv = {.type = MT_DOUBLE, .u.dblv = round(x / m) * m};
return rv;
}
// ----------------------------------------------------------------
mv_t s_s_tolower_func(mv_t* pval1);
mv_t s_s_toupper_func(mv_t* pval1);

View file

@ -5,6 +5,7 @@
TOP OF LIST
* roundm function: round to multiple of m
-> UTs
!! booleans into put-dsl: should be able to do: mlr put '$ok = $x < 10'
-> boolean literal parsing? on by default? doc why not if not. (various words in text columns,