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?
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
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);
}
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);
User contributions licensed under CC BY-SA 3.0