0

I have a problem with C's bitwise operations and can't "merge" two numbers together. Suppose I have the number 0x0A (or any 2 hexadecimal digits) and I want to replace the left digit with 0xF for example, That is: 00001010 -> 11111010 in terms of bitwise.

What I tried to do is the following:

  1. We drop the left digit of the 2-digit hex number by left shifting (sizeof(int)*8-4) times, thus leaving the rightmost bits that we care about, and then right shifting (unsigned) so that we get only the right hex digit in the end. In the example above it won't matter as it'll yield 'A' which is the same as 0x0A.
  2. The second step is to "merge" the digit we got in step one and the shifted hex digit we want to use, and we'll do that by using an OR gate.

Thus:

Hex number before and after step one: A (1010) Desired hex digit after shifting: F0 (1111 0000) OR gate:

00001010 OR 11110000 = 11111010 = 0xFA

However, for some reason, my C code does all of the above correctly, and just when applying OR it gives the result 0xFFFFFFFA (8-byte).

Is there something that I'm missing on how C works with bitwise?

Note that I use sizeof(int) because the code should be able to account for 4 or 8 byte int.

Thanks for help in advance!

int setHexDigit(char* digitPairPtr, int digitPos, char hexDigit)
{
    int return_value = 0;
    if( (hexDigit>='0' && hexDigit<='9') || (hexDigit>='A' && hexDigit <='F'))
    {
        if(digitPos==0)
        {   
            hexDigit = ((hexDigit<='9' && hexDigit>='0') ? (hexDigit-'0') : ( (hexDigit>='A' && hexDigit<='F') ? (hexDigit-('A'-10)) : (-1))); //THIS LINE IS NOT IMPORTANT 
            *digitPairPtr = ((unsigned)*digitPairPtr<<((sizeof(int))*8-4))>>((sizeof(int))*8-4); //Drop left digit.
            hexDigit = (hexDigit << 4);
            *digitPairPtr = *digitPairPtr | hexDigit;
            return_value=1;
        }
        else
        {
            //For later
        }
    }
    return return_value;
}

int main()
{
    char c = 0x0A;
    setHexDigit(&c,0,'F');
    printf("\n%X", c);
    return 0;
}

  • 2
    When dealing with bits, you should almost always use the `uintN_t` types from `stdint.h` – hyde May 30 '22 at 13:02
  • 1
    Unless you want to intentionally fill the upper bits with sign bits, your left-shift-right-shift-thingy could be replaced by a simple bitwise AND. As it seems this is what you DON'T want. You could just use `*digitPairPtr &= 0x0F;` – Gerhardh May 30 '22 at 13:14
  • @hyde unfortunately I can't make that choice, it's a uni homework. On top of that, this is programmed inside of linux' terminal and compiled on a remote server. – Basel Massarweh May 30 '22 at 13:16
  • @Gerhardh Yeah I noticed that too late, thanks for feedback! – Basel Massarweh May 30 '22 at 13:48
  • @Mitch Wheat - Although right-shifting is used in the code, the core ask in this post is not about right shifting, therefore the link you cited as rational for duplicate does not apply here. Rather question has to do with explicitly placing a hexadecimal value in a specific position within a hexadecimal number. Please reconsider your decision to close, and reopen. – ryyker May 30 '22 at 13:58

1 Answers1

3

I think the problem is in the printf statement. If you are using a compiler where char is signed, passing c to printf will sign extend it from 0xFA to 0xFFFFFFFA. Try using unsigned char instead.

Lindydancer
  • 25,428
  • 4
  • 49
  • 68