[Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Convert Signed Big Endian short to Little Endian signed Short

Posted on 2006-06-06
16
Medium Priority
?
1,645 Views
Last Modified: 2007-12-19
I have a file that contains signed shorts in big-endian format.

How do I convert these to little-endian SIGNED format?

I thought I had this working, but later realized I didn't handle negative values.

Thanks
0
Comment
Question by:oxygen_728
  • 7
  • 3
  • 2
  • +2
16 Comments
 
LVL 12

Assisted Solution

by:rajeev_devin
rajeev_devin earned 1200 total points
ID: 16841055
Just interchange the bytes
0
 
LVL 12

Accepted Solution

by:
rajeev_devin earned 1200 total points
ID: 16841119
A technique

union BYTES {
   unsigned short number;
   unsigned char bytes[2];
};

BYTES b;
read(&b.bytes[1], 1, ...); // Read first byte in index 1
read(&b.bytes[0], 1, ...); // Read first byte in index 0

b.number contains the number in little-endian.
0
 
LVL 4

Assisted Solution

by:e_tadeu
e_tadeu earned 600 total points
ID: 16841424
It is much more efficient if you read them in a batch and use the swab function!
E.g:

#include <cstdlib>
#include <cstdio>

using namespace std;

short inputArray[1024], array[1024];
fread(inputArray, sizeof short, 1024, someFile);

// now swap the bytes
swab(reinterpret_cast<char*>(inputArray), reinterpret_cast<char*>(array), sizeof inputArray);

Or, if you would like to do it without the extra memory buffer, but with a speed penalty, you can do it 'inplace', like this:

inline inswab(char *array, size_t bytes) {
  for (int i = 0; i < bytes; i += 2) {
    register char aux = array[i];
    array[i] = array[i+1];
    array[i+1] = aux;
  }
}

See:
http://www.cplusplus.com/ref/cstdlib/swab.html
http://www.codeproject.com/cpp/endianness.asp
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 17

Assisted Solution

by:rstaveley
rstaveley earned 200 total points
ID: 16843132
If your application is running on a little-endian system, you can use ntohs and htons to convert to and from the host (little-endian) from and to network (big-endian) byte order. See http://www.google.com/search?q=htons
0
 

Author Comment

by:oxygen_728
ID: 16845262
raj:

Are you sure it is as simple as interchanging the bytes? There's a sign bit in there somewhere.
I switched over from unsigned shorts to signed shorts and my results are screwy with the numbers that should be negative
0
 

Author Comment

by:oxygen_728
ID: 16845284
E_Tadeu:

well, that doesnt seem far from what I'm doing:

      ifstream in;
      in.open("N36W117.hgt",ios::in | ios::binary);
      int x;
      short Val = 0;
      int counter = 0;
      Vertices = new SimpleVertex[1201*1201];
   
      //load in elevation data
      while (counter < 1201 * 1201){
            in.read((char*)&Val, 2);                      //<--------------------------------------------------
            Val = (Val << 8) | (Val >> 8);             //<----------------------------------------------------
            Vertices[counter].x = counter % 1201;
            Vertices[counter].y = Val;
            Vertices[counter].z = counter / 1201;
            counter++;
      }
0
 

Author Comment

by:oxygen_728
ID: 16845642
I think I found part of the problem;

short Val;
Val = 0xa300

Val = Val >> 8;

Val will equal ffa3 instead of  00a3

Must be a sign issue.

0
 

Author Comment

by:oxygen_728
ID: 16845927
Ya, apparently I was using a short too early - there was some funky stuff going on with the bit shifting.

Val >> 8   SOMETIMES would fill in the 'new' bits (on the left) with f's instead of 0's  (hex)

It's all fixed now, I used bytes - and I learned about this strange union structure thanks to rajeev.

Thanks guys
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 16846546
>> Val >> 8   SOMETIMES would fill in the 'new' bits (on the left) with f's instead of 0's  (hex)
that "SOMETIMES" happens when the left most bit is set to 1 ... by shifting, you shift in that same bit on the left side. That doesn't happen with unsigned integer types though.

The rule with converting between little and big endian is to either use unsigned types, or to avoid shifting when using signed types.

Any way you inter-change bytes would be ok ... and I see you already have some examples given by the others :)
0
 
LVL 4

Expert Comment

by:e_tadeu
ID: 16848096
Note: if you use "unsigned short", the problem of filling 1's in the left should not happen. It only happens with signed shift, because of negative numbers in 2's-complement!
0
 

Author Comment

by:oxygen_728
ID: 16848288
Perhaps I could have used unsigned shorts, then performed a cast to a signed short? I have a feeling that conversion does something goofy to overcome the negativity though =\
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 16849669
Can I ask why you need to extract certain bits from a signed short ? It sounds like it's something that could be done easier differently.
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 16850253
> Val >> 8   SOMETIMES would fill in the 'new' bits (on the left) with f's instead of 0's  (hex)

The problem occurred when you made the original assignment, which set the signed bit.

--------8<--------
#include <stdio.h>

int main()
{
      short Val;
      Val = 0xa300;   // Same as assigning -23808 to the short
      printf("%hd %hx %x\n", Val, Val, Val);

      Val = Val >> 8;
      printf("%hd %hx %x\n", Val, Val, Val);
}
--------8<--------

The shift right operator drags the signed bit into the most significant bit, when you operate on signed integers.
0
 

Author Comment

by:oxygen_728
ID: 16850388
Well, I'm just reading in data in big-endian signed-short format... and I need the data in little-endian signed-short format.
0
 

Author Comment

by:oxygen_728
ID: 16850394
rstavlely - I thought I had read somewhere that 0's are always 'dragged in' ... I don't remember reading anything about the sign bit being dragged in - thus my confusion =)

Thanks for clearing things up!
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 16850441
>> Well, I'm just reading in data in big-endian signed-short format... and I need the data in little-endian signed-short format.
My apologies - I mixed up two questions ... ignore my question :)

>> I thought I had read somewhere that 0's are always 'dragged in'
That's true for unsigned types
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
Suggested Courses

868 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question