Go Down

Topic: Urgent - Split Long into 2 Int using BitShift (Read 6 times) previous topic - next topic

robtillaart

#15
Jan 20, 2011, 06:17 pm Last Edit: Jan 20, 2011, 06:29 pm by robtillaart Reason: 1
with 32769 I read:

=> try 32769[glow]L[/glow]  (to be sure its a long)


Quote
With -1 as ValueLong I read on serial monitor:

L = 11111111111111111111111111111111
H = 11111111111111111111111111111111


because both L & H & ValueLong are signed, 1111...11 will read as -1 for all three of them. Bitwise it is a correct split.

Another way to split your long is to use an union, a less used construct in C++, A union has multiple var's mapped upon the same memory space:

Code: [Select]
union split_t
{
 int I[2];
 long ValueLong;
} X;

void setup()
{
 Serial.begin(115200);
}

void loop()
{
 X.ValueLong = -1;
 
 int H = X.I[0];
 int L = X.I[1];
 
 Serial.print(H, DEC);
 Serial.print(" = ");
 Serial.println(L,DEC);
 delay(500);
}


The union split_t could be extended with unsigned long or an array of four bytes. Although it seems that no math is involved the indexing of the array takes some cpu cycles ...
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

AWOL

#16
Jan 20, 2011, 06:38 pm Last Edit: Jan 20, 2011, 06:43 pm by AWOL Reason: 1
Pay more attention to your data types.
BTW, with 32 bit data types, a one-in-a-million chance means you have over 4000 chances to screw up!
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

jraskell

I'm not quite sure what your expectations are here.  The intermediate int decimal values will in no way correlate to the original long decimal value.  If they are only being used as a necessary step to transfer the entire data, then that doesn't matter.

What matters is that the bit representation is maintained.
Say you have a long value of (just for example) 1,582,081.
It's binary representation would be:
00000000 00011000 00100100 00000001

If you then assign that value to two ints with bitwise shifting, you would end up with
high int 00000000 00011000
low  int 00100100 00000001

If you then properly recompose that back into a new long, that new long will have the same decimal value as the previous one (assuming the binary representation of that decimal value is the same across any platform transitions).

You could use unsigned ints for your intermediate variables and it wouldn't make a difference.  You could even use 4 bytes or chars instead.

Quote

With -1 as ValueLong I read on serial monitor:

L = 11111111111111111111111111111111
H = 11111111111111111111111111111111


That looks completely correct.  Signed ints are stored in a twos complement format.  Google it for more info on how twos complement works, and why it's an ideal format to use for signed ints.

MatrixGTI

Quote
Pay more attention to your data types.
BTW, with 32 bit data types, a one-in-a-million chance means you have over 4000 chances to screw up!


Sorry but as I'm a noob in programming I have difficults to understand some things. Also english is not my language so...  ::)

Now I understand that variable are 32 bit long, this means that I can use Bitshift but in different way ?

Quote
because both L & H & ValueLong are signed, 1111...11 will read as -1 for all three of them. Bitwise it is a correct split.

Another way to split your long is to use an union, a less used construct in C++, A union has multiple var's mapped upon the same memory space:


I'll try with Union code, thanks for it, but I dont understand why bitshift did non work or I dont understand how to correctly read the variable sent

AWOL

How are you putting your two 16 bit value back together as a 32 bit value?
Not still multiplying by 32767 I hope.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Go Up