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
<2013>
2014
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
<2013>
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
|