# how to replace given nibbles with another set of nibbles in an integer

4

Suppose you have an integer `a = 0x12345678` & a short `b = 0xabcd`

What i wanna do is replace the given nibbles in `integer a` with nibbles from `short b`

Eg: Replace 0,2,5,7th nibbles in `a = 0x12345678` (where 8 = 0th nibble, 7=1st nibble, 6=2nd nibble and so on...) with nibbles from `b = 0xabcd` (where d = 0th nibble, c=1st nibble, b=2nd nibble & so on...)

My approach is -

1. Clear the bits we're going to replace from `a`. like `a = 0x02045070`
2. Create the mask from the short `b` like `mask = 0xa0b00c0d`
3. bitwise `OR` them to get the result. `result = a| mask` i.e `result = 0xa2b45c7d` hence nibbles replaced.

My problem is I don't know any efficient way to create the desired mask (like in step 2) from the given `short b`

If you can give me an efficient way of doing so, it would be a great help to me and I thank you for that in advance ;)

EDIT:
My code to solve the problem (not good enough though)
Any improvement is highly appreciated.

``````int index = {0,1,5,7}; // Given nibbles to be replaced in integer
int s = 0x01024300; // integer mask i.e. cleared nibbles
int r = 0x0000abcd; // short (converted to int )
r = ((r & 0x0000000f) << 4*(index-0)) |
((r & 0x000000f0) << 4*(index-1)) |
((r & 0x00000f00) << 4*(index-2)) |
((r & 0x0000f000) << 4*(index-3));
s = s|r;
``````
c
bit-manipulation
bitwise-operators
bit-shift

1

Nibble has 4 bits, and according to your indexing scheme, the zeroth nibble is represented by least significant bits at positions 0-3, the first nibble is represented by least significant bits at positions 4-7, and so on.

Simply shift the values the necessary amount. This will set the nibble at position set by the variable index:

``````size_t index = 5;    //6th nibble is at index 5
size_t shift = 4 * index;    //6th nibble is represented by bits 20-23
unsigned long nibble = 0xC;
unsigned long result = 0x12345678;
result = result & ~( 0xFu << shift );    //clear the 6th nibble
result = result | ( nibble << shift );    //set the 6th nibble
``````

If you want to set more than one value, put this code in a loop. The variable index should be changed to an array of values, and variable nibble could also be an array of values, or it could contain more than one nibble, in which case you extract them one by one by shifting values to the right.

1

A lot depends on how your flexible you are in accepting the "nibble list" `index` in your case.

You mentioned that you can replace anywhere from 0 to 8 nibbles. If you take your nibble bits as an 8-bit bitmap, rather than as a list, you can use the bitmap as a lookup in a 256-entry table, which maps from bitmap to a (fixed) mask with 1s in the nibble positions. For example, for the nibble list {1, 3}, you'd have the bitmap `0b00001010` which would map to the mask `0x0000F0F0`.

Then you can use `pdep` which has intrinsics on gcc, clang, icc and MSVC on x86 to expand the bits in your short to the right position. E.g., for `b == 0xab` you'd have `_pdep_u32(b, mask) == 0x0000a0b0`.

If you aren't on a platform with `pdep`, you can accomplish the same thing with multiplication.

0

To be able to change easy the nibbles assignment, a bit-field union structure could be used:

Step 1 - create a union allowing to have nibbles access

``````typedef union u_nibble {
uint32_t dwValue;
uint16_t wValue;
struct sNibble {
uint32_t nib0: 4;
uint32_t nib1: 4;
uint32_t nib2: 4;
uint32_t nib3: 4;
uint32_t nib4: 4;
uint32_t nib5: 4;
uint32_t nib6: 4;
uint32_t nib7: 4;
} uNibble;
} NIBBLE;
``````

Step 2 - assign two NIBBLE items with your integer `a` and short `b`

``````NIBBLE myNibbles;
uint32_t a = 0x12345678;
uint16_t b = 0xabcd;

myNibbles.dwValue = a;
myNibbles.wValue = b;
``````

Step 3 - initialize nibbles of `a` by nibbles of `b`

``````printf("a = %08x\n",myNibbles.dwValue);
myNibbles.uNibble.nib0 = myNibbles.uNibble.nib0;
myNibbles.uNibble.nib2 = myNibbles.uNibble.nib1;
myNibbles.uNibble.nib5 = myNibbles.uNibble.nib2;
myNibbles.uNibble.nib7 = myNibbles.uNibble.nib3;
printf("a = %08x\n",myNibbles.dwValue);
``````

Output will be:

``````a = 12345678
a = a2b45c7d
``````
0

If I understand your goal, the fun you are having comes from the reversal of the order of your fill from the upper half to the lower half of your final number. (instead of `0, 2, 4, 6`, you want `0, 2, 5, 7`) It isn't any more difficult, but it does make you count where the holes are in the final number. If I understood, then you could mask with `0x0f0ff0f0` and then fill in the zeros with shifts of `16, 12, 4 and 0`. For example:

``````#include <stdio.h>

int main (void) {

unsigned a = 0x12345678, c = 0, mask = 0x0f0ff0f0;
unsigned short b = 0xabcd;

/* mask a, fill in the holes with the bits from b */
c = (a & mask) | (((unsigned)b & 0xf000) << 16);
c |= (((unsigned)b & 0x0f00) << 12);
c |= (((unsigned)b & 0x00f0) << 4);
c |= (unsigned)b & 0x000f;

printf (" a : 0x%08x\n b : 0x%0hx\n c : 0x%08x\n", a, b, c);

return 0;
}
``````

Example Use/Output

``````\$ ./bin/bit_swap_nibble
a : 0x12345678
b : 0xabcd
c : 0xa2b45c7d
``````

Let me know if I misunderstood, I'm happy to help further.

-1

With `nibble = 4 bits` and `unsigned int = 32 bits`, a nibble inside a unsigned int can be found as follows:

`x = 0x00a0b000`, find 3rd nibble in `x` i.e locate `'b'`. Note nibble index starts with `0`.

Now 3rd nibble is from `12th bit to 15th bit`.

3rd_nibble can be selected with `n = 2^16 - 2^12`. So, in `n` all the bits in 3rd nibble will be `1` and all the bits in other nibbles will be `0`. That is, `n=0x00001000`

In general, suppose if you want to find a continuous sequence of `1` in binary representation in which sequence starts from `Xth` bit to `Yth` bit then formula is `2^(Y+1) - 2^X`.

``````#include <stdio.h>

#define BUF_SIZE 33

char *int2bin(int a, char *buffer, int buf_size)
{
int i;
buffer[BUF_SIZE - 1] = '\0';

buffer += (buf_size - 1);

for(i = 31; i >= 0; i--)
{
*buffer-- = (a & 1) + '0';
a >>= 1;
}

return buffer;
}

int main()
{
unsigned int a = 0;
unsigned int b = 65535;
unsigned int b_nibble;
unsigned int b_at_a;
unsigned int a_nibble_clear;
char replace_with;
unsigned int ai;
char buffer[BUF_SIZE];

memset(replace_with, -1, sizeof(replace_with));
replace_with = 0; //replace 0th nibble of a with 0th nibble of b
replace_with = 1; //replace 2nd nibble of a with 1st nibble of b
replace_with = 2; //replace 5th nibble of a with 2nd nibble of b
replace_with = 3; //replace 7th nibble of a with 3rd nibble of b

int2bin(a, buffer, BUF_SIZE - 1);
printf("a               = %s, %08x\n", buffer, a);
int2bin(b, buffer, BUF_SIZE - 1);
printf("b               = %s, %08x\n", buffer, b);

for(ai = 0; ai < 8; ++ai)
{
if(replace_with[ai] != -1)
{
b_nibble = (b & (1LL << ((replace_with[ai] + 1)*4)) - (1LL << (replace_with[ai]*4))) >> (replace_with[ai]*4);
b_at_a = b_nibble << (ai * 4);
a_nibble_clear = (a & ~(a & (1LL << ((ai + 1) * 4)) - (1LL << (ai * 4))));
a = a_nibble_clear | b_at_a;
}
}

int2bin(a, buffer, BUF_SIZE - 1);
printf("a               = %s, %08x\n", buffer, a);

return 0;
}

Output:
a               = 00000000000000000000000000000000, 00000000
b               = 00000000000000001111111111111111, 0000ffff
a               = 11110000111100000000111100001111, f0f00f0f
``````

User contributions licensed under CC BY-SA 3.0