在C / C ++中签名扩展数字的最佳方法是什么

问题描述 投票:2回答:2

我有10位有符号值。它实际上是一个10位颜色值,我想转换为int

10位将被解释为更大的int内的有符号值,其他位为零。

我可以想到3种方法,如下所示:

#include <stdio.h>

void p(int v)
{
    printf("\t%d", v);
}

int main()
{
    for (int i = -2; i < 3; ++i)
    {
        unsigned int u = i & 0x3ff;

        int v;

        // method 1: test the bit
        v = u;
        if (u & 0x200) v = v ^ -0x400;
        p(v);

        // method 2: shift
        v = u<<(sizeof(int)*8-10);
        v >>= (sizeof(int)*8-10);
        p(v);

        // method 3: use sign extend
        v = (signed char)(u >> 2);
        v <<= 2;
        v |= u;
        p(v);


        printf("\n");

    }

    return 0;
}

有没有更好的办法?经常有这个有点麻烦的问题。

感谢您的任何意见。

更新

再添加两个方法。 @ cruz-jean建议的第一个是位字段,第二个是在编译位域后由gcc建议的。

      // method 4: bit fields
        struct { int v:10; } f;
        f.v = u;
        v = f.v;

        // method 5: sign extend short
        v = (signed short)(u << 6);
        v >>= 6;

出于兴趣,似乎MSVC将#4编译为#2,gcc将#4编译为#5。

方法5看起来不错。

c++ c bit
2个回答
2
投票

您可以声明一个10位带符号的位域辅助类型,并将该值作为int访问:

struct signed_10_bit
{
    int val : 10;
};

int some_10_bit_num = 0x3ff;
int extended = signed_10_bit{ some_10_bit_num }.val;

0
投票

另一个尝试:

v = u | (0 - (u&0x200));

适合转移缓慢的cpu。

© www.soinside.com 2019 - 2024. All rights reserved.