Hello knee266,
You basically don't convert HEX to another data type. HEX is just a way to represent the data. Here a quick example:
uint8_t var1 = 65; // Small int
uint8_t var2 = 0x41 // Small int
Serial.println(var1 + var2, DEC); //This should output 130
Serial.println(var1 + var2, HEX); //This should output 82 (or 0x82)
You just need to take care when you're manipulating variable of different sizes, for example, if you try to do the operation:
uint8_t varX = (0xF1 + 0x80) // 241 + 128
The result will be 0x71 (or 113 DEC) and not 369 because the variable size is only 8 bits and it'll overflow.
Now if you change the variable size:
uint16_t varY = (0xF1 + 0x80) // 241 + 128
The result will be 0x171 (or 369 in DEC)
When reading data some sensors, you normally will ready byte by byte, so it's very common to "join" 2 uint8_t values to form a uint16_t value. For example:
uint8_t varA = 0x01; //1 Dec
uint8_t varB = 0x71; //113 Dec
uint16_t myVar = 0;
myVar = varA; //1 Dec
myVar <<= 8; //Left shit 8 bits, so from 1 Dec it's not 256 Dec. From 0x01 to 0x100;
myVar = myVar | varB; //OR operation, basically 0x100 merged with 0x71, which will result in 0x171
Serial.println(myVar,DEC);
Serial.println(myVar,HEX);
The above is just a very simple example, that can even be reduced to a few operations, but should give an ideal. At the end, the datasheet for the Sensor/Device where you're reading the data from will tell if the reading is an 8 bit, 10, 16 bit, etc... also will tell if the data is MSB or LSB.
I personally like to user uint8_t and uint16_t instead of "small unsigned int" and "unsigned int" as it's easier to see the variable size.
You might wanna have a look on this link, which will explain all bit manipulations: Arduino Playground - BitMath
Cheers