Give byte existing byte value (homework) - c

I need to make an assignment where I switch the values of a certain int. For example: 0xaabbccdd should be turned in to 0xddccbbaa.
I've already extraced all of the bytes from the given number and their values are correct.
unsigned int input;
scanf("%i", &input);
unsigned int first_byte = (input >> (8*0)) & 0xff;
unsigned int second_byte = (input >> (8*1)) & 0xff;
unsigned int third_byte = (input >> (8*2)) & 0xff;
unsigned int fourth_byte = (input >> (8*3)) & 0xff;
Now I'm trying to set an empty int variable (aka 00000000 00000000 00000000 00000000) to those byte values, but turned around. So how can I say that the first byte of the empty variable is the fourth byte of the given input? I've been trying different combinations of bitwise operations, but I can't seem to wrap my head around it. I'm pretty sure I should be able to do something like:
answer *first byte* | fourth_byte;
I would appreciate any help, becau'se I've been stuck and searching for an answer for a couple of hours now.

Based on your code :
#include <stdio.h>
int main(void)
{
unsigned int input = 0xaabbccdd;
unsigned int first_byte = (input >> (8*0)) & 0xff;
unsigned int second_byte = (input >> (8*1)) & 0xff;
unsigned int third_byte = (input >> (8*2)) & 0xff;
unsigned int fourth_byte = (input >> (8*3)) & 0xff;
printf(" 1st : %x\n 2nd : %x\n 3rd : %x\n 4th : %x\n",
first_byte,
second_byte,
third_byte,
fourth_byte);
unsigned int combo = first_byte<<8 | second_byte;
combo = combo << 8 | third_byte;
combo = combo << 8 | fourth_byte;
printf(" combo : %x ", combo);
return 0;
}
It will output 0xddccbbaa
Here's a more elegant function to do this :
unsigned int setByte(unsigned int input, unsigned char byte, unsigned int position)
{
if(position > sizeof(unsigned int) - 1)
return input;
unsigned int orbyte = byte;
input |= byte<<(position * 8);
return input;
}
Usage :
unsigned int combo = 0;
combo = setByte(combo, first_byte, 3);
combo = setByte(combo, second_byte, 2);
combo = setByte(combo, third_byte, 1);
combo = setByte(combo, fourth_byte, 0);
printf(" combo : %x ", combo);

unsigned int result;
result = ((first_byte <<(8*3)) | (second_byte <<(8*2)) | (third_byte <<(8*1)) | (fourth_byte))

You can extract the bytes and put them back in order as you're trying, that's a perfectly valid approach. But here are some other possibilities:
bswap, if you have access to it. It's an x86 instruction that does exactly this. It doesn't get any simpler. Similar instructions may exist on other platforms. Probably not good for a C assignment though.
Or, swapping adjacent "fields". If you have AABBCCDD and first swap adjacent 8-bit groups (get BBAADDCC), and then swap adjacent 16-bit groups, you get DDCCBBAA as desired. This can be implemented, for example: (not tested)
x = ((x & 0x00FF00FF) << 8) | ((x >> 8) & 0x00FF00FF);
x = ((x & 0x0000FFFF) << 16) | ((x >> 16) & 0x0000FFFF);
Or, a closely related method but with rotates. In AABBCCDD, AA and CC are both rotated to the left by 8 positions, and BB and DD are both rotated right by 8 positions. So you get:
x = rol(x & 0xFF00FF00, 8) | ror(x & 0x00FF00FF, 8);
This requires rotates however, which most high level languages don't provide, and emulating them with two shifts and an OR negates their advantage.

#include <stdio.h>
int main(void)
{
unsigned int input = 0xaabbccdd,
byte[4] = {0},
n = 0,
output = 0;
do
{
byte[n] = (input >> (8*n)) & 0xff;
n = n + 1;
}while(n < 4);
n = 0;
do
{
printf(" %d : %x\n", byte[n]);
n = n + 1;
}while (n < 4);
n = 0;
do
{
output = output << 8 | byte[n];
n = n + 1;
}while (n < 4);
printf(" output : %x ", output );
return 0;
}
You should try to avoid repeating code.

Related

RGB color converting into 5:6:5 format

This code is supposed to convert a RGB color to an hex in the 5:6:5 format. 5 bits for red, 6 bits for green, 5 bits for blue. I have no idea why this is not picturing the correct color.
Does anyone knows why?
int rgb(unsigned char r, unsigned char g, unsigned char b) {
if (r < 0 || 255 < r || g < 0 || 255 < g || b < 0 || b > 255)
return -1;
int result;
int red = r * 31 / 255;
int green = g * 63/ 255;
int blue = b * 31 / 255;
//int result = (red << 11) | (green << 5) | blue;
green = green << 5;
red = red << 11;
result = red | green | blue;
//tests
printf("\nred: %x", red);
printf("\ngreen: %x", green);
printf("blue: %x\n", blue);
printf("result: %x\n", result);
return result;
}
After another look at your question I don't really know what you're asking about. Anyway, I'm leaving my answer in case you find it useful.
Your rgb(...) function takes three byte arguments - they have 8 bits each.
Let's take "red" component into account first. If you pass XXXX XXXX (8 bits) and want to convert them into a 5-bit equivalent representation, it's enough to shift the value right by 3 bits, so:
int red = r >> 3;
The value XXXXXXXX will be truncated in the place of the pipeline character:
XXXXX|xxx
so that only the bits marked with large Xes will be saved to the red variable.
The same goes for blue, and for the green component, you have to shift it right by two (8 - 6 = 2).
You probably want your function to work like this:
int rgb(unsigned char r, unsigned char g, unsigned char b) {
if (r < 0 || 255 < r || g < 0 || 255 < g || b < 0 || b > 255)
return -1;
unsigned char red = r >> 3;
unsigned char green = g >> 2;
unsigned char blue = b >> 3;
int result = (red << (5 + 6)) | (green << 5) | blue;
//tests
printf("red: %x\n", red);
printf("green: %x\n", green);
printf("blue: %x\n", blue);
printf("result: %x\n", result);
return result;
}
Assuming 8-bit char, your unsigned char arguments must already be in the 0-255 range, so you don't need to check that. And the multiplication you're trying to use to scale the color components is probably not a good approach.
A better approach would be to AND each component with a mask to get the upper 5 bits (6 for green), shift them to the proper positions, and OR them together. When shifting, remember to account for the fact that you're using the upper bits... and for the last component, you won't need to AND with a mask because the unneeded bits are shifted out anyway. So this gets you something like this (as the only line in your function):
return ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
(r & 0xf8) gets the upper 5 bits of r. These are then left shifted by 8 bits, so they move from positions 3..7 into 11..15.
(g & 0xfc) gets the upper 6 bits of g. Those are then left shifted by 3 bits, from 2..7 into 5..10.
b doesn't need to be masked... it's just shifted right 3 bits. Its upper 5 bits are then moved from 3..7 into 0..4, and its lower 3 bits are discarded when they're shifted out.
All those values are then ORed together to get your RGB 5:6:5 value, and returned.
Alternatively, if you prefer shifts over AND, you can use:
return ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
You might also consider changing the return type to an unsigned 16-bit type and not worry about returning an error value (there isn't really any kind of error condition to check for here).
You need a function that shows you the binary contents, so that you can "count" the bits and better find errors. My approach added a rounding routine:
#include <stdio.h>
#include <math.h>
char* sprint_bin (unsigned a, unsigned count, char* bin)
{
char* p = bin;
unsigned i;
unsigned mask = pow(2,count-1);
unsigned b;
for (i = 0; i<count; ++i)
{
b = (a & mask) ? '1' : '0';
p += sprintf (p, "%c ",b);
mask >>= 1;
}
return bin;
}
unsigned rgb(unsigned char r, unsigned char g, unsigned char b) {
char bin[64];
int result;
printf("r: %s\n", sprint_bin(r,8,bin));
printf("g: %s\n", sprint_bin(g,8,bin));
printf("b: %s\n", sprint_bin(b,8,bin));
// masks
unsigned red = (unsigned)(r & 0xF8) << 8;
unsigned green = (unsigned)(g & 0xFC) << 3;
unsigned blue = (unsigned)(b >> 3);
// rounding
if ((r & 4) && (r<0xF8)) red += 0x0800;
if ((g & 2) && (g<0xFC)) green += 0x20;
if ((b & 4) && (b<0xF8)) blue++;
// 5:6:5
result = red | green | blue;
// test
printf("red: %s\n", sprint_bin(red,16,bin));
printf("green: %s\n", sprint_bin(green,16,bin));
printf("blue: %s\n", sprint_bin(blue,16,bin));
printf("result: %s\n", sprint_bin(result,32,bin));
return result;
}
int main ()
{
rgb (0x81, 0x87, 0x9F);
return 0;
}

Swap byte 2 and 4 in a 32 bit integer

I had this interview question -
Swap byte 2 and byte 4 within an integer sequence.
Integer is a 4 byte wide i.e. 32 bits
My approach was to use char *pointer and a temp char to swap the bytes.
For clarity I have broken the steps otherwise an character array can be considered.
unsigned char *b2, *b4, tmpc;
int n = 0xABCD; ///expected output 0xADCB
b2 = &n; b2++;
b4 = &n; b4 +=3;
///swap the values;
tmpc = *b2;
*b2 = *b4;
*b4 = tmpc;
Any other methods?
int someInt = 0x12345678;
int byte2 = someInt & 0x00FF0000;
int byte4 = someInt & 0x000000FF;
int newInt = (someInt & 0xFF00FF00) | (byte2 >> 16) | (byte4 << 16);
To avoid any concerns about sign extension:
int someInt = 0x12345678;
int newInt = (someInt & 0xFF00FF00) | ((someInt >> 16) & 0x000000FF) | ((someInt << 16) & 0x00FF0000);
(Or, to really impress them, you could use the triple XOR technique.)
Just for fun (probably a tupo somewhere):
int newInt = someInt ^ ((someInt >> 16) & 0x000000FF);
newInt = newInt ^ ((newInt << 16) & 0x00FF0000);
newInt = newInt ^ ((newInt >> 16) & 0x000000FF);
(Actually, I just tested it and it works!)
You can mask out the bytes you want and shift them around. Something like this:
unsigned int swap(unsigned int n) {
unsigned int b2 = (0x0000FF00 & n);
unsigned int b4 = (0xFF000000 & n);
n ^= b2 | b4; // Clear the second and fourth bytes
n |= (b2 << 16) | (b4 >> 16); // Swap and write them.
return n;
}
This assumes that the "first" byte is the lowest order byte (even if in memory it may be stored big-endian).
Also it uses unsigned ints everywhere to avoid right shifting introducing extra 1s due to sign extension.
What about unions?
int main(void)
{
char tmp;
union {int n; char ary[4]; } un;
un.n = 0xABCDEF00;
tmp = un.ary[3];
un.ary[3] = un.ary[1];
un.ary[1] = tmp;
printf("0x%.2X\n", un.n);
}
in > 0xABCDEF00
out>0xEFCDAB00
Please don't forget to check endianess. this only work for little endian, but should not be hard to make it portable.

how to make a bit-set/byte-array conversion in c

Given an array,
unsigned char q[32]="1100111...",
how can I generate a 4-bytes bit-set, unsigned char p[4], such that, the bit of this bit-set, equals to value inside the array, e.g., the first byte p[0]= "q[0] ... q[7]"; 2nd byte p[1]="q[8] ... q[15]", etc.
and also how to do it in opposite, i.e., given bit-set, generate the array?
my own trial out for the first part.
unsigned char p[4]={0};
for (int j=0; j<N; j++)
{
if (q[j] == '1')
{
p [j / 8] |= 1 << (7-(j % 8));
}
}
Is the above right? any conditions to check? Is there any better way?
EDIT - 1
I wonder if above is efficient way? As the array size could be upto 4096 or even more.
First, Use strtoul to get a 32-bit value. Then convert the byte order to big-endian with htonl. Finally, store the result in your array:
#include <arpa/inet.h>
#include <stdlib.h>
/* ... */
unsigned char q[32] = "1100111...";
unsigned char result[4] = {0};
*(unsigned long*)result = htonl(strtoul(q, NULL, 2));
There are other ways as well.
But I lack <arpa/inet.h>!
Then you need to know what byte order your platform is. If it's big endian, then htonl does nothing and can be omitted. If it's little-endian, then htonl is just:
unsigned long htonl(unsigned long x)
{
x = (x & 0xFF00FF00) >> 8) | (x & 0x00FF00FF) << 8);
x = (x & 0xFFFF0000) >> 16) | (x & 0x0000FFFF) << 16);
return x;
}
If you're lucky, your optimizer might see what you're doing and make it into efficient code. If not, well, at least it's all implementable in registers and O(log N).
If you don't know what byte order your platform is, then you need to detect it:
typedef union {
char c[sizeof(int) / sizeof(char)];
int i;
} OrderTest;
unsigned long htonl(unsigned long x)
{
OrderTest test;
test.i = 1;
if(!test.c[0])
return x;
x = (x & 0xFF00FF00) >> 8) | (x & 0x00FF00FF) << 8);
x = (x & 0xFFFF0000) >> 16) | (x & 0x0000FFFF) << 16);
return x;
}
Maybe long is 8 bytes!
Well, the OP implied 4-byte inputs with their array size, but 8-byte long is doable:
#define kCharsPerLong (sizeof(long) / sizeof(char))
unsigned char q[8 * kCharsPerLong] = "1100111...";
unsigned char result[kCharsPerLong] = {0};
*(unsigned long*)result = htonl(strtoul(q, NULL, 2));
unsigned long htonl(unsigned long x)
{
#if kCharsPerLong == 4
x = (x & 0xFF00FF00UL) >> 8) | (x & 0x00FF00FFUL) << 8);
x = (x & 0xFFFF0000UL) >> 16) | (x & 0x0000FFFFUL) << 16);
#elif kCharsPerLong == 8
x = (x & 0xFF00FF00FF00FF00UL) >> 8) | (x & 0x00FF00FF00FF00FFUL) << 8);
x = (x & 0xFFFF0000FFFF0000UL) >> 16) | (x & 0x0000FFFF0000FFFFUL) << 16);
x = (x & 0xFFFFFFFF00000000UL) >> 32) | (x & 0x00000000FFFFFFFFUL) << 32);
#else
#error Unsupported word size.
#endif
return x;
}
For char that isn't 8 bits (DSPs like to do this), you're on your own. (This is why it was a Big Deal when the SHARC series of DSPs had 8-bit bytes; it made it a LOT easier to port existing code because, face it, C does a horrible job of portability support.)
What about arbitrary length buffers? No funny pointer typecasts, please.
The main thing that can be improved with the OP's version is to rethink the loop's internals. Instead of thinking of the output bytes as a fixed data register, think of it as a shift register, where each successive bit is shifted into the right (LSB) end. This will save you from all those divisions and mods (which, hopefully, are optimized away to bit shifts).
For sanity, I'm ditching unsigned char for uint8_t.
#include <stdint.h>
unsigned StringToBits(const char* inChars, uint8_t* outBytes, size_t numBytes,
size_t* bytesRead)
/* Converts the string of '1' and '0' characters in `inChars` to a buffer of
* bytes in `outBytes`. `numBytes` is the number of available bytes in the
* `outBytes` buffer. On exit, if `bytesRead` is not NULL, the value it points
* to is set to the number of bytes read (rounding up to the nearest full
* byte). If a multiple of 8 bits is not read, the last byte written will be
* padded with 0 bits to reach a multiple of 8 bits. This function returns the
* number of padding bits that were added. For example, an input of 11 bits
* will result `bytesRead` being set to 2 and the function will return 5. This
* means that if a nonzero value is returned, then a partial byte was read,
* which may be an error.
*/
{ size_t bytes = 0;
unsigned bits = 0;
uint8_t x = 0;
while(bytes < numBytes)
{ /* Parse a character. */
switch(*inChars++)
{ '0': x <<= 1; ++bits; break;
'1': x = (x << 1) | 1; ++bits; break;
default: numBytes = 0;
}
/* See if we filled a byte. */
if(bits == 8)
{ outBytes[bytes++] = x;
x = 0;
bits = 0;
}
}
/* Padding, if needed. */
if(bits)
{ bits = 8 - bits;
outBytes[bytes++] = x << bits;
}
/* Finish up. */
if(bytesRead)
*bytesRead = bytes;
return bits;
}
It's your responsibility to make sure inChars is null-terminated. The function will return on the first non-'0' or '1' character it sees or if it runs out of output buffer. Some example usage:
unsigned char q[32] = "1100111...";
uint8_t buf[4];
size_t bytesRead = 5;
if(StringToBits(q, buf, 4, &bytesRead) || bytesRead != 4)
{
/* Partial read; handle error here. */
}
This just reads 4 bytes, and traps the error if it can't.
unsigned char q[4096] = "1100111...";
uint8_t buf[512];
StringToBits(q, buf, 512, NULL);
This just converts what it can and sets the rest to 0 bits.
This function could be done better if C had the ability to break out of more than one level of loop or switch; as it stands, I'd have to add a flag value to get the same effect, which is clutter, or I'd have to add a goto, which I simply refuse.
I don't think that will quite work. You are comparing each "bit" to 1 when it should really be '1'. You can also make it a bit more efficient by getting rid of the if:
unsigned char p[4]={0};
for (int j=0; j<32; j++)
{
p [j / 8] |= (q[j] == `1`) << (7-(j % 8));
}
Going in reverse is pretty simple too. Just mask for each "bit" that you set earlier.
unsigned char q[32]={0};
for (int j=0; j<32; j++) {
q[j] = p[j / 8] & ( 1 << (7-(j % 8)) ) + '0';
}
You'll notice the creative use of (boolean) + '0' to convert between 1/0 and '1'/'0'.
According to your example it does not look like you are going for readability, and after a (late) refresh my solution looks very similar to Chriszuma except for the lack of parenthesis due to order of operations and the addition of the !! to enforce a 0 or 1.
const size_t N = 32; //N must be a multiple of 8
unsigned char q[N+1] = "11011101001001101001111110000111";
unsigned char p[N/8] = {0};
unsigned char r[N+1] = {0}; //reversed
for(size_t i = 0; i < N; ++i)
p[i / 8] |= (q[i] == '1') << 7 - i % 8;
for(size_t i = 0; i < N; ++i)
r[i] = '0' + !!(p[i / 8] & 1 << 7 - i % 8);
printf("%x %x %x %x\n", p[0], p[1], p[2], p[3]);
printf("%s\n%s\n", q,r);
If you are looking for extreme efficiency, try to use the following techniques:
Replace if by subtraction of '0' (seems like you can assume your input symbols can be only 0 or 1).
Also process the input from lower indices to higher ones.
for (int c = 0; c < N; c += 8)
{
int y = 0;
for (int b = 0; b < 8; ++b)
y = y * 2 + q[c + b] - '0';
p[c / 8] = y;
}
Replace array indices by auto-incrementing pointers:
const char* qptr = q;
unsigned char* pptr = p;
for (int c = 0; c < N; c += 8)
{
int y = 0;
for (int b = 0; b < 8; ++b)
y = y * 2 + *qptr++ - '0';
*pptr++ = y;
}
Unroll the inner loop:
const char* qptr = q;
unsigned char* pptr = p;
for (int c = 0; c < N; c += 8)
{
*pptr++ =
qptr[0] - '0' << 7 |
qptr[1] - '0' << 6 |
qptr[2] - '0' << 5 |
qptr[3] - '0' << 4 |
qptr[4] - '0' << 3 |
qptr[5] - '0' << 2 |
qptr[6] - '0' << 1 |
qptr[7] - '0' << 0;
qptr += 8;
}
Process several input characters simultaneously (using bit twiddling hacks or MMX instructions) - this has great speedup potential!

convert number to slash divided hex path

I need to generate a path string from a number (in C)
e.g:
53431453 -> 0003/2F4/C9D
what I have so far is this:
char *id_to_path(long long int id, char *d)
{
char t[MAX_PATH_LEN];
sprintf(t, "%010llX", id);
memcpy(d, t, 4);
memcpy(d+5, t+4, 3);
memcpy(d+9, t+7, 4);
d[4] = d[8] = '/';
return d;
}
I'm wondering if there's a better way, e.g to generate the final string in one step instead of doing sprintf and then moving the bytes around.
Thanks
Edit:
I benchmarked the given solutions
results in operations per second (higher is better):
(1) sprintf + memcpy : 3383005
(2) single sprintf : 2219253
(3) not using sprintf : 10917996
when compiling with -O3 the difference is even greater:
(1) 4422101
(2) 2207157
(3) 178756551
Since this function will be called a lot, I'll use the fastest solution even though the single sprintf is the shortest and most readable.
Thanks for your answers!
Not tested, but you can split the int into three then print it:
char *id_to_path(long long int id, char *d)
{
sprintf(d, "%04llX/%03llX/%03llX", ( id >> 24 ) & 0xffff, ( id >> 12 ) & 0xfff, id & 0xfff);
return d;
}
Since the string uses hex, it can be quite easily done using shift and bit operators.
Getting the 4 highest bits from the value can be done like this:
id >> 28
Converting this to a digit simply means adding the character '0' to it, like this:
'0' + (id >> 28)
However, since A, B, C, ... don't immediately follow the character 9, we have to perform an additional check, something like:
if (c > '9') c = c - '9' - 1 'A'
If we want the next 4 bits, we should only shift 24 bits, but then we still have the highest 4 bits left, so we should mask them out, like this:
(id >> 24) & 0xf
If we pour this into your function, we get this:
char convert (int value)
{
char c = value + '0';
if (c > '9') c = c - '9' - 1 + 'A';
return c;
}
void main()
{
long id = 53431453;
char buffer[20];
buffer[0] = convert(id >> 28);
buffer[1] = convert((id >> 24) & 0xf);
buffer[2] = convert((id >> 20) & 0xf);
buffer[3] = convert((id >> 16) & 0xf);
buffer[4] = convert((id >> 12) & 0xf);
buffer[5] = convert((id >> 8) & 0xf);
buffer[6] = convert((id >> 4) & 0xf);
buffer[7] = convert((id >> 0) & 0xf);
buffer[8] = '\0';
}
Now adjust this to add the slashes in between, the extra zeroes in the beginning, ...
EDIT:
I know this is not in one step, but it is better extensible if you later want to change the places of the slashes, ...
Did you try this option yet?
typedef struct {
unsigned f7 : 4;
unsigned f6 : 4;
unsigned f5 : 4;
unsigned f4 : 4;
unsigned f3 : 4;
unsigned f2 : 4;
unsigned f1 : 4;
unsigned f0 : 4;
} lubf;
#define convert(a) ( a > 9 ? a + 'A' - 10 : a + '0' )
int main()
{
lubf bf;
unsigned long a = 0xABCDE123;
memcpy(&bf, &a, sizeof(a));
char arr[9];
arr[0] = convert(bf.f0);
arr[1] = convert(bf.f1);
arr[2] = convert(bf.f2);
arr[3] = convert(bf.f3);
arr[4] = convert(bf.f4);
arr[5] = convert(bf.f5);
arr[6] = convert(bf.f6);
arr[7] = convert(bf.f7);
arr[8] = '\0';
printf("%lX : %s\n", a, arr);
};

Swap bits in a number in C [duplicate]

This question already has answers here:
Best practices for circular shift (rotate) operations in C++
(16 answers)
Closed 4 years ago.
In a C interview, I was asked to swap the first 4-bits of a number with the last 4 bit. (eg. 1011 1110 should be 1110 1011.)
Does anyone have a solution for this?
If you haven't seen or done much bit twiddling, a good resource to study is:
Bit Twiddling Hacks
unsigned char c;
c = ((c & 0xf0) >> 4) | ((c & 0x0f) << 4);
There is no "correct answer" to this kind of interview question. There are several ways to do this (lookup tables, anyone?) and the tradeoffs between each way (readability vs. performance vs. portability vs. maintainability) would need to be discussed.
The question is just an opening gambit to get you discussing some of the above issues, and to determine how 'deeply' you can discuss such problems.
Just use a temporary variable and move the last bit into that variable, then shift the bit in that direction and end of masking in the bits in the tmp var and you are done.
Update:
Let's add some code and then you can choose what is more readable.
The working one liner
unsigned int data = 0x7654;
data = (data ^ data & 0xff) | ((data & 0xf) << 4) | ((data & 0xf0) >> 4);
printf("data %x \n", data);
the same code but with some tmp vars
unsigned int data = 0x7654;
unsigned int tmp1 = 0;
unsigned int tmp2 = 0;
tmp1 = (0x0f&data)<<4;
tmp2 = (0xf0&data)>>4;
tmp1 = tmp1 | tmp2;
data = data ^ (data & 0xff);
data = data | tmp1;
printf("data %x \n", data);
Well the one liner is shorter anyway :)
Update:
And if you look at the asm code that gcc generated with -Os -S, my guess is that they are more or less identical since the overhead is removed during the "compiler optimisation" part.
There's no need for a temporary variable, something like this should do it:
x = ((x & 0xf) << 4) | ((x & 0xf0) >> 4);
There is a potential pitfall with this depending on the exact type of x. Identification of this problem is left as an exercise for the reader.
C++-like pseudocode (can be easily rewritten to not use temporary variables):
int firstPart = source & 0xF;
int offsetToHigherPart = sizeof( source ) * CHAR_BIT - 4;
int secondPart = ( source >> offsetToHigherPart ) & 0xF;
int maskToSeparateMiddle = -1 & ( ~0xF ) & ( ~( 0xF << offsetToHigherPart );
int result = ( firstPart << offsetToHigherPart ) | secondPart | (source & maskToSeparateMiddle);
This will require CHAR_BIT to be defined. It is usually in limits.h and is defined as 8 bits but is strictly speaking platform-dependent and can be not defined at all in the headers.
unsigned char b;
b = (b << 4) | (b >> 4);
x86 assembly:
asm{
mov AL, 10111110b
rol AL
rol AL
rol AL
rol AL
}
http://www.geocities.com/SiliconValley/Park/3230/x86asm/asml1005.html
Are you looking for something more clever than standard bit-shifting?
(assuming a is an 8-bit type)
a = ((a >> 4) & 0xF) + ((a << 4) &0xF0)
The easiest is (t is unsigned):
t = (t>>4)|(t<<4);
But if you want to obfuscate your code, or to swap other bits combination you can use this base:
mask = 0x0F & (t ^ (t >> 4));
t ^= (mask | (mask << 4));
/*swaping four bits*/
#include<stdio.h>
void printb(char a) {
int i;
for( i = 7; i >= 0; i--)
printf("%d", (1 & (a >> i)));
printf("\n");
}
int swap4b(char a) {
return ( ((a & 0xf0) >> 4) | ((a & 0x0f) << 4) );
}
int main()
{
char a = 10;
printb(a);
a = swap4b(a);
printb(a);
return 0;
}
This is how you swap bits entirely, to change the bit endianess in a byte.
"iIn" is actually an integer because I'm using it to read from a file. I need the bits in an order where I can easily read them in order.
// swap bits
iIn = ((iIn>>4) & 0x0F) | ((iIn<<4) & 0xF0); // THIS is your solution here.
iIn = ((iIn>>2) & 0x33) | ((iIn<<2) & 0xCC);
iIn = ((iIn>>1) & 0x55) | ((iIn<<1) & 0xAA);
For swapping just two nibbles in a single byte, this is the most efficient way to do this, and it's probably faster than a lookup table in most situations.
I see a lot of people doing shifting, and forgetting to do the masking here. This is a problem when there is sign extension. If you have the type of unsigned char, it's fine since it's a unsigned 8 bit quantity, but it will fail with any other type.
The mask doesn't add overhead, with an unsigned char, the mask is implied anyhow, and any decent compiler will remove unnecessary code and has for 20 years.
Solution for generic n bits swapping between last and first.
Not verified for case when total bits are less than 2n.
here 7 is for char, take 31 for integer.
unsigned char swapNbitsFtoL(unsigned char num, char nbits)
{
unsigned char u1 = 0;
unsigned char u2 = 0;
u1 = ~u1;
u1 &= num;
u1 = (u1 >> (7 - (nbits - 1))); /* Here nbits is number of n=bits so I have taken (nbits - 1). */
u2 = ~u2;
u2 &= num;
u2 = (u2 << (7 - (nbits - 1))); /* Here nbits is number of n=bits so I have taken (nbits - 1). */
u1 |= u2; /* u1 have first and last swapped n bits with */
u2 = 0;
u2 = ~u2;
u2 = ((u2 >> (7 - (nbits - 1))) | (u2 << (7 - (nbits - 1))));
bit_print(u2);
u2 = ~u2;
u2 &= num;
return (u1 | u2);
}
My skills in this area are new and therefore unproven so if I'm wrong then I learn something new, which is at least a part of the point of Stack Overflow.
Would a bitmask and XOR work also?
Like so?
var orginal=
var mask =00001110 //I may have the mask wrong
var value=1011 1110
var result=value^mask;
I might be misunderstanding things, forgive me if I've screwed up entriely.
#include <stdio.h>
#include <conio.h>
#include <math.h>
void main() {
int q,t,n,a[20],j,temp;
int i=0;
int s=0;
int tp=0;
clrscr();
printf("\nenter the num\n");
scanf("%d",&n);
t=n;
while(n>0) {
a[i]=n%2;
i++;
n=n/2;
}
printf("\n\n");
printf("num:%d\n",t);
printf("number in binary format:");
for(j=i-1;j>=0;j--) {
printf("%d",a[j]);
}
printf("\n");
temp=a[i-1];
a[i-1]=a[0];
a[0]=temp;
printf("number in binary format wid reversed boundary bits:");
for(j=i-1;j>=0;j--) {
printf("%d",a[j]);
}
printf("\n");
q=i-1;
while(q>=0) {
tp=pow(2,q);
s=s+(tp*a[q]);
q--;
}
printf("resulatnt number after reversing boundary bits:%d",s);
printf("\n");
getch();
}

Resources