diff --git a/src/db/dbConvert.c b/src/db/dbConvert.c index 181387568..d9708e750 100644 --- a/src/db/dbConvert.c +++ b/src/db/dbConvert.c @@ -16,6 +16,8 @@ of this distribution. #include #include #include +#include +#include #include "dbDefs.h" #include "errlog.h" @@ -32,6 +34,18 @@ of this distribution. #include "recGbl.h" #include "dbConvert.h" +/*safe double to float conversion*/ +static void safeDoubleToFloat(double *pd,float *pf) +{ + double abs = fabs(*pd); + if(abs>=FLT_MAX) { + if(*pd>0.0) *pf = FLT_MAX; else *pf = -FLT_MAX; + } else if(abs<=FLT_MIN) { + if(*pd>0.0) *pf = FLT_MIN; else *pf = -FLT_MIN; + } else { + *pf = *pd; + } +} /* DATABASE ACCESS GET CONVERSION SUPPORT */ static long getStringString ( @@ -1881,12 +1895,13 @@ static long getDoubleFloat( double *psrc=(double *)(paddr->pfield); if(nRequest==1 && offset==0) { - *pbuffer = *psrc; + safeDoubleToFloat(psrc,pbuffer); return(0); } psrc += offset; while (nRequest) { - *pbuffer++ = *psrc++; + safeDoubleToFloat(psrc,pbuffer); + ++psrc; ++pbuffer; if(++offset==no_elements) psrc=(double *)paddr->pfield; nRequest--; } @@ -4090,12 +4105,13 @@ static long putDoubleFloat( float *pdest=(float *)(paddr->pfield); if(nRequest==1 && offset==0) { - *pdest = *pbuffer; + safeDoubleToFloat(pbuffer,pdest); return(0); } pdest += offset; while (nRequest) { - *pdest++ = *pbuffer++; + safeDoubleToFloat(pbuffer,pdest); + ++pbuffer; ++pdest; if(++offset==no_elements) pdest=(float *)paddr->pfield; nRequest--; } diff --git a/src/db/dbFastLinkConv.c b/src/db/dbFastLinkConv.c index 399d1a7d2..f6a6375f4 100644 --- a/src/db/dbFastLinkConv.c +++ b/src/db/dbFastLinkConv.c @@ -32,6 +32,8 @@ #include #include #include +#include +#include #include "dbDefs.h" #include "errlog.h" @@ -932,7 +934,17 @@ static long cvt_d_f( double *from, float *to, struct dbAddr *paddr) - { *to=*from; return(0); } +{ + double abs = fabs(*from); + if(abs>=FLT_MAX) { + if(*from>0.0) *to = FLT_MAX; else *to = -FLT_MAX; + } else if(abs<=FLT_MIN) { + if(*from>0.0) *to = FLT_MIN; else *to = -FLT_MIN; + } else { + *to = *from; + } + return(0); +} /* Convert Double to Double */ static long cvt_d_d( diff --git a/src/db/db_access.c b/src/db/db_access.c index 5a380dd92..06ee1ff2e 100644 --- a/src/db/db_access.c +++ b/src/db/db_access.c @@ -49,6 +49,8 @@ #include #include #include +#include +#include #include "dbDefs.h" #include "errlog.h" @@ -484,9 +486,18 @@ struct dbr_ctrl_double{ double value; /* current value */ }; - - - +/*safe double to float conversion*/ +static void safeDoubleToFloat(double *pd,float *pf) +{ + double abs = fabs(*pd); + if(abs>=FLT_MAX) { + if(*pd>0.0) *pf = FLT_MAX; else *pf = -FLT_MAX; + } else if(abs<=FLT_MIN) { + if(*pd>0.0) *pf = FLT_MIN; else *pf = -FLT_MIN; + } else { + *pf = *pd; + } +} /* From $cs/dblib/src/dbiocsubs.c * subroutines @@ -1060,12 +1071,12 @@ void *pfl pold->precision = new.precision; strncpy(pold->units,new.units,MAX_UNITS_SIZE); pold->units[MAX_UNITS_SIZE-1] = '\0'; - pold->upper_disp_limit = new.upper_disp_limit; - pold->lower_disp_limit = new.lower_disp_limit; - pold->upper_alarm_limit = new.upper_alarm_limit; - pold->upper_warning_limit = new.upper_warning_limit; - pold->lower_warning_limit = new.lower_warning_limit; - pold->lower_alarm_limit = new.lower_alarm_limit; + safeDoubleToFloat(&new.upper_disp_limit,&pold->upper_disp_limit); + safeDoubleToFloat(&new.lower_disp_limit,&pold->lower_disp_limit); + safeDoubleToFloat(&new.upper_alarm_limit,&pold->upper_alarm_limit); + safeDoubleToFloat(&new.upper_warning_limit,&pold->upper_warning_limit); + safeDoubleToFloat(&new.lower_warning_limit,&pold->lower_warning_limit); + safeDoubleToFloat(&new.lower_alarm_limit,&pold->lower_alarm_limit); options=0; nRequest=no_elements; status = dbGetField(paddr,DBR_FLOAT,&(pold->value),&options, @@ -1233,14 +1244,14 @@ void *pfl pold->precision = new.precision; strncpy(pold->units,new.units,MAX_UNITS_SIZE); pold->units[MAX_UNITS_SIZE-1] = '\0'; - pold->upper_disp_limit = new.upper_disp_limit; - pold->lower_disp_limit = new.lower_disp_limit; - pold->upper_alarm_limit = new.upper_alarm_limit; - pold->upper_warning_limit = new.upper_warning_limit; - pold->lower_warning_limit = new.lower_warning_limit; - pold->lower_alarm_limit = new.lower_alarm_limit; - pold->upper_ctrl_limit = new.upper_ctrl_limit; - pold->lower_ctrl_limit = new.lower_ctrl_limit; + safeDoubleToFloat(&new.upper_disp_limit,&pold->upper_disp_limit); + safeDoubleToFloat(&new.lower_disp_limit,&pold->lower_disp_limit); + safeDoubleToFloat(&new.upper_alarm_limit,&pold->upper_alarm_limit); + safeDoubleToFloat(&new.upper_warning_limit,&pold->upper_warning_limit); + safeDoubleToFloat(&new.lower_warning_limit,&pold->lower_warning_limit); + safeDoubleToFloat(&new.lower_alarm_limit,&pold->lower_alarm_limit); + safeDoubleToFloat(&new.upper_ctrl_limit,&pold->upper_ctrl_limit); + safeDoubleToFloat(&new.lower_ctrl_limit,&pold->lower_ctrl_limit); options=0; nRequest=no_elements; status = dbGetField(paddr,DBR_FLOAT,&(pold->value),&options,