I'm trying to convert a hexadecimal INT to a char so I could convert it into a binary to count the number of ones in it. Here's my function to convert it into char:
#include <stdio.h>
#include <stdlib.h>
#define shift(a) a=a<<5
#define parity_even(a) a = a+0x11
#define add_msb(a) a = a + 8000
void count_ones(int hex){
char *s = malloc(2);
sprintf(s, "0x%x", hex);
free(s);
printf("%x", s);
};
int main() {
int a = 0x01B9;
shift(a);
parity_even(a);
count_ones(a);
return 0;
}
Every time I run this, i always get different outputs but the first three hex number are always the same. Example of outputs:
8c0ba2a0
fc3b92a0
4500a2a0
d27e82a0
c15d62a0
What exactly is happening here? I allocated 2 bytes for the char since my hex int is 2 bytes.
It's too long to write a comment so here goes:
intare stored as a group of value, padding (possible empty) and sign bits, so is there no such thing as a hexadecimalINTbut you can represent (print) a given number in the hexadecimal format.That would be lossy conversion as an
intmight have 4 bytes of data that you are trying to cram into a 1 byte.charspecifically may be signed or unsigned. You probably meanstring(generic term) orchar [](standard way to represent a string in C).That's the real issue you are trying to solve and this is a duplicate of:
How to count the number of set bits in a 32-bit integer?
count number of ones in a given integer using only << >> + | & ^ ~ ! =
To address the question you ask:
Need to allocate more than 2 bytes. Specifically
ceil(log16(hex)) + 2 (for 0x) + 1 (for trailing '\0').One way to get the size is to just ask
snprintf(s, 0, ...)then allocate a suitable array viamalloc(see first implementation below) or use stack allocated variable length array (VLA).You can use
INT_MAXinstead ofhexto get an upper bound.log16(INT_MAX) <= CHAR_BIT * sizeof(int) / 4and the latter is a compile time constant. This means you can allocate your string on stack (see 2nd implementation below).It's undefined behavior to use a variable after it's deallocated. Move
free()to after the last use.Here is one of the dynamic versions mentioned above:
Note, I initialized
stoNULLwhich would cause the first call tosnprintf()to return an undefined value on SUSv2 (legacy). It's well defined on c99 and later. The output is:And the compile-time version using a fixed upper bound:
and the output is: