Connecting Tech Pros Worldwide Help | Site Map

Signed little-endian-big-endian problems

Newbie
 
Join Date: Nov 2009
Posts: 5
#1: 2 Weeks Ago
Hi.
I am having some problem converting some signed shorts from little endian (intel) to big (motorola chip).

Im using this code but it appear to produce errors when I convert some negative shorts:

Expand|Select|Wrap|Line Numbers
  1. short SwapShortWords( const short sWord )
  2. {
  3.           union {
  4.                    short iSwapped;
  5.                    char acBytes[2];
  6.                 }
  7.            WordIn, WordOut;
  8.            WordIn.iSwapped = sWord;
  9.            WordOut.acBytes[0] = WordIn.acBytes[1];
  10.            WordOut.acBytes[1] = WordIn.acBytes[0];
  11.  
  12.            return WordOut.iSwapped;
  13. }
  14.  
Eg when I convert values near 0, -256, -512, -756 I get converted values around +2500, +2800, etc. Note these values are approximate ie I have an idea of where the problems are occuring but not the exact values.

I think it has something to do with the sign bit. Can anyone suggest a modification to my code to solve this problem?

thanks in advance.
Expert
 
Join Date: Mar 2008
Location: Naperville, Illinois U.S.
Posts: 828
#2: 2 Weeks Ago

re: Signed little-endian-big-endian problems


You should never use plain char for numeric values; you should use either signed char or unsigned char. In this case unsigned is probably better.

Using a union to obtain the native endianness makes me wince, but it ought to work in this case so I won't make any waves.
Newbie
 
Join Date: Nov 2009
Posts: 5
#3: 2 Weeks Ago

re: Signed little-endian-big-endian problems


Don
Thanks for the response. I tried 'unsigned short' with no improvement.

I have been bashing my head against the wall trying to solve this and still havent. Further info I found was:

I tired with positive values between about 3000 and 4000 to see if the negative was the root of the problem but it appears it is not.

Most values swap OK but these input values below produce the returns values.

Input Returns
3082 2566 2573 2567
3338 2812 2561 2573 2565
3593 2802 2803
3594 2803

Note the return results dont seem to be fully consistant bit similar eg 3082 returns three values 2566, 2573, 2567.

Also note the return values are actually swapped, then written to file, file closed and reopened and then I read them back. The writing to file might be something to do with the problem too. To write I use

Expand|Select|Wrap|Line Numbers
  1. short sElevation, mytest;
  2. mytest = short((points[i].PropZ-pBenchmark[0].Z+10)/0.0025    
  3. sElevation = SwapShortWords(mytest);
  4. iWriteReturn = write(gihFile, &sElevation,2); 
  5.  
  6.  
What the heck is going on?
Expert
 
Join Date: Mar 2008
Location: Naperville, Illinois U.S.
Posts: 828
#4: 2 Weeks Ago

re: Signed little-endian-big-endian problems


Let me repeat myself more succinctly.
Use unsigned char in the definition of the union.

(It doesn't matter if you use short or unsigned short in the union.)
Newbie
 
Join Date: Nov 2009
Posts: 5
#5: 2 Weeks Ago

re: Signed little-endian-big-endian problems


Don
Soory. I meant to say I tried unsigned char:

short SwapShortWords( const short sWord )
{
union {
short iSwapped;
unsigned char acBytes[2];
}
WordIn, WordOut;
WordIn.iSwapped = sWord;
WordOut.acBytes[0] = WordIn.acBytes[1];
WordOut.acBytes[1] = WordIn.acBytes[0];

return WordOut.iSwapped;
}
Banfa's Avatar
AdministratorVoR
 
Join Date: Feb 2006
Location: South West UK
Posts: 6,151
#6: 2 Weeks Ago

re: Signed little-endian-big-endian problems


Your number, -756, 2500 etc? How are you getting them?

Are you just printing them before and after conversion?
Newbie
 
Join Date: Nov 2009
Posts: 5
#7: 2 Weeks Ago

re: Signed little-endian-big-endian problems


Banfa
Hi. Thanks for having a look.

To get the return values (eg 2500) I actually swapped the input (eg 756) , then write to binary file, 1000s of other values are written to file in the same way, file is closed and reopened and then I read them back.

To write them I use:
short sElevation, mytest;
mytest = short((points[i].PropZ-pBenchmark[0].Z+10)/0.0025
sElevation = SwapShortWords(mytest);
iWriteReturn = write(gihFile, &sElevation,2);


Thinking about it more, the writing to file might be something to do with the problem too because if I swap the values using:

mytest = short(3338);
sElevation = SwapShortWords(mytest);
mytest = SwapShortWords(sElevation);

It seems to work fine but if I go through the full procedure then it doesnt.

The other interesting I just found was:
SwapShortWords(3338) is equal to 2573 (0x0d0a to 0x0a0d)
and
SwapShortWords(3594 ) is equal to 2574

Wow. Is that a coincidence: 0x0d0a is equal to CRLF in DOS/Windows?????

OK CRLF is my lead now. Im looking into this. Any ideas??
Newbie
 
Join Date: Nov 2009
Posts: 5
#8: 2 Weeks Ago

re: Signed little-endian-big-endian problems


BINGO!!!!!! I hadnt set file open to O_BINARY
Helalula ;)))))))))
This had been frustrating me for weeks.

Thanks for your help guys.
Reply

Tags
endian