EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  <20132014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  <20132014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: Re: Conversion problem from double to 32 bit unsigned int (in ao)
From: Benjamin Franksen <[email protected]>
To: <[email protected]>
Date: Thu, 11 Apr 2013 19:14:27 +0200
On Wednesday, April 10, 2013 10:20:34 Dirk Zimoch wrote:
> Today I found a strange problem. I have a device that has 32 bit
> unsigned int output registers. I want to scale an analog value (e.g.
> -10.0 .. +10.0) to the raw range 0x00000000 ... 0xffffffff.

I could have told you that this is impossible before reading further, since
the ai/aoRecord's RVAL is a signed 32bit integer.

> The
> special_linconv() function of the ao record sets ESLO and EOFF correctly
> (ESLO /4294967295=4.65661287416E-09, EOFF=-10.0). All negative values
> work but any positive value gives wrong results. Even worse, the results
> are different on different machines: 0x80000000 on linux-x86, 0x7fffffff
> on vxworks-ppc604 for all positive values.
>
> What happens? In the convert() function the analog (double) value is
> converted to epicsInt32 (type of the RVAL field). However if the double
> value is too large for the integer, strange and obviously implementation
> dependent things happen. I cannot find anything about this case in K&R.

In my copy (2nd edition, 1988) is says on page 197 (section A6.3):

"""
In particular, the result of converting negative floating values to unsigned
integral types is undefined.
"""

> I suggest to modify the convert function as follows:
>
> diff -u -r1.1.1.1 aoRecord.c
> --- src/rec/aoRecord.c  29 Nov 2010 10:38:07 -0000      1.1.1.1
> +++ src/rec/aoRecord.c  10 Apr 2013 07:30:08 -0000
> @@ -469,7 +469,7 @@
>       value -= prec->aoff;
>       if (prec->aslo != 0) value /= prec->aslo;
>       if (value >= 0.0)
> -        prec->rval = (epicsInt32)(value + 0.5) - prec->roff;
> +        prec->rval = (epicsUInt32)(value + 0.5) - prec->roff;
>       else
>           prec->rval = (epicsInt32)(value - 0.5) - prec->roff;
>   }
>
> I.e using unsigned integer conversion for positive values. This changes
> nothing for any values < 0x7fffffff and gives a useful result for
> positive values >= 0x80000000.

Well, "useful" is a somewhat relative term here. Device supports that do not
know of this convention might become confused since they see a negative result
now. You might argue that this happens only if the configuration is invalid
anyway (which is true), but I am still not sure this is such a good idea.

A better solution would be to fix the ai/oRecord(s). For instance, add another
raw value field for unsigned raw values ("URVL") and a flag/menu ("UURV") that
lets the user or the device support switch to this unsigned raw value
(defaulting to "Use RVAL").

Cheers
--
Ben Franksen
()  ascii ribbon campaign - against html e-mail
/\  www.asciiribbon.org   - against proprietary attachm€nts

Attachment: signature.asc
Description: This is a digitally signed message part.


References:
Conversion problem from double to 32 bit unsigned int (in ao) Dirk Zimoch

Navigate by Date:
Prev: RE: linux file search from Asyn Mark Rivers
Next: Re: Conversion problem from double to 32 bit unsigned int (in ao) Andrew Johnson
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  <20132014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: Conversion problem from double to 32 bit unsigned int (in ao) Dirk Zimoch
Next: Re: Conversion problem from double to 32 bit unsigned int (in ao) Andrew Johnson
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  <20132014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 20 Apr 2015 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·