Given a hex value of 0x80 (supplied as a uint16_t) in c++ how would I extract the digits into an int variable. I don't want to convert the hex to int, rather I want to extract the digits as an int, so for example, for 0x80 i want an int of 80, not 128, or for 0x55 I want 55 not 85, etc.
uint16_t hex = 0x80;
uint8_t val = ???; // Needs to be 80
Numbers with hex-only digits will never happen. I.e. input will only consist of decimal digits.
E.g. 0x08, 0x09, 0x10, 0x11, 0x12, etc.
Since you say that the hex number never contains 'a', 'b', etc. this code should do the trick:
#include <iostream>
int main() {
uint16_t in = 0x4321;
int t = (1000 * ((in & 0xf000) / (16*16*16))) +
(100 * ((in & 0xf00) / (16*16))) +
(10 * ((in & 0xf0) / 16)) +
(1 * ((in & 0xf) / 1));
std::cout << t << std::endl;
return 0;
}
output
4321
Explanation
A 16 bit hex number in = 0xWZYX is calculated as
in = W*16^3 + Z*16^2 + Y*16^1 + X*16^0 (or just W*16^3 + Z*16^2 + Y*16^1 + X)
When doing
in & 0xf000 you get 0xW000
when doing
0xW000 / 16^3 you get 0x000W or just W
When doing
1000 * W you get W000 decimal
The pattern is then repeated for each digit.
An alternative implementation using shift
#include <iostream>
int main() {
uint16_t in = 0x9321;
int t = (1000 * ((in & 0xf000) >> 12)) +
(100 * ((in & 0xf00) >> 8)) +
(10 * ((in & 0xf0) >> 4)) +
(1 * ((in & 0xf) >> 0));
std::cout << t << std::endl;
return 0;
}
For a 16 bit unsigned integer it can be okay to write out the four lines. However, if you wanted a similar function for a larger unsigned int, it may be better to do a loop to keep the code more compact and maintainable.
64 bit solution using a loop
#include <iostream>
int64_t directHexToDec(uint64_t in)
{
int64_t res = 0;
uint64_t mask = 0xf;
uint64_t sh = 0;
uint64_t mul = 1;
for (int i=0; i<16; ++i)
{
res += mul * ((in & mask) >> sh);
mul *= 10;
mask <<= 4;
sh += 4;
}
return res;
}
int main() {
uint64_t in = 0x987654321;
int64_t t = directHexToDec(in);
std::cout << t << std::endl;
return 0;
}
output
987654321