signed math and prop
I'm working on converting some C code for an MPL115A1 sensor over to spin, and I have a few questions about doing signed math.
Let's say I read a 16-bit value into a 32-bit integer. The value is read out of two registers, a hi byte and a low byte. The hi byte has a sign bit in it. My code so far looks like this:
a0 is a signed value. Do I need to do anything special to sign extend it? The original C code looked something like this:
Let's say I read a 16-bit value into a 32-bit integer. The value is read out of two registers, a hi byte and a low byte. The hi byte has a sign bit in it. My code so far looks like this:
a0l := read_reg(A0MSB) << 8 + read_reg(A0LSB) & $00FF
a0 is a signed value. Do I need to do anything special to sign extend it? The original C code looked something like this:
signed char a0msb = read_reg(A0MSB) signed char a0lsb = read_reg(A0LSB) signed int a0 = (signed int) a0msb<<8 a0 = a0 + (signed int) a0lsb & 0x00FF signed long a0l = (signed long) a0
Comments
Try this right after your line of code
... Tim
It says sign extend of bit 15 in the quick reference.
That it does ... hadn't noticed that before!
... Tim
EDIT: Actually if read_reg returns a signed extended byte value you would just need to do If it returns an unsigned byte value you could get by with If you don't know whether the bytes are sign-extended or not the first statement I posted will work.
My Spin equivalent looks like this:
I'm wondering if I botched something in my conversion. In particular, there's lots of type conversions in the C code applied to bytes that are shifted, perhaps I'm missing something here. In particular, the value I'm getting for Pcomp is well outside the acceptable range of [0..1023]; I'm getting about 17080.
The datasheet is at http://cache.freescale.com/files/sensors/doc/app_note/AN3785.pdf?fpsp=1&WT_TYPE=Application%20Notes&WT_VENDOR=FREESCALE&WT_FILE_FORMAT=pdf&WT_ASSET=Documentation if anyone is interested...
As far as reading the signed values and extending them, I'm doing this:
I tried both Dave's and MagiO2's suggestions and both worked out equivalently.
So, I think the advise above should work...
Ah, I think I understand. So, in C, a shift of an unsigned value preserves the sign bit:
-4096 >> 1 = -2048
-4096 << 1 = -8192
Spin has two different operators. << and >> would act like C's << and >> on unsigned variables. ~< and ~> would act like C's << and >> on signed variables.
So, in spin:
-4096 ~> 1 = -2048
-4096 ~< 1 = -8192
-4096 >> 1 = some large positive number, because sign bit is shifted down one bit
-4096 << 1 = some positive number, maybe 8192? (I'd have to look up 2s compliment arithmetic to be sure) since the sign bit was discarded
Am I understanding it correctly?
int a = -4096 >> 1
will give a different result from
int b = (unsigned int) -4096 >> 1
-4096 = 0xfffff000
so in the above 'a' will be -2048 or 0xfffff800
and 'b' will be 2147481600 or 0x7ffff800
-Tor
Ah, I see. As usual, I had forgotten how 2s compliment numbers were represented.
I think I have some good ideas now on fixing this code. I'll keep the thread updated if I get it working (and hopefully submit the completed object to the OBEX).
EDIT: I think with the changes suggested, this is working now. At least it's returning an altitude computation that's close to my actual altitude. Only problem with this sensor appears that it's very noisy. At least 3 of the 12 bits are noise, maybe 4. I'm probably going to switch my application over to use a BMP85 (this will teach me to read the datasheets more carefully!).
Scott