To get the four highest bits of a 16-bit value, you shift it right by 12 bits. This will cause the top bits to be zeroes so no masking needed. For the others you (optionally) shift right and mask out the four lowest bits with the bitwise and operator &
.
To make the value gotten from the above steps to a hexadecimal digit in character form, then for values lower than 10 add '0'
(if you're on a computer with with ASCII encoding), and for values at 10 or higher then subtract ten and add e.g. 'A'
.
There are simpler ways of course, like using e.g. sprintf
to convert the number directly. Just get the 16-bit value into an unsigned short, and do e.g.
printf("%04hx\n", value_as_unsigned_short);
Let say you have the binary number 0001001010101011
. This is, in hexadecimal presentation 12ab
.
If the binary number is in an integer variable, lets say one named value
, we can get the hexadecimal representation as a string like this:
// First get each digit, one by one
digit0 = value & 0x0f; // Mask out everything but the lowest four bits
digit1 = (value >> 4) 0x0f;
digit2 = (value >> 8) 0x0f;
digit3 = value >> 12;
// Now make a string out of those four digits
char str[5]; // Four digits plus the string terminator
// If a digit is less than 10, then add '0' to get an ASCII character
// Else decrease by ten (to get a number between 0 and 5) and add 'A'
str[0] = digit3 < 10 ? digit3 + '0' : (digit3 - 10) + 'A';
str[1] = digit2 < 10 ? digit2 + '0' : (digit2 - 10) + 'A';
str[2] = digit1 < 10 ? digit1 + '0' : (digit1 - 10) + 'A';
str[3] = digit0 < 10 ? digit0 + '0' : (digit0 - 10) + 'A';
str[4] = '\0'; // Terminate string
printf("value is in hex %s\n", str);
The above code will print
value is in hex 12AB
However that is a lot of code, though it can be reused for all numbers. If you already have your 16-bit number in the integer variable value
, then it's much easier to just write
printf("value is in hex %04hX\n", value);
The result of both code snippets above will be just the same.
Regarding your edit:
std::ostringstream oss;
for (size_t i = 0; i < 8; ++i, aBinaryIPAddress += 2)
{
// Take the first byte, and shift it left 8 bits, making it
// the high byte of a 16-bit number. Then or (or add) the next
// byte at the low 8 bits in the 16-bit number.
// The casting is needed because we're working with 16-bit numbers
// and not bytes.
uint16_t value = static_cast<uint16_t>(*aBinaryIPAddress << 8) |
static_cast<uint16_t>(*(aBinaryIPAddress + 1));
oss << std::setfill('0') << std::setw(4) << std::hex << value;
if (i < 7)
oss << ':';
}
std::cout << "Address is " << oss.str() << '\n';