Signed little-endian-big-endian problems

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • graemejcox
    New Member
    • Nov 2009
    • 5

    Signed little-endian-big-endian problems

    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:

    Code:
    short SwapShortWords( const short sWord )
    {
              union {
                       short iSwapped;
                       char acBytes[2];
                    }
    		   WordIn, WordOut;
               WordIn.iSwapped = sWord;
               WordOut.acBytes[0] = WordIn.acBytes[1];
               WordOut.acBytes[1] = WordIn.acBytes[0];
    
    		   return WordOut.iSwapped;
    }
    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.
  • donbock
    Recognized Expert Top Contributor
    • Mar 2008
    • 2427

    #2
    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.

    Comment

    • graemejcox
      New Member
      • Nov 2009
      • 5

      #3
      More info

      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

      Code:
      short sElevation, mytest;
      mytest = short((points[i].PropZ-pBenchmark[0].Z+10)/0.0025	
      sElevation = SwapShortWords(mytest);
      iWriteReturn = write(gihFile, &sElevation,2);
      What the heck is going on?

      Comment

      • donbock
        Recognized Expert Top Contributor
        • Mar 2008
        • 2427

        #4
        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.)

        Comment

        • graemejcox
          New Member
          • Nov 2009
          • 5

          #5
          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.iSwappe d;
          }

          Comment

          • Banfa
            Recognized Expert Expert
            • Feb 2006
            • 9067

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

            Are you just printing them before and after conversion?

            Comment

            • graemejcox
              New Member
              • Nov 2009
              • 5

              #7
              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??

              Comment

              • graemejcox
                New Member
                • Nov 2009
                • 5

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

                Thanks for your help guys.

                Comment

                Working...