Considering only 4 bits at a time when converting decimal to hex

-2

I have a C function to convert decimal to a hex string hexConversion:

int hexConversion(int num){
    char hex_buffer[9];
    unsigned int mask = 4026531840;
    for(int i = 0; i < 9; i++){
        int temp = mask & num;
        if(temp < 10){
            hex_buffer[i] = temp + '0';
        }
        else if(temp == 10){
            hex_buffer[i] = 'A';
        }
        else if(temp == 11){
            hex_buffer[i] = 'B';
        }
        else if(temp == 12){
            hex_buffer[i] = 'C';
        }
        else if(temp == 13){
            hex_buffer[i] = 'D';
        }
        else if(temp == 14){
            hex_buffer[i] = 'E';
        }
        else if(temp == 15){
            hex_buffer[i] = 'F';
        }
        mask >>= 4;
    }

    hex_buffer[8] = '\0';

    for(int i = 0; i < sizeof(hex_buffer); i++){
        printf("%c", hex_buffer[i]);
    }
}

with driver code:

int main(){
    hexConversion(2);
    hexConversion(255);
    hexConversion(-1);
    hexConversion(INT_MAX);
    hexConversion(INT_MIN);
    hexConversion(0xDEADBEEF);
}

My output is: 00000002 0000000F 0000000F 0000000F 00000000 0000000F

Every output has the last value correct, but all the values before the last one are not evaluating. I believe this is because my temp = mask & num is not producing a value that is not 0-15. My question is, how do I consider only 4 bits at a time so that all of my temp values will be within this range?

c
function
binary
hex
output
asked on Stack Overflow Mar 5, 2019 by d827

3 Answers

2

It depends on your system but if you want to extract nybbles out of your value you can eventually apply 0xF (masks >> (4 * n)) over your values For instance if i got a binary data looking like this 0x4602 = 0100 0110 0000 0010 and i need to extract only the 1rst part of this one i could use a 0xF000 = 1111 0000 0000 0000 with a & mask over this 0x4602 to get the first part of this value This would give us 0xF000 = 1111 0000 0000 0000 &0x4602 = 0100 0110 0000 0010 result would be 0x4000 = 0100 0000 0000 0000

to get the nth part of this value you could drift the (0xF000) with the >> 4 n times

answered on Stack Overflow Mar 5, 2019 by fratardi
2

The first remark looking at your code without considering the problem is why do you manage well the case 0..9 but you separate the case A and B ... and F rather than to do the same as you do for the digit ?

so

int hexConversion(int num){
  char hex_buffer[9];
  unsigned int mask = 4026531840;
  for(int i = 0; i < 9; i++){
    int temp = mask & num;
    if(temp < 10){
      hex_buffer[i] = temp + '0';
    }
    else if (temp < 16) {
      hex_buffer[i] = temp - 10 + 'A';
    }
    else {
      hex_buffer[i] = '?';
    }
    mask >>= 4;
  }

  hex_buffer[8] = '\0';

  for(int i = 0; i < sizeof(hex_buffer); i++){
    printf("%c", hex_buffer[i]);
  }
}

I added the test if (temp < 16) normally useless if the code is the right one, but the result is :

Compilation and execution :

pi@raspberrypi:/tmp $ gcc -g -pedantic -Wextra h.c
h.c: In function ‘hexConversion’:
h.c:23:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for(int i = 0; i < sizeof(hex_buffer); i++){
                      ^
pi@raspberrypi:/tmp $ ./a.out
00000002000000?F0??????F???????F000000000??????F

so in your solution you do not write on some indexes, because of the error in your code

One way to do is :

void hexConversion(int num){
  char hex_buffer[9];

  for(size_t i = 0; i < sizeof(hex_buffer) -1; i++){
    int temp = (num >> (28-4*i)) & 0xf;
    if(temp < 10){
      hex_buffer[i] = temp + '0';
    }
    else {
      hex_buffer[i] = temp - 10 + 'A';
    }
  }
  hex_buffer[8] = 0;
  puts(hex_buffer);
}

Compilation and execution :

pi@raspberrypi:/tmp $ gcc -g -pedantic -Wextra h.c
pi@raspberrypi:/tmp $ ./a.out
00000002
000000FF
FFFFFFFF
7FFFFFFF
80000000
DEADBEEF

Note your code suppose int on 32b, to be independent on the size (but supposing a char is on 8bits) :

void hexConversion(int num){
  char hex_buffer[sizeof(int)*2 + 1];

  for(size_t i = 0; i < sizeof(int)*2; i++){
    int temp = (num >> (sizeof(int)*8-4-4*i)) & 0xf;

    if(temp < 10){
      hex_buffer[i] = temp + '0';
    }
    else {
      hex_buffer[i] = temp - 10 + 'A';
    }
  }
  hex_buffer[sizeof(int)*2] = 0;
  puts(hex_buffer);
}
answered on Stack Overflow Mar 5, 2019 by bruno • edited Mar 5, 2019 by bruno
1

You need to run loop from 0-7 and also move the number after applying the mask to lower nibble.

for(int i = 0; i < 8; i++){
    int temp = (mask & num) >> (28 -4*i);
answered on Stack Overflow Mar 5, 2019 by Ajay P

User contributions licensed under CC BY-SA 3.0