What exactly means U0.8, U4.8, U12.8, S0.4, S4.4, S12.4, U8.8 etc. fixed-point representation?

StackOverflow https://stackoverflow.com/questions/19571012

  •  01-07-2022
  •  | 
  •  

Question

I'm finding it hard to understand fixed-point representations. When I have unsigned type of data (C++) and I want to work with that number as if it is fixed-point, I need do do certain amount of bit manipulation which aren't clear to me.

So let's say I want that my number which is unsigned and can be max 255 (8 bit number) be represented in U4.4 or U12.8 or S13.8 or whichever notation (U - unsigned, S - signed, and it comes in question when my number is int). Basically I'm expanding (or I hope that I'm) the number, working on it, and then returning it to the previous state.

How do I do that?

Can someone share link where I can find something closely related to this subject. I was looking for three hours and all I have found are general explanations on fixed-point arithmetics, nothing very practical.

Thanks

Était-ce utile?

La solution

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top