FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
eval.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include <math.h>
20 #include <stdio.h>
21 #include <string.h>
22 
23 #include "libavutil/libm.h"
24 #include "libavutil/timer.h"
25 #include "libavutil/eval.h"
26 
27 static const double const_values[] = {
28  M_PI,
29  M_E,
30  0
31 };
32 
33 static const char *const const_names[] = {
34  "PI",
35  "E",
36  0
37 };
38 
39 int main(int argc, char **argv)
40 {
41  int i;
42  double d;
43  const char *const *expr;
44  static const char *const exprs[] = {
45  "",
46  "1;2",
47  "-20",
48  "-PI",
49  "+PI",
50  "1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)",
51  "80G/80Gi",
52  "1k",
53  "1Gi",
54  "1gi",
55  "1GiFoo",
56  "1k+1k",
57  "1Gi*3foo",
58  "foo",
59  "foo(",
60  "foo()",
61  "foo)",
62  "sin",
63  "sin(",
64  "sin()",
65  "sin)",
66  "sin 10",
67  "sin(1,2,3)",
68  "sin(1 )",
69  "1",
70  "1foo",
71  "bar + PI + E + 100f*2 + foo",
72  "13k + 12f - foo(1, 2)",
73  "1gi",
74  "1Gi",
75  "st(0, 123)",
76  "st(1, 123); ld(1)",
77  "lte(0, 1)",
78  "lte(1, 1)",
79  "lte(1, 0)",
80  "lt(0, 1)",
81  "lt(1, 1)",
82  "gt(1, 0)",
83  "gt(2, 7)",
84  "gte(122, 122)",
85  /* compute 1+2+...+N */
86  "st(0, 1); while(lte(ld(0), 100), st(1, ld(1)+ld(0));st(0, ld(0)+1)); ld(1)",
87  /* compute Fib(N) */
88  "st(1, 1); st(2, 2); st(0, 1); while(lte(ld(0),10), st(3, ld(1)+ld(2)); st(1, ld(2)); st(2, ld(3)); st(0, ld(0)+1)); ld(3)",
89  "while(0, 10)",
90  "st(0, 1); while(lte(ld(0),100), st(1, ld(1)+ld(0)); st(0, ld(0)+1))",
91  "isnan(1)",
92  "isnan(NAN)",
93  "isnan(INF)",
94  "isinf(1)",
95  "isinf(NAN)",
96  "isinf(INF)",
97  "floor(NAN)",
98  "floor(123.123)",
99  "floor(-123.123)",
100  "trunc(123.123)",
101  "trunc(-123.123)",
102  "ceil(123.123)",
103  "ceil(-123.123)",
104  "sqrt(1764)",
105  "isnan(sqrt(-1))",
106  "not(1)",
107  "not(NAN)",
108  "not(0)",
109  "6.0206dB",
110  "-3.0103dB",
111  "pow(0,1.23)",
112  "pow(PI,1.23)",
113  "PI^1.23",
114  "pow(-1,1.23)",
115  "if(1, 2)",
116  "if(1, 1, 2)",
117  "if(0, 1, 2)",
118  "ifnot(0, 23)",
119  "ifnot(1, NaN) + if(0, 1)",
120  "ifnot(1, 1, 2)",
121  "ifnot(0, 1, 2)",
122  "taylor(1, 1)",
123  "taylor(eq(mod(ld(1),4),1)-eq(mod(ld(1),4),3), PI/2, 1)",
124  "root(sin(ld(0))-1, 2)",
125  "root(sin(ld(0))+6+sin(ld(0)/12)-log(ld(0)), 100)",
126  "7000000B*random(0)",
127  "squish(2)",
128  "gauss(0.1)",
129  "hypot(4,3)",
130  "gcd(30,55)*print(min(9,1))",
131  "bitor(42, 12)",
132  "bitand(42, 12)",
133  "bitand(NAN, 1)",
134  "between(10, -3, 10)",
135  "between(-4, -2, -1)",
136  "between(1,2)",
137  "clip(0, 2, 1)",
138  "clip(0/0, 1, 2)",
139  "clip(0, 0/0, 1)",
140  NULL
141  };
142  int ret;
143 
144  for (expr = exprs; *expr; expr++) {
145  printf("Evaluating '%s'\n", *expr);
146  ret = av_expr_parse_and_eval(&d, *expr,
148  NULL, NULL, NULL, NULL, NULL, 0, NULL);
149  if (isnan(d))
150  printf("'%s' -> nan\n\n", *expr);
151  else
152  printf("'%s' -> %f\n\n", *expr, d);
153  if (ret < 0)
154  printf("av_expr_parse_and_eval failed\n");
155  }
156 
157  ret = av_expr_parse_and_eval(&d, "1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)",
159  NULL, NULL, NULL, NULL, NULL, 0, NULL);
160  printf("%f == 12.7\n", d);
161  if (ret < 0)
162  printf("av_expr_parse_and_eval failed\n");
163  ret = av_expr_parse_and_eval(&d, "80G/80Gi",
165  NULL, NULL, NULL, NULL, NULL, 0, NULL);
166  printf("%f == 0.931322575\n", d);
167  if (ret < 0)
168  printf("av_expr_parse_and_eval failed\n");
169 
170  if (argc > 1 && !strcmp(argv[1], "-t")) {
171  for (i = 0; i < 1050; i++) {
172  START_TIMER;
173  ret = av_expr_parse_and_eval(&d, "1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)",
175  NULL, NULL, NULL, NULL, NULL, 0, NULL);
176  if (ret < 0)
177  printf("av_expr_parse_and_eval failed\n");
178  STOP_TIMER("av_expr_parse_and_eval");
179  }
180  }
181 
182  return 0;
183 }
#define NULL
Definition: coverity.c:32
high precision timer, useful to profile code
static const double const_values[]
Definition: eval.c:27
int av_expr_parse_and_eval(double *d, const char *s, const char *const *const_names, const double *const_values, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), void *opaque, int log_offset, void *log_ctx)
Parse and evaluate an expression.
Definition: eval.c:726
#define M_E
Definition: mathematics.h:37
int main(int argc, char **argv)
Definition: eval.c:39
#define START_TIMER
Definition: timer.h:94
Replacements for frequently missing libm functions.
#define isnan(x)
Definition: libm.h:340
#define STOP_TIMER(id)
Definition: timer.h:95
#define M_PI
Definition: mathematics.h:52
static const char *const const_names[]
Definition: eval.c:33
simple arithmetic expression evaluator