eval

Table of Contents

Prototype: eval(expression, mode, options)

Return type: string

Description: Returns expression evaluated according to mode and options. Currently only the math and class modes with infix option are supported for evaluating traditional math expressions.

All the math is done with the C double type internally. The results are returned as a string. When the mode is math the returned value is a floating-point value formatted to 6 decimal places as a string.

Example:

  vars:
    # returns 20.000000
    "result" expression => eval("200/10", "math", "infix");

When the mode is class, the returned string is either false for 0 (!any) or true for anything else (any) so it can be used in an expression. The == operator (see below) is very convenient for this purpose. The actual accepted values for false allow a tiny margin around 0, just like ==.

Example:

  classes:
    # the class will be set
    "they_are_equal" expression => eval("20 == (200/10)", "class", "infix");

The supported infix mathematical syntax, in order of precedence, is:

  • ( and ) parentheses for grouping expressions
  • ^ operator for exponentiation
  • * and / operators for multiplication and division
  • % operators for modulo operation
  • + and - operators for addition and subtraction
  • == "close enough" operator to tell if two expressions evaluate to the same number, with a tiny margin to tolerate floating point errors. It returns 1 or 0.

The numbers can be in any format acceptable to the C scanf function with the %lf format specifier, followed by the k, m, g, t, or p SI units. So e.g. -100 and 2.34m are valid numbers.

In addition, the following constants are recognized:

  • e: 2.7182818284590452354
  • log2e: 1.4426950408889634074
  • log10e: 0.43429448190325182765
  • ln2: 0.69314718055994530942
  • ln10: 2.30258509299404568402
  • pi: 3.14159265358979323846
  • pi_2: 1.57079632679489661923 (pi over 2)
  • pi_4: 0.78539816339744830962 (pi over 4)
  • 1_pi: 0.31830988618379067154 (1 over pi)
  • 2_pi: 0.63661977236758134308 (2 over pi)
  • 2_sqrtpi: 1.12837916709551257390 (2 over square root of pi)
  • sqrt2: 1.41421356237309504880 (square root of 2)
  • sqrt1_2: 0.70710678118654752440 (square root of 1/2)

The following functions can be used, with parentheses:

  • ceil and floor: the next highest or the previous highest integer
  • log10, log2, log
  • sqrt
  • sin, cos, tan, asin, acos, atan
  • abs: absolute value
  • step: 0 if the argument is negative, 1 otherwise

Arguments:

  • expression: string, in the range: .*
  • mode: one of
    • math
    • class
  • options: one of
    • infix

Example:

body common control
{
      bundlesequence => { run };
}

bundle agent run
{
  vars:
      "values[0]" string => "x"; # bad
      "values[1]" string => "+ 200"; # bad
      "values[2]" string => "200 + 100";
      "values[3]" string => "200 - 100";
      "values[4]" string => "- - -"; # bad
      "values[5]" string => "2 + 3 - 1";
      "values[6]" string => ""; # 0
      "values[7]" string => "3 / 0"; # inf but not an error
      "values[8]" string => "3^3";
      "values[9]" string => "-1^2.1"; # -nan but not an error
      "values[10]" string => "sin(20)";
      "values[11]" string => "cos(20)";
      "values[19]" string => "20 % 3"; # remainder
      "values[20]" string => "sqrt(0.2)";
      "values[21]" string => "ceil(3.5)";
      "values[22]" string => "floor(3.4)";
      "values[23]" string => "abs(-3.4)";
      "values[24]" string => "-3.4 == -3.4";
      "values[25]" string => "-3.400000 == -3.400001";
      "values[26]" string => "e";
      "values[27]" string => "pi";
      "values[28]" string => "100m"; # 100 million
      "values[29]" string => "100k"; # 100 thousand

      "indices" slist => getindices("values");

      "eval[$(indices)]" string => eval("$(values[$(indices)])", "math", "infix");

  reports:
      "math/infix eval('$(values[$(indices)])') = '$(eval[$(indices)])'";
}

Output:

2013-09-14T08:34:16-0400     info: eval error: expression could not be parsed (input 'x')
2013-09-14T08:34:16-0400     info: eval error: expression could not be parsed (input '+ 200')
2013-09-14T08:34:16-0400     info: eval error: expression could not be parsed (input '- - -')
2013-09-14T08:34:16-0400   notice: R: math/prefix eval('x') = ''
2013-09-14T08:34:16-0400   notice: R: math/prefix eval('+ 200') = ''
2013-09-14T08:34:16-0400   notice: R: math/prefix eval('floor(3.4)') = '3.000000'
2013-09-14T08:34:16-0400   notice: R: math/prefix eval('sqrt(0.2)') = '0.447214'
2013-09-14T08:34:16-0400   notice: R: math/prefix eval('2 + 3 - 1') = '4.000000'
2013-09-14T08:34:16-0400   notice: R: math/prefix eval('sin(20)') = '0.912945'
2013-09-14T08:34:16-0400   notice: R: math/prefix eval('200 - 100') = '100.000000'
2013-09-14T08:34:16-0400   notice: R: math/prefix eval('20 % 3') = '2.000000'
2013-09-14T08:34:16-0400   notice: R: math/prefix eval('ceil(3.5)') = '4.000000'
2013-09-14T08:34:16-0400   notice: R: math/prefix eval('200 + 100') = '300.000000'
2013-09-14T08:34:16-0400   notice: R: math/prefix eval('pi') = '3.141593'
2013-09-14T08:34:16-0400   notice: R: math/prefix eval('- - -') = ''
2013-09-14T08:34:16-0400   notice: R: math/prefix eval('-3.400000 == -3.400001') = '0.000000'
2013-09-14T08:34:16-0400   notice: R: math/prefix eval('3 / 0') = 'inf'
2013-09-14T08:34:16-0400   notice: R: math/prefix eval('e') = '2.718282'
2013-09-14T08:34:16-0400   notice: R: math/prefix eval('cos(20)') = '0.408082'
2013-09-14T08:34:16-0400   notice: R: math/prefix eval('') = '0.000000'
2013-09-14T08:34:16-0400   notice: R: math/prefix eval('-1^2.1') = '-nan'
2013-09-14T08:34:16-0400   notice: R: math/prefix eval('abs(-3.4)') = '3.400000'
2013-09-14T08:34:16-0400   notice: R: math/prefix eval('-3.4 == -3.4') = '1.000000'
2013-09-14T08:34:16-0400   notice: R: math/prefix eval('3^3') = '27.000000'