Byte swapping in bit wise operations - c

I have this function called byte swap I am supposed to implement. The idea is that the function takes 3 integers (int x, int y, int z) and the function will swap the y and z bytes of the int x. The restrictions are pretty much limited to bit wise operations (no loops, and no if statements or logical operators such as ==).
I don't believe that I presented this problem adequately so Im going to re attempt
I now understand that
byte 1 is referring to bits 0-7
byte 2 is referring to bits 8-15
byte 3 16-23
byte 4 24-31
My function is supposed to take 3 integer inputs, x, y and z. The y byte and z byte on the x then would have to get switched
int byteSwap(int x, int y, int z)
ex of the working function
byteSwap(0x12345678, 1, 3) = 0x56341278
byteSwap(0xDEADBEEF, 0, 2) = 0xDEEFBEAD
My original code had some huge errors in it, namely the fact that I was considering a byte to be 2 bits instead of 8. The main problem that I'm struggling with is that I do not know how to access the bits inside of the given byte. For example, when I'm given byte 4 and 5, how do I access their respected bits? As far as I can tell I can't find a mathematical relationship between the given byte, and its starting bit. I'm assuming I have to shift and then mask, and save those to variables.Though I cannot even get that far.

Extract the ith byte by using ((1ll << ((i + 1) * 8)) - 1) >> (i * 8). Swap using the XOR operator, and put the swapped bytes in their places.
int x, y, z;
y = 1, z = 3;
x = 0x12345678;
int a, b; /* bytes to swap */
a = (x & ((1ll << ((y + 1) * 8)) - 1)) >> (y * 8);
b = (x & ((1ll << ((z + 1) * 8)) - 1)) >> (z * 8);
/* swap */
a = a ^ b;
b = a ^ b;
a = a ^ b;
/* put zeros in bytes to swap */
x = x & (~((0xff << (y * 8))));
x = x & (~((0xff << (z * 8))));
/* put new bytes in place */
x = x | (a << (y * 8));
x = x | (b << (z * 8));

When you say the 'the y and z bytes of x' this implies x is an array of bytes, not an integer. If so:
x[z] ^= x[y];
x[y] ^= x[z];
x[z] ^= x[y];
will do the trick, by swapping x[y] and x[z]
After your edit, it appears you want to swap individual bytes of a 32 bit integer:
On a little-endian machine:
int
swapbytes (int x, int y, int z)
{
char *b = (char *)&x;
b[z] ^= b[y];
b[y] ^= b[z];
b[z] ^= b[y];
return x;
}
On a big-endian machine:
int
swapbytes (int x, int y, int z)
{
char *b = (char *)&x;
b[3-z] ^= b[3-y];
b[3-y] ^= b[3-z];
b[3-z] ^= b[3-y];
return x;
}
With a strict interpretation of the rules, you don't even need the xor trick:
int
swapbytes (int x, int y, int z)
{
char *b = (char *)&x;
char tmp = b[z];
b[z] = b[y];
b[y] = tmp;
return x;
}
On a big-endian machine:
int
swapbytes (int x, int y, int z)
{
char *b = (char *)&x;
char tmp = b[3-z];
b[3-z] = b[3-y];
b[3-y] = tmp;
return x;
}
If you want to do it using bit shifts (note <<3 multiplies by 8):
int
swapbytes (unsigned int x, int y, int z)
{
unsigned int masky = 0xff << (y<<3);
unsigned int maskz = 0xff << (z<<3);
unsigned int origy = (x & masky) >> (y<<3);
unsigned int origz = (x & maskz) >> (z<<3);
return (x & ~masky & ~maskz) | (origz << (y<<3)) | (origy << (z<<3));
}

Related

Interleave 4 byte ints to 8 byte int

I'm currently working to create a function which accepts two 4 byte unsigned integers, and returns an 8 byte unsigned long. I've tried to base my work off of the methods depicted by this research but all my attempts have been unsuccessful. The specific inputs I am working with are: 0x12345678 and 0xdeadbeef, and the result I'm looking for is 0x12de34ad56be78ef. This is my work so far:
unsigned long interleave(uint32_t x, uint32_t y){
uint64_t result = 0;
int shift = 33;
for(int i = 64; i > 0; i-=16){
shift -= 8;
//printf("%d\n", i);
//printf("%d\n", shift);
result |= (x & i) << shift;
result |= (y & i) << (shift-1);
}
}
However, this function keeps returning 0xfffffffe which is incorrect. I am printing and verifying these values using:
printf("0x%x\n", z);
and the input is initialized like so:
uint32_t x = 0x12345678;
uint32_t y = 0xdeadbeef;
Any help on this topic would be greatly appreciated, C has been a very difficult language for me, and bitwise operations even more so.
This can be done based on interleaving bits, but skipping some steps so it only interleaves bytes. Same idea: first spread out the bytes in a couple of steps, then combine them.
Here is the plan, illustrated with my amazing freehand drawing skills:
In C (not tested):
// step 1, moving the top two bytes
uint64_t a = (((uint64_t)x & 0xFFFF0000) << 16) | (x & 0xFFFF);
// step 2, moving bytes 2 and 6
a = ((a & 0x00FF000000FF0000) << 8) | (a & 0x000000FF000000FF);
// same thing with y
uint64_t b = (((uint64_t)y & 0xFFFF0000) << 16) | (y & 0xFFFF);
b = ((b & 0x00FF000000FF0000) << 8) | (b & 0x000000FF000000FF);
// merge them
uint64_t result = (a << 8) | b;
Using SSSE3 PSHUFB has been suggested, it'll work but there is an instruction that can do a byte-wise interleave in one go, punpcklbw. So all we need to really do is get the values into and out of vector registers, and that single instruction will then just care of it.
Not tested:
uint64_t interleave(uint32_t x, uint32_t y) {
__m128i xvec = _mm_cvtsi32_si128(x);
__m128i yvec = _mm_cvtsi32_si128(y);
__m128i interleaved = _mm_unpacklo_epi8(yvec, xvec);
return _mm_cvtsi128_si64(interleaved);
}
With bit-shifting and bitwise operations (endianness independent):
uint64_t interleave(uint32_t x, uint32_t y){
uint64_t result = 0;
for(uint8_t i = 0; i < 4; i ++){
result |= ((x & (0xFFull << (8*i))) << (8*(i+1)));
result |= ((y & (0xFFull << (8*i))) << (8*i));
}
return result;
}
With pointers (endianness dependent):
uint64_t interleave(uint32_t x, uint32_t y){
uint64_t result = 0;
uint8_t * x_ptr = (uint8_t *)&x;
uint8_t * y_ptr = (uint8_t *)&y;
uint8_t * r_ptr = (uint8_t *)&result;
for(uint8_t i = 0; i < 4; i++){
*(r_ptr++) = y_ptr[i];
*(r_ptr++) = x_ptr[i];
}
return result;
}
Note: this solution assumes little-endian byte order
You could do it like this:
uint64_t interleave(uint32_t x, uint32_t y)
{
uint64_t z;
unsigned char *a = (unsigned char *)&x; // 1
unsigned char *b = (unsigned char *)&y; // 1
unsigned char *c = (unsigned char *)&z;
c[0] = a[0];
c[1] = b[0];
c[2] = a[1];
c[3] = b[1];
c[4] = a[2];
c[5] = b[2];
c[6] = a[3];
c[7] = b[3];
return z;
}
Interchange a and b on the lines marked 1 depending on ordering requirement.
A version with shifts, where the LSB of y is always the LSB of the output as in your example, is:
uint64_t interleave(uint32_t x, uint32_t y)
{
return
(y & 0xFFull)
| (x & 0xFFull) << 8
| (y & 0xFF00ull) << 8
| (x & 0xFF00ull) << 16
| (y & 0xFF0000ull) << 16
| (x & 0xFF0000ull) << 24
| (y & 0xFF000000ull) << 24
| (x & 0xFF000000ull) << 32;
}
The compilers I tried don't seem to do a good job of optimizing either version so if this is a performance critical situation then maybe the inline assembly suggestion from comments is the way to go.
use union punning. Easy for the compiler to optimize.
#include <stdio.h>
#include <stdint.h>
#include <string.h>
typedef union
{
uint64_t u64;
struct
{
union
{
uint32_t a32;
uint8_t a8[4]
};
union
{
uint32_t b32;
uint8_t b8[4]
};
};
uint8_t u8[8];
}data_64;
uint64_t interleave(uint32_t a, uint32_t b)
{
data_64 in , out;
in.a32 = a;
in.b32 = b;
for(size_t index = 0; index < sizeof(a); index ++)
{
out.u8[index * 2 + 1] = in.a8[index];
out.u8[index * 2 ] = in.b8[index];
}
return out.u64;
}
int main(void)
{
printf("%llx\n", interleave(0x12345678U, 0xdeadbeefU)) ;
}

Check if a number can be represented using n bits in 2’s complement

I'm working on a function that returns 1 when x can be represented as an n-bit, 2’s complement number and 0 if it can't. Right now my code works for some examples like (5, 3), (-4, 3). But I can't get it to work for instances where n is bigger than x like (2, 6). Any suggestions as to why?
I do have restrictions though which include casting, either explicit or implicit, relative comparison operators (<, >, <=, and >=), division, modulus, and multiplication, subtraction, conditionals (if or ? :), loops, switch statements, function calls, and macro invocations. Assume 1 < n < 32.
int problem2(int x, int n){
int temp = x;
uint32_t mask;
int maskco;
mask = 0xFFFFFFFF << n;
maskco = (mask | temp);
return (maskco) == x;
}
In your function, temp is just redundant, and maskco always have the top bit(s) set, so it won't work if x is a positive number where the top bit isn't set
The simple solution is to mask out the most significant bits of the absolute value, leaving only the low n bits and check if it's still equal to the original value. The absolute value can be calculated using this method
int fit_in_n_bits(int x, int n)
{
int maskabs = x >> (sizeof(int) * CHAR_BIT - 1);
int xabs = (x + maskabs) ^ maskabs; // xabs = |x|
int nm = ~n + 1U; // nm = -n
int mask = 0xFFFFFFFFU >> (32 + nm);
return (xabs & mask) == xabs;
}
Another way:
int fit_in_n_bits2(int x, int n)
{
int nm = ~n + 1U;
int shift = 32U + nm;
int masksign = x >> (shift + 1);
int maskzero = 0xFFFFFFFFU >> shift;
return ((x & maskzero) | masksign) == x;
}
You can also check out oon's way here
int check_bits_fit_in_2s_complement(signed int x, unsigned int n) {
int mask = x >> 31;
return !(((~x & mask) + (x & ~mask))>> (n + ~0));
}
One more way
/*
* fitsBits - return 1 if x can be represented as an
* n-bit, two's complement integer.
* 1 <= n <= 32
* Examples: fitsBits(5,3) = 0, fitsBits(-4,3) = 1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 15
* Rating: 2
*/
int fitsBits(int x, int n) {
int r, c;
c = 33 + ~n;
r = !(((x << c)>>c)^x);
return r;
}
Related:
How to tell if a 32 bit int can fit in a 16 bit short
counting the number of bit required to represent an integer in 2's complement
int problem2_mj(int x, int n){
unsigned int r;
int const mask = (-x) >> sizeof(int) * CHAR_BIT - 1;
r = (-x + mask - (1 & mask)) ^ mask; // Converts +n -> n, -n -> (n-1)
return !(((1 << (n-1)) - r) >> sizeof(int) * CHAR_BIT - 1);
}
Find the absolute value and subtract 1 if the number was negative
Check if number is less than or equal to 2n-1
Check a working demo here
As per your updated request here is the code how to add two numbers:
int AddNums(int x, int y)
{
int carry;
// Iteration 1
carry = x & y;
x = x ^ y;
y = carry << 1;
// Iteration 2
carry = x & y;
x = x ^ y;
y = carry << 1;
...
// Iteration 31 (I am assuming the size of int is 32 bits)
carry = x & y;
x = x ^ y;
y = carry << 1;
return x;
}

Bitmask understanding in C program

I have a program that my professor gave me for a HW, and I want to see if any of y'all can explain me how bits work. Note: I don't want you guys to give me the answer; I want to learn so if you guys can explain me how this work would be awesome so I can go ahead an start on my hw.
Instructions:
a) unsigned setbits (unsigned x, int p, int n, unsigned y) that returns x with the n bits that begin at position p (right-adjusted) set to the rightmost n bits of y, leaving the other bits unchanged. Note: it does not change the values of x and y though.
b) unsigned invertbits (unsigned x, int p, int n) that returns x with the n bits that begin at position p (right-adjusted) inverted, i.e. 1 changed to 0 and vice versa, leaving the other bits unchanged. Note: it does not change the value of x though.
#include <stdio.h>
#include <limits.h>
void bit_print(int);
int pack(char, char, char, char);
char unpack(int, int);
unsigned getbits(unsigned, int, int);
void bit_print(int a){
int i;
int n = sizeof(int) * CHAR_BIT;
int mask = 1 << (n-1); // mask = 100...0
for (i=1; i<=n; i++){
putchar(((a & mask) == 0)? '0' : '1');
a <<= 1;
if (i % CHAR_BIT == 0 && i < n)
putchar(' ');
}
putchar('\n');
}
int pack(char a, char b, char c, char d){
int p=a;
p = (p << CHAR_BIT) | b;
p = (p << CHAR_BIT) | c;
p = (p << CHAR_BIT) | d;
return p;
}
char unpack(int p, int k){ // k=0, 1, 2, or 3
int n = k * CHAR_BIT; // n = 0, 8, 16, 24
unsigned mask = 255; // mask = low-order byte
mask <<= n;
return ((p & mask) >> n);
}
// getbits() extracts n bits from position p(start counting from the right-most bit) in x
unsigned getbits(unsigned x, int p, int n){
unsigned temp = x >> (p+1-n);
unsigned mask = 0;
mask = ~mask;
mask = mask << n;
mask = ~mask;
return temp & mask;
// return (x >> (p+1-n)) & ~(~0<<n);
}
int main(){
int x = 19;
printf("The binary rep. of %d is:\n", x);
bit_print(x);
int p=pack('w', 'x', 'y', 'z');
printf("\n'w', 'x', 'y', and 'z' packed together is equal to %d. Its binary rep. is:\n", p);
bit_print(p);
printf("calling unpack(p, 0) to extract the byte # 0 from the right:\n");
bit_print(unpack(p, 0));
printf("calling unpack(p, 1) to extract the byte # 1 from the right:\n");
bit_print(unpack(p, 1));
printf("calling unpack(p, 2) to extract the byte # 2 from the right:\n");
bit_print(unpack(p, 2));
printf("calling unpack(p, 3) to extract the byte # 3 from the right:\n");
bit_print(unpack(p, 3));
unsigned result = getbits(p, 20, 7);
printf("\ncalling getbits(p, 20, 7) to extract 7 bits from bit # 20 returns %d:\n", result);
bit_print(result);
return 0;
}
Using bitwise AND & , OR |, XOR ^, NOT ~ and a proper bit mask you can manipulate bits inside a variable. You will also need bit shifts >> and <<.
So let us have an example:
Let's take a 8bit var x = 0xff and try to invert its 3'rd bit:
unsigned char x = 0xff; // Our var
unsigned char mask = 1<<3; // Our mask
x = x & ~mask; // Invert mask so its value is b1111_0111
// and make a bitwise AND with x
Every bit in x keeps its value if there is 1 in a mask, and turns into 0 when masks bit value is 0. Now x value is x = 0xf7.
Using other operators you can do whatever you want with bits :)
So for example yours unpack function does:
char unpack(int p, int k){ // k - byte offset
int n = k * CHAR_BIT; // n - bit offset (k * 8)
unsigned mask = 255; // mask with all ones at first byte (0x000f)
mask <<= n; // move mask left n times;
// Now the ones are at the k'th byte
// if k = 2 => mask = 0x0f00
return ((p & mask) >> n); // Mask out k'th byte of p and remove all zeros
// from beginning.
}
When p = 0x3579 and k = 1:
n = k * CHAR_BIT; // n = 8
mask = 255; // mask = 0x000f
mask <<= n; // mask = 0x00f0
p &= mask; // p = 0x0070
p >>= n; // p = 0x0007
I hope it will help you!

Reducing number of operations

I have a function to find the max of three numbers, but it uses 24 ops I want to reduce it to 20 ops. Only using bitwise operations.
int maxOfThree(int x, int y, int z) {
int a1 = (x+(~y+1))>>31;
int a2 = (x+(~z+1))>>31;
int a3 = (y+(~z+1))>>31;
return ((~a1&((a2&z)|(~a2&x))) | (a1& ((a3&z)|( ~a3&y)))) ;
}
Assuming that your code as written doesn't use any "illegal" operations (i.e. you are OK with +1), then you can write
#include <stdio.h>
int main(void) {
int x, y, z;
int mxy, mxyz;
x = 5;
y = 123;
z = 9;
mxy = x - ((x - y) & ((x - y) >> 31)); // max(x, y)
mxyz = mxy - ((mxy - z) & ((mxy - z) >> 31));
printf("max is %d\n", mxyz);
}
Only 10 operations. Every - can be replaced with a ~ and +1 adding a further 6 operations. I will leave that as an exercise. Point is - you don't need to evaluate max(x,y) and max(y,z) and max(x,z) separately. max(x,y,z) = max(max(x,y),z)... and that's where your savings come from.
UPDATE using only +1 and bitwise operators:
#include <stdio.h>
int main(void) {
unsigned int x, y, z, r;
unsigned int mxy, mxyz;
unsigned int xmy;
unsigned int mxymz;
x = 5;
y = 123;
z = 9;
xmy = x + (~y+1); // x minus y
mxy = x + ~(xmy & (xmy >> 31)) + 1; // max(x, y)
mxymz = mxy + (~z+1); // max(x,y) minus z
mxyz = mxy + (~(mxymz & (mxymz >> 31))+1); // max(x,y,z)
printf("max is %d\n", mxyz);
}
Total of 16 operations (plus 3 intermediate assignments to variables, if you're counting those). Using only + ~ >>. I think that counts.
A couple of points:
the hard-wired value 31 really should be sizeof(int) * CHAR_BIT - 1
You should be using unsigned integers since the >>31 operation is not recommended on signed integers (see https://www.securecoding.cert.org/confluence/display/seccode/INT13-C.+Use+bitwise+operators+only+on+unsigned+operands )

Even parity of a unsigned int [duplicate]

This question already has answers here:
Count the number of set bits in a 32-bit integer
(65 answers)
Closed 9 years ago.
/*A value has even parity if it has an even number of 1 bits.
*A value has an odd parity if it has an odd number of 1 bits.
*For example, 0110 has even parity, and 1110 has odd parity.
*Return 1 iff x has even parity.
*/
int has_even_parity(unsigned int x) {
}
I'm not sure where to begin writing this function, I'm thinking that I loop through the value as an array and apply xor operations on them.
Would something like the following work? If not, what is the way to approach this?
int has_even_parity(unsigned int x) {
int i, result = x[0];
for (i = 0; i < 3; i++){
result = result ^ x[i + 1];
}
if (result == 0){
return 1;
}
else{
return 0;
}
}
Option #1 - iterate the bits in the "obvious" way, at O(number of bits):
int has_even_parity(unsigned int x)
{
int p = 1;
while (x)
{
p ^= x&1;
x >>= 1; // at each iteration, we shift the input one bit to the right
}
return p;
Option #2 - iterate only the bits that are set to 1, at O(number of 1s):
int has_even_parity(unsigned int x)
{
int p = 1;
while (x)
{
p ^= 1;
x &= x-1; // at each iteration, we set the least significant 1 to 0
}
return p;
}
Option #3 - use the SWAR algorithm for counting 1s, at O(log(number of bits)):
http://aggregate.org/MAGIC/#Population%20Count%20%28Ones%20Count%29
You can't access an integer as an array,
unsigned x = ...;
// x[0]; doesn't work
But you can use bitwise operations.
unsigned x = ...;
int n = ...;
int bit = (x >> n) & 1u; // Extract bit n, where bit 0 is the LSB
There is a clever way to do this, assuming 32-bit integers:
unsigned parity(unsigned x)
{
x ^= x >> 16;
x ^= x >> 8;
x ^= x >> 4;
x ^= x >> 2;
x ^= x >> 1;
return x & 1;
}

Resources