Improve handling of NaN values.

In selRecord, replaced the 1e30 'magic number' with NaN and Inf values.
This commit is contained in:
Andrew Johnson
2004-10-11 22:32:05 +00:00
parent 4f731caf14
commit 331979dfb9
5 changed files with 30 additions and 21 deletions
+4 -3
View File
@@ -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 {
+5 -4
View File
@@ -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;
+4 -3
View File
@@ -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;
}
+14 -9
View File
@@ -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; i<SEL_MAX; i++, plink++, pvalue++) {
*pvalue = 1e+30;
*pvalue = NaN;
if (plink->type==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*/
+3 -2
View File
@@ -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);
}