1

I have a method that receives 3 parameters: int x, int n, and int m. It returns an int with the nth and mth bytes of x swapped

x is just a normal integer, set to any value. n and m are integers between 0 and 3.

For example, let the hex representation of x be 0x12345678, n is 0, and m is 2. The last and 3rd to last byte are supposed to be switched (n = 78, m = 34).

I have figured out how extract the nth and mth byte from x, but I can't figure out how to recombine all 4 bytes into the integer that the method is supposed to return.

Here is my current code: `

int byteSwap(int x, int n, int m)
{
    // Initialize variables which will hold nth and mth byte
    int xn = x;
    int xm = x;
    // If n is in bytes, n << 3 will be the number of bits in that byte
    // For example, if n is 2 (as in 2 bytes), n << 3 will be 16 (as in 16 bits)
    xn = x >> (n << 3);
    // Mask off everything except the part we want
    xn = xn & 0xFF;
    // Do the same for m
    xm = x >> (m << 3);
    xm = xm & 0xFF;
}

`

There are some additional constraints - only the following are allowed:

~ & ^ | ! + << >>

(That means no - * /, loops, ifs, etc. However, additional variables can be initialized and adding is still OK.)

My code can get the nth and mth byte extracted, but I don't get how to recombine everything without using ifs.

Fiddling Bits
  • 8,712
  • 3
  • 28
  • 46
the_pwner224
  • 99
  • 1
  • 1
  • 11
  • Some advice - when bit-fiddling, it's a good idea to use unsigned integer types. C doesn't guarantee that signed integers will use any particular representation - without a clear definition of how numbers translate to/from bits, bit-fiddling is very bug-prone. In practice the representation will be twos complement for any not-completely-strange platform, but compilers are increasingly exploiting undefinedness for optimization reasons. So even though you know your platform uses twos complement you may get behavior that's inconsistent with that, depending on the whims of your compiler. –  Jan 26 '14 at 03:14
  • Is casting and pointers allowed? (e.g. unsigned char* bytes = (unsigned char*)&x;) – Travis Griggs Jan 26 '14 at 03:32
  • No, casting and pointers are not allowed. This is a homework problem, and it was specified that the representation of signed integers is in twos-complement. – the_pwner224 Jan 27 '14 at 16:41
  • @thepwner224 - the point of my comment is that it doesn't matter if the representation is twos-complement. Undefined behavior is undefined behavior - the compiler can do whatever it likes. Of course if you were specifically told that you're probably expected to use that knowledge, but to me that just means you have a bad teacher - the cost of writing `unsigned` in a few places is far less than the cost of investigating weird bugs that disappear in a debug build or whatever. Besides, bit-fiddling in unsigned means you don't have to special-case the sign bit. –  Jan 30 '14 at 13:13
  • @thepwner224 - the only reason to fiddle your bits with signed integers is if you're working in Java, which doesn't have unsigned integers but at least guarantees 2s complement representation with no undefined behavior. –  Jan 30 '14 at 13:16

1 Answers1

1

Couple of things

You can recombine by masking x with a value that is all FF except for bytes m and n You can compute the mask by left shifting 0xFF m times and n times and combining the result and then XOR it with 0xFFFFFFFF

int mask = 0;
int mask_m = 0xFF << (m << 3);
int mask_n = 0xFF << (n << 3);

mask = (mask_m | mask_n) ^ 0xFFFFFFFF;

int x_swapped = (x & mask) | (xm << (n <<3)) | (xn << (m <<3));
return x_swapped;

FYI when you right shift a signed value, it may or may not propagates 1s instead of 0 into the high order bit and is implementation defined. Either way 0xFF will protect against that.

waTeim
  • 9,095
  • 2
  • 37
  • 40
  • I haven't tried this yet but it should work. The code already masks off everything except the bytes after right shifting m and n. – the_pwner224 Jan 26 '14 at 03:08
  • 1
    "when you right shift a signed value, it propagates 1s instead of 0 into the high order bit" - unless it doesn't. Right-shifting a positive signed int shifts in zeros, what happens with negative signed ints is implementation-defined. – Notlikethat Jan 26 '14 at 03:14