I have a bit of a situation. I am designing a board based on the Arduino with an I2C chip. It reports a value as a 14 bit signed int. I want it to be a 16 bit signed int. It seems like simply moving the signing bit doesn't work. Here's the structure of the input bit and the output bit:
Input:
Sx xxxx xxxx xxxx ----->S is the signing bit. x Are the binary 1's and 0's.
Output:
Sxxx xxxx xxxx xxxx
What can I use to convert this? I know C, I just don't know how to convert these numbers.
Also, I need to do the same thing with a 12 bit number, so the generic algorithm will be useful too. The format is this:
Input:
Sxxx xxxx xxxx ----->S is the signing bit. x Are the binary 1's and 0's.
Output:
Sxxx xxxx xxxx xxxx
I guess it only takes a few bit-wise functions and maybe an if statement or a for loop.
Thanks,
Ivan
This is solved. Here are some tags for the search engines:
Convert signed int to signed long
Change signed int size
I2C signed value
STC3100 read current
STC3100 read voltage
I was thinking about storing the sign bit elsewhere and get the absolute value of the 14-bit signed int. Both 14 and 16 bit positive ints look the same. Then I can multiply the result by -1 if it has to be negative.
In my example, if n is positive, bit 14 = 0, then the shift operations don't change n. If bit 14 of n = 1, indicating that the 14 bit word is negative then the <<= 2 shifts the 1 into the MSB of the 16 bit word and the >>= shifts 1s back in so that you end up with a proper negative integer.
It's not 100% clear how the 14 bit value is being read, and whether the top bits might contain garbage. If the top bits are not guaranteed to be zeros, it is safer to OR on the ones this way:
It's not 100% clear how the 14 bit value is being read, and whether the top bits might contain garbage. If the top bits are not guaranteed to be zeros, it is safer to OR on the ones this way:
They are guaranteed to be 0.
When the += way is used, it produces garbage. The |= seems to work.
Alright, problem solved. Both of the solutions tested by me worked. I can't get the solution on the first post to work, but it showed be two very handy functions on the Arduino IDE that will be useful for my project: readByte and writeByte. They can handle individual bytes. That is useful for setting and clearing bits in I2C devices, which can only be accessed byte by byte.
Tested both solutions with a 12 bit number and they both worked. For the shift (<<= and >>=) solution, just replace 2's with 4's. For the other solution, follow Magician's advice.
Even though I suggested the solution, I feel compelled to point out that it's not necessarily portable. On the Arduino and all the machines I've worked with the right shift is arithmetic, that is it propagates the sign bit during shifts. The C programming language specifies that it is machine dependent and may shift in zeroes for the signed integer. I don't imagine it's going to change on the Arduino, but it could.