From 331979dfb91cc6761eace908dc2fb6463088abf0 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Mon, 11 Oct 2004 22:32:05 +0000 Subject: [PATCH] Improve handling of NaN values. In selRecord, replaced the 1e30 'magic number' with NaN and Inf values. --- src/rec/aiRecord.c | 7 ++++--- src/rec/aoRecord.c | 9 +++++---- src/rec/dfanoutRecord.c | 7 ++++--- src/rec/selRecord.c | 23 ++++++++++++++--------- src/rec/subRecord.c | 5 +++-- 5 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/rec/aiRecord.c b/src/rec/aiRecord.c index 6493c848d..dbf1a53ce 100644 --- a/src/rec/aiRecord.c +++ b/src/rec/aiRecord.c @@ -25,6 +25,7 @@ #include "dbDefs.h" #include "errlog.h" +#include "epicsMath.h" #include "alarm.h" #include "cvtTable.h" #include "dbAccess.h" @@ -285,7 +286,7 @@ static void checkAlarms(aiRecord *pai) double hyst, lalm, hihi, high, low, lolo; unsigned short hhsv, llsv, hsv, lsv; - if(pai->udf == TRUE ){ + if (pai->udf) { recGblSetSevr(pai,UDF_ALARM,INVALID_ALARM); return; } @@ -355,7 +356,7 @@ static void convert(aiRecord *pai) }else{ pai->val = val; } - pai->udf = FALSE; + pai->udf = isnan(pai->val); return; } @@ -419,7 +420,7 @@ static long readValue(aiRecord *pai) status = dbGetLink(&(pai->siol),DBR_DOUBLE,&(pai->sval),0,0); if (status==0){ pai->val=pai->sval; - pai->udf=FALSE; + pai->udf=isnan(pai->val); } status=2; /* dont convert */ } else { diff --git a/src/rec/aoRecord.c b/src/rec/aoRecord.c index 41078b461..32ca99ff4 100644 --- a/src/rec/aoRecord.c +++ b/src/rec/aoRecord.c @@ -25,6 +25,7 @@ #include "dbDefs.h" #include "epicsPrint.h" +#include "epicsMath.h" #include "alarm.h" #include "cvtTable.h" #include "dbAccess.h" @@ -121,7 +122,7 @@ static long init_record(struct aoRecord *pao, int pass) /* get the initial value if dol is a constant*/ if (pao->dol.type == CONSTANT) { if(recGblInitConstantLink(&pao->dol,DBF_DOUBLE,&pao->val)) - pao->udf = FALSE; + pao->udf = isnan(pao->val); } /* must have write_ao function defined */ @@ -156,7 +157,7 @@ static long init_record(struct aoRecord *pao, int pass) (void *)&pao->pbrk,&pao->lbrk)!=0) break; } pao->val = value; - pao->udf=FALSE; + pao->udf = isnan(value); break; case(2): /* no convert */ break; @@ -193,6 +194,7 @@ static long process(pao) value = pao->val; } if(!status) convert(pao, value); + pao->udf = isnan(pao->val); } /* check for alarms */ @@ -356,7 +358,7 @@ static void checkAlarms(pao) double hyst, lalm, hihi, high, low, lolo; unsigned short hhsv, llsv, hsv, lsv; - if(pao->udf == TRUE ){ + if (pao->udf) { recGblSetSevr(pao,UDF_ALARM,INVALID_ALARM); return; } @@ -413,7 +415,6 @@ static long fetch_value(pao,pvalue) recGblSetSevr(pao,LINK_ALARM,INVALID_ALARM); return(status); } - pao->udf = FALSE; if (pao->oif == aoOIF_Incremental) *pvalue += pao->val; diff --git a/src/rec/dfanoutRecord.c b/src/rec/dfanoutRecord.c index a388382ed..1d40c93ce 100644 --- a/src/rec/dfanoutRecord.c +++ b/src/rec/dfanoutRecord.c @@ -29,6 +29,7 @@ #include "dbDefs.h" #include "epicsPrint.h" +#include "epicsMath.h" #include "alarm.h" #include "dbAccess.h" #include "dbEvent.h" @@ -100,7 +101,7 @@ static long init_record(struct dfanoutRecord *pdfanout, int pass) recGblInitConstantLink(&pdfanout->sell,DBF_USHORT,&pdfanout->seln); /* get the initial value dol is a constant*/ if(recGblInitConstantLink(&pdfanout->dol,DBF_DOUBLE,&pdfanout->val)) - pdfanout->udf=FALSE; + pdfanout->udf = isnan(pdfanout->val); return(0); } @@ -113,7 +114,7 @@ static long process(struct dfanoutRecord *pdfanout) && (pdfanout->omsl == menuOmslclosed_loop)){ status = dbGetLink(&(pdfanout->dol),DBR_DOUBLE,&(pdfanout->val),0,0); if(pdfanout->dol.type!=CONSTANT && RTN_SUCCESS(status)) - pdfanout->udf=FALSE; + pdfanout->udf = isnan(pdfanout->val); } pdfanout->pact = TRUE; recGblGetTimeStamp(pdfanout); @@ -208,7 +209,7 @@ static void checkAlarms(struct dfanoutRecord *pdfanout) double hyst, lalm, hihi, high, low, lolo; unsigned short hhsv, llsv, hsv, lsv; - if(pdfanout->udf == TRUE ){ + if (pdfanout->udf) { recGblSetSevr(pdfanout,UDF_ALARM,INVALID_ALARM); return; } diff --git a/src/rec/selRecord.c b/src/rec/selRecord.c index 0b93a379a..fde140b20 100644 --- a/src/rec/selRecord.c +++ b/src/rec/selRecord.c @@ -25,6 +25,7 @@ #include "dbDefs.h" #include "epicsPrint.h" +#include "epicsMath.h" #include "alarm.h" #include "dbAccess.h" #include "dbEvent.h" @@ -89,6 +90,9 @@ static int do_sel(); static int fetch_values(); static void monitor(); +/* This needed to prevent the MS optimizer from barfing */ +static double divide(double num, double den) { return num / den; } + static long init_record(psel,pass) struct selRecord *psel; @@ -97,6 +101,7 @@ static long init_record(psel,pass) struct link *plink; int i; double *pvalue; + double NaN = divide(0.0, 0.0); if (pass==0) return(0); @@ -108,7 +113,7 @@ static long init_record(psel,pass) plink = &psel->inpa; pvalue = &psel->a; for(i=0; itype==CONSTANT) { recGblInitConstantLink(plink,DBF_DOUBLE,pvalue); } @@ -260,7 +265,7 @@ static void checkAlarms(psel) double hyst, lalm, hihi, high, low, lolo; unsigned short hhsv, llsv, hsv, lsv; - if(psel->udf == TRUE ){ + if (psel->udf){ recGblSetSevr(psel,UDF_ALARM,INVALID_ALARM); return; } @@ -358,16 +363,16 @@ struct selRecord *psel; /* pointer to selection record */ val = *(pvalue+psel->seln); break; case (SELECT_HIGH): - val = -1e+30; + val = divide(-1.0, 0.0); /* Start at -Inf */ for (i = 0; i < SEL_MAX; i++,pvalue++){ - if (val < *pvalue && *pvalue != 1e+30) + if (!isnan(*pvalue) && val < *pvalue) val = *pvalue; } break; case (SELECT_LOW): - val = 1e+30; + val = divide(1.0, 0.0); /* Start at +Inf */ for (i = 0; i < SEL_MAX; i++,pvalue++){ - if (val > *pvalue && *pvalue != 1e+30) + if (!isnan(*pvalue) && val > *pvalue) val = *pvalue; } break; @@ -375,7 +380,7 @@ struct selRecord *psel; /* pointer to selection record */ plink = &psel->inpa; order_inx = 0; for (i = 0; i < SEL_MAX; i++,pvalue++,plink++){ - if (*pvalue != 1e+30){ + if (!isnan(*pvalue)){ j = order_inx; while ((order[j-1] > *pvalue) && (j > 0)){ order[j] = order[j-1]; @@ -391,9 +396,9 @@ struct selRecord *psel; /* pointer to selection record */ recGblSetSevr(psel,SOFT_ALARM,MAJOR_ALARM); return(-1); } - if (val != 1e+30 && val != -1e+30 ){ + if (!isinf(val)){ psel->val=val; - psel->udf=FALSE; + psel->udf=isnan(psel->val); } else { recGblSetSevr(psel,UDF_ALARM,MAJOR_ALARM); /* If UDF is TRUE this alarm will be overwritten by checkAlarms*/ diff --git a/src/rec/subRecord.c b/src/rec/subRecord.c index bc5249d91..c52781050 100644 --- a/src/rec/subRecord.c +++ b/src/rec/subRecord.c @@ -25,6 +25,7 @@ #include "dbDefs.h" #include "epicsPrint.h" +#include "epicsMath.h" #include "registryFunction.h" #include "alarm.h" #include "callback.h" @@ -267,7 +268,7 @@ static void checkAlarms(psub) double hyst, lalm, hihi, high, low, lolo; unsigned short hhsv, llsv, hsv, lsv; - if(psub->udf == TRUE ){ + if (psub->udf) { recGblSetSevr(psub,UDF_ALARM,INVALID_ALARM); return; } @@ -378,6 +379,6 @@ struct subRecord *psub; /* pointer to subroutine record */ status = (*psubroutine)(psub); if(status < 0){ recGblSetSevr(psub,SOFT_ALARM,psub->brsv); - } else psub->udf = FALSE; + } else psub->udf = isnan(psub->val); return(status); }