Abhijit Kumar
Abhijit Kumar

Reputation:

How can I concatenate upper and lower nibbles stored sequentially in an array?

I have an array which contains a list of nibbles:

{0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, ...}

I want to combine adjacent nibbles into single bytes by left-shifting the upper nibble and concatenating it with the lower one. The output should look as follows:

{0xab, 0xcd, 0xef, ...}

How can I accomplish this in C?

Upvotes: 2

Views: 8119

Answers (4)

Neeraj
Neeraj

Reputation: 11

May be this will help you, it nothing just a simple artical about the nibble(upper/lower)

This system is called Binary Coded Decimal or BCD which also occupies a nibble. In BCD, the binary patterns 1010 through 1111 do not represent valid BCD numbers, and cannot be used.

Conversion from Decimal to BCD is straightforward. You merely assign each digit of the decimal number to a byte and convert 0 through 9 to 0000 0000 through 0000 1001, but you cannot perform the repeated division by 2 as you did to convert decimal to binary.

Let us see how this works. Determine the BCD value for the decimal number 5,319. Since there are four digits in our decimal number, there are four bytes in our BCD number. They are:

Final Number is -5319

    Thousands               Hundreds             Tens                    Units 
       [5]                      [3]               [1]                      [9] 
    0 0 0 0 0 1 0 1      0 0 0 0 0 0 1 1     0 0 0 0 0 0 0 1     0 0 0 0 1 0 0 1 

Since computer storage requires the minimum of 1 byte, you can see that the upper nibble of each BCD number is wasted storage. BCD is still a weighted position number system so you may perform mathematics, but we must use special techniques in order to obtain a correct answer.


PACKED BCD

Since storage on disk and in RAM is so valuable, we would like to eliminate this wasted storage. This may be accomplished by packing the BCD numbers. In a packed BCD number, each nibble has a weighted position starting from the decimal point. Therefore, instead of requiring 4 bytes to store the BCD number 5319, we would only require 2 bytes, half the storage. The upper nibble of the upper byte of our number would store the THOUSANDS value while the lower nibble of the upper byte would store the HUNDREDS value. Likewise, the lower byte would store the TENS value in the upper nibble and the UNITS digit in the lower nibble. Therefore, our previous example would be:

Thousands - Hundreds          Tens - Units 
        [53]                       [19] 
0 1 0 1 0 0 1 1              0 0 0 1 1 0 0 1 

Upvotes: 1

James Eichele
James Eichele

Reputation: 119164

Just for kicks, here is a version that produces the concatenated array without using a second array. It simply overwrites the first half of the original array with the new values:

char * writePtr = originalArray;
char * readPtr = originalArray;
while (readPtr < (originalArray + arraySize))
{
    *writePtr = (*readPtr << 4) | *(readPtr + 1);
    readPtr += 2;
    writePtr++;
}

Upvotes: 3

jpalecek
jpalecek

Reputation: 47770

Something like

char *input, *output;
int i;
...
for(i=0; i<len; i+=2) {
  output[i/2]=(input[i]<<4) | input[i+1];
}

provided output as an array at least half as long as input, and the upper nibbles are not set in the input.

Upvotes: 7

ChrisN
ChrisN

Reputation: 16953

Without writing the whole code for you, here's a hint:

unsigned int Nibble1 = 0x0A;
unsigned int Nibble2 = 0x0B;

unsigned int Result = (Nibble1 << 4) | Nibble2; // Result = 0xAB

You then just need to write a loop that iterates through your input array two elements at a time and writes to an output array.

I hope this helps!

Upvotes: 6

Related Questions