From 2ebb9e5e4cd81f7f389600a475a6f3e4f8afc87f Mon Sep 17 00:00:00 2001 From: oetiker Date: Fri, 7 Mar 2008 08:57:01 +0000 Subject: [PATCH] a nan-safe add operator (ADDNAN) into rrd. I used it to add several incomplete graphs. NaN + NaN => NaN x + NaN => x NaN + y => y x + y => x + y -- Timo Stripf tstripf gmx.de git-svn-id: svn://svn.oetiker.ch/rrdtool/trunk/program@1303 a5681a0c-68f1-0310-ab6d-d61299d08faa --- doc/rrdgraph_rpn.pod | 5 +++++ src/rrd_rpncalc.c | 15 +++++++++++++++ src/rrd_rpncalc.h | 2 +- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/doc/rrdgraph_rpn.pod b/doc/rrdgraph_rpn.pod index 3718349..aabd738 100644 --- a/doc/rrdgraph_rpn.pod +++ b/doc/rrdgraph_rpn.pod @@ -99,6 +99,11 @@ B<+, -, *, /, %> Add, subtract, multiply, divide, modulo +B + +NAN-safe addition. If one parameter is NAN/UNKNOWN it'll be treated as +zero. If both parameters are NAN/UNKNOWN, NAN/UNKNOWN will be returned. + B Sine and cosine (input in radians), log and exp (natural logarithm), diff --git a/src/rrd_rpncalc.c b/src/rrd_rpncalc.c index ed08662..839643b 100644 --- a/src/rrd_rpncalc.c +++ b/src/rrd_rpncalc.c @@ -178,6 +178,7 @@ void rpn_compact2str( add_op(OP_DEG2RAD, DEG2RAD) add_op(OP_AVG, AVG) add_op(OP_ABS, ABS) + add_op(OP_ADDNAN, ADDNAN) #undef add_op } (*str)[offset] = '\0'; @@ -374,6 +375,7 @@ rpnp_t *rpn_parse( match_op(OP_DEG2RAD, DEG2RAD) match_op(OP_AVG, AVG) match_op(OP_ABS, ABS) + match_op(OP_ADDNAN, ADDNAN) #undef match_op else if ((sscanf(expr, DEF_NAM_FMT "%n", vname, &pos) == 1) && ((rpnp[steps].ptr = (*lookup) (key_hash, vname)) != @@ -543,6 +545,19 @@ short rpn_calc( + rpnstack->s[stptr]; stptr--; break; + case OP_ADDNAN: + stackunderflow(1); + if (isnan(rpnstack->s[stptr - 1])) { + rpnstack->s[stptr - 1] = rpnstack->s[stptr]; + } else if (isnan(rpnstack->s[stptr])) { + //rpnstack->s[stptr - 1] = rpnstack->s[stptr - 1]; + } else { + rpnstack->s[stptr - 1] = rpnstack->s[stptr - 1] + + rpnstack->s[stptr]; + } + + stptr--; + break; case OP_SUB: stackunderflow(1); rpnstack->s[stptr - 1] = rpnstack->s[stptr - 1] diff --git a/src/rrd_rpncalc.h b/src/rrd_rpncalc.h index b178f05..3e4da4c 100644 --- a/src/rrd_rpncalc.h +++ b/src/rrd_rpncalc.h @@ -18,7 +18,7 @@ enum op_en { OP_NUMBER = 0, OP_VARIABLE, OP_INF, OP_PREV, OP_NEGINF, OP_UN, OP_END, OP_LTIME, OP_NE, OP_ISINF, OP_PREV_OTHER, OP_COUNT, OP_ATAN, OP_SQRT, OP_SORT, OP_REV, OP_TREND, OP_TRENDNAN, OP_ATAN2, OP_RAD2DEG, OP_DEG2RAD, - OP_AVG, OP_ABS + OP_AVG, OP_ABS, OP_ADDNAN }; typedef struct rpnp_t { -- 2.11.0