如何处理带有两个unsigned short的结构,就好像它是unsigned int一样?(在C中)

sna*_*ile 2 c struct fixed-point

我创建了一个表示定点正数的结构.我希望小数点两边的数字包含2个字节.

typedef struct Fixed_t {
    unsigned short floor; //left side of the decimal point
    unsigned short fraction; //right side of the decimal point
} Fixed;
Run Code Online (Sandbox Code Playgroud)

现在我想添加两个定点数,Fixed xFixed y.为此,我将它们视为整数并添加.

(Fixed) ( (int)x + (int)y );
Run Code Online (Sandbox Code Playgroud)

但正如我的visual studio 2010编译器所说,我无法在Fixed和之间进行转换int.

这样做的正确方法是什么?

编辑:我不承诺{short floor, short fraction}执行Fixed.

Ste*_*sop 6

你可以尝试一个令人讨厌的黑客,但这里有一个问题与endian-ness.无论你做什么转换,编译器应该如何知道你想floor成为结果中最重要的部分,fraction而不那么重要的部分?任何依赖于重新解释内存的解决方案都适用于一个字节序而不是另一个字节序.

你应该:

(1)明确定义转换.假设short是16位:

unsigned int val = (x.floor << 16) + x.fraction;
Run Code Online (Sandbox Code Playgroud)

(2)改变Fixed使其有一个int成员而不是两个短裤,然后在需要时分解,而不是在需要时作曲.

如果你想要加快,那么(2)就是要做的事情.如果你有64位类型,那么你也可以在不分解的情况下进行乘法:unsigned int result = (((uint64_t)x) * y) >> 16.

顺便说一句,令人讨厌的黑客就是:

unsigned int val;
assert(sizeof(Fixed) == sizeof(unsigned int))              // could be a static test
assert(2 * sizeof(unsigned short) == sizeof(unsigned int)) // could be a static test
memcpy(&val, &x, sizeof(unsigned int));
Run Code Online (Sandbox Code Playgroud)

这将适用于大端系统,其中Fixed没有填充(并且整数类型没有填充位).在一个小端系统上,你需要Fixed的成员处于另一个顺序,这就是为什么它很讨厌.有时候通过memcpy进行操作是正确的(在这种情况下,它是一个"技巧"而不是"讨厌的黑客").这不是那个时代之一.


Cas*_*Cow 5

如果必须,您可以使用联合但请注意字节序问题.您可能会发现算术不起作用,当然也不可移植.

typedef struct Fixed_t {
   union { 
        struct { unsigned short floor; unsigned short fraction }; 
        unsigned int whole;
         };
} Fixed;
Run Code Online (Sandbox Code Playgroud)

这更有可能(我认为)工作大端(Windows/Intel不是).