From: oetiker Date: Fri, 7 Mar 2008 08:57:01 +0000 (+0000) Subject: a nan-safe add operator (ADDNAN) into rrd. I used it to add several incomplete graphs. X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=3f29f218ee41c1413cd8823cdd463c13a7ff78e5;p=rrdtool-all.git 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@1303 a5681a0c-68f1-0310-ab6d-d61299d08faa --- diff --git a/program/doc/rrdgraph_rpn.pod b/program/doc/rrdgraph_rpn.pod index 3718349c..aabd7383 100644 --- a/program/doc/rrdgraph_rpn.pod +++ b/program/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/program/src/rrd_rpncalc.c b/program/src/rrd_rpncalc.c index ed086626..839643b0 100644 --- a/program/src/rrd_rpncalc.c +++ b/program/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/program/src/rrd_rpncalc.h b/program/src/rrd_rpncalc.h index b178f05f..3e4da4c7 100644 --- a/program/src/rrd_rpncalc.h +++ b/program/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 {