It's telling you how many bits are used for each side of the decimal point.
Take a simple example. 2 bytes, 16 bits.
That can easily be U8.8. That is, the top byte is the "integer" part, and the low byte in the "fraction" part.
So, let's make this a bit easier as an explanation.
Consider binary coded decimal. That's where you encode decimal numbers in to nibbles of bytes, each byte is 2 digits. Each nibble is a decimal digit, so 1001 0010 is "92". With two bytes, 1001 0010 0100 0111 is 9287.
So, you can see how, with no fractions, 16 bits can represent 0000 to 9999. Using you notation, that could be U16.0.
Now, you can see if we logically put the decimal point in the middle, now we can have 00.00 to 99.99, or U8.8.
The underlying bit pattern is the same, it's all a matter where you logically put the decimal point.
Now, in this example, you saw the decimal point between decimal digits.
If you're using a binary representation, then the "decimal" point is between binary digits.
So, U8.8 us 11111111. 11111111
, a U12.4 is 11111111 1111.1111
.
The S vs U tells you about the Sign bit. So, instead of U8.8 you'd have S7.8 S1111111. 11111111
.
When you have numbers that are represented similarly, then it's just binary math upon then, just like any other number (like an integer). It's when you convert the number to ascii, or combine then with other representations that you need to shift about.
For example. To add a U8.8 to a U12.4, you need to convert the U8.8 to U12.4 before performing your math.
So, 11111111. 11111111
would just need to be shifted right 4 places to become 00001111 1111.1111
. Then you can work on the two 12.4 numbers like normal. You'll notice that you lose precision of the 8.8 number during the conversion. This is known as "tough luck". You could also elevate both numbers to a higher representation, there's all sorts of options.