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  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 
<== Date ==> <== Thread ==>

Subject: Re: Conversion problem from double to 32 bit unsigned int (in ao)
From: Benjamin Franksen <benjamin.franksen@helmholtz-berlin.de>
To: <tech-talk@aps.anl.gov>
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 
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 
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 ·