I created a structure to represent a fixed-point positive number. I want the numbers in both sides of the decimal point to consist 2 bytes.
typedef struct Fixed_t {
unsigned short floor; //left side of the decimal point
unsigned short fraction; //right side of the decimal point
} Fixed;
Now I want to add two fixed point numbers, Fixed x and Fixed y. To do so I treat them like integers and add.
(Fixed) ( (int)x + (int)y );
But as my visual studio 2010 compiler says, I cannot convert between Fixed and int.
What’s the right way to do this?
EDIT: I’m not committed to the {short floor, short fraction} implementation of Fixed.
Some magic:
Key points:
shortbeing 16-bit andintbeing 32-bit.FloorandFraction(capitalized to avoid clashing withfloor()function) access the two parts in an endian-independent way, asfoo.Floorandfoo.Fraction.Edit: At OP’s request, an explanation of the macros:
Unions are a way of declaring an object consisting of several different overlapping types. Here we have
uint16_t w[2];overlappinguint32_t d;, making it possible to access the value as 2 16-bit units or 1 32-bit unit.(Fixed){1}is a compound literal, and could be written more verbosely as(Fixed){{1,0}}. Its first element (uint16_t w[2];) gets initialized with{1,0}. The expression((Fixed){1}).dthen evaluates to the 32-bit integer whose first 16-bit half is 1 and whose second 16-bit half is 0. On a little-endian system, this value is 1, so((Fixed){1}).d==1evaluates to 1 (true) and((Fixed){1}).d!=1evaluates to 0 (false). On a big-endian system, it’ll be the other way around.Thus, on a little-endian system,
Floorisw[1]andFractionisw[0]. On a big-endian system,Floorisw[0]andFractionisw[1]. Either way, you end up storing/accessing the correct half of the 32-bit value for the endian-ness of your platform.In theory, a hypothetical system could use a completely different representation for 16-bit and 32-bit values (for instance interleaving the bits of the two halves), breaking these macros. In practice, that’s not going to happen. 🙂