FFmpeg  4.0
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 "libavutil/timer.h"
20 
21 #include <math.h>
22 #include <stdio.h>
23 #include <string.h>
24 
25 #include "libavutil/libm.h"
26 #include "libavutil/eval.h"
27 
28 static const double const_values[] = {
29  M_PI,
30  M_E,
31  0
32 };
33 
34 static const char *const const_names[] = {
35  "PI",
36  "E",
37  0
38 };
39 
40 int main(int argc, char **argv)
41 {
42  int i;
43  double d;
44  const char *const *expr;
45  static const char *const exprs[] = {
46  "",
47  "1;2",
48  "-20",
49  "-PI",
50  "+PI",
51  "1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)",
52  "80G/80Gi",
53  "1k",
54  "1Gi",
55  "1gi",
56  "1GiFoo",
57  "1k+1k",
58  "1Gi*3foo",
59  "foo",
60  "foo(",
61  "foo()",
62  "foo)",
63  "sin",
64  "sin(",
65  "sin()",
66  "sin)",
67  "sin 10",
68  "sin(1,2,3)",
69  "sin(1 )",
70  "1",
71  "1foo",
72  "bar + PI + E + 100f*2 + foo",
73  "13k + 12f - foo(1, 2)",
74  "1gi",
75  "1Gi",
76  "st(0, 123)",
77  "st(1, 123); ld(1)",
78  "lte(0, 1)",
79  "lte(1, 1)",
80  "lte(1, 0)",
81  "lt(0, 1)",
82  "lt(1, 1)",
83  "gt(1, 0)",
84  "gt(2, 7)",
85  "gte(122, 122)",
86  /* compute 1+2+...+N */
87  "st(0, 1); while(lte(ld(0), 100), st(1, ld(1)+ld(0));st(0, ld(0)+1)); ld(1)",
88  /* compute Fib(N) */
89  "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)",
90  "while(0, 10)",
91  "st(0, 1); while(lte(ld(0),100), st(1, ld(1)+ld(0)); st(0, ld(0)+1))",
92  "isnan(1)",
93  "isnan(NAN)",
94  "isnan(INF)",
95  "isinf(1)",
96  "isinf(NAN)",
97  "isinf(INF)",
98  "floor(NAN)",
99  "floor(123.123)",
100  "floor(-123.123)",
101  "trunc(123.123)",
102  "trunc(-123.123)",
103  "ceil(123.123)",
104  "ceil(-123.123)",
105  "sqrt(1764)",
106  "isnan(sqrt(-1))",
107  "not(1)",
108  "not(NAN)",
109  "not(0)",
110  "6.0206dB",
111  "-3.0103dB",
112  "pow(0,1.23)",
113  "pow(PI,1.23)",
114  "PI^1.23",
115  "pow(-1,1.23)",
116  "if(1, 2)",
117  "if(1, 1, 2)",
118  "if(0, 1, 2)",
119  "ifnot(0, 23)",
120  "ifnot(1, NaN) + if(0, 1)",
121  "ifnot(1, 1, 2)",
122  "ifnot(0, 1, 2)",
123  "taylor(1, 1)",
124  "taylor(eq(mod(ld(1),4),1)-eq(mod(ld(1),4),3), PI/2, 1)",
125  "root(sin(ld(0))-1, 2)",
126  "root(sin(ld(0))+6+sin(ld(0)/12)-log(ld(0)), 100)",
127  "7000000B*random(0)",
128  "squish(2)",
129  "gauss(0.1)",
130  "hypot(4,3)",
131  "gcd(30,55)*print(min(9,1))",
132  "bitor(42, 12)",
133  "bitand(42, 12)",
134  "bitand(NAN, 1)",
135  "between(10, -3, 10)",
136  "between(-4, -2, -1)",
137  "between(1,2)",
138  "clip(0, 2, 1)",
139  "clip(0/0, 1, 2)",
140  "clip(0, 0/0, 1)",
141  NULL
142  };
143  int ret;
144 
145  for (expr = exprs; *expr; expr++) {
146  printf("Evaluating '%s'\n", *expr);
147  ret = av_expr_parse_and_eval(&d, *expr,
149  NULL, NULL, NULL, NULL, NULL, 0, NULL);
150  if (isnan(d))
151  printf("'%s' -> nan\n\n", *expr);
152  else
153  printf("'%s' -> %f\n\n", *expr, d);
154  if (ret < 0)
155  printf("av_expr_parse_and_eval failed\n");
156  }
157 
158  ret = av_expr_parse_and_eval(&d, "1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)",
160  NULL, NULL, NULL, NULL, NULL, 0, NULL);
161  printf("%f == 12.7\n", d);
162  if (ret < 0)
163  printf("av_expr_parse_and_eval failed\n");
164  ret = av_expr_parse_and_eval(&d, "80G/80Gi",
166  NULL, NULL, NULL, NULL, NULL, 0, NULL);
167  printf("%f == 0.931322575\n", d);
168  if (ret < 0)
169  printf("av_expr_parse_and_eval failed\n");
170 
171  if (argc > 1 && !strcmp(argv[1], "-t")) {
172  for (i = 0; i < 1050; i++) {
173  START_TIMER;
174  ret = av_expr_parse_and_eval(&d, "1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)",
176  NULL, NULL, NULL, NULL, NULL, 0, NULL);
177  if (ret < 0)
178  printf("av_expr_parse_and_eval failed\n");
179  STOP_TIMER("av_expr_parse_and_eval");
180  }
181  }
182 
183  return 0;
184 }
#define NULL
Definition: coverity.c:32
high precision timer, useful to profile code
static const double const_values[]
Definition: eval.c:28
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:744
#define M_E
Definition: mathematics.h:37
int main(int argc, char **argv)
Definition: eval.c:40
#define START_TIMER
Definition: timer.h:137
Replacements for frequently missing libm functions.
#define isnan(x)
Definition: libm.h:340
#define STOP_TIMER(id)
Definition: timer.h:138
#define M_PI
Definition: mathematics.h:52
static const char *const const_names[]
Definition: eval.c:34
simple arithmetic expression evaluator