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

C++ 在C/C+;中签名和扩展数字的最佳方式是什么+;,c++,c,bit,C++,C,Bit,我有一个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;

我有一个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;
}
#包括
无效p(内部v)
{
printf(“\t%d”,v);
}
int main()
{
对于(int i=-2;i<3;++i)
{
无符号整数u=i&0x3ff;
INTV;
//方法1:测试钻头
v=u;
如果(u&0x200)v=v^-0x400;
p(v);
//方法2:轮班
v=u=(整型尺寸)*8-10);
p(v);
//方法3:使用符号扩展
v=(有符号字符)(u>>2);

v您可以声明一个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;
另一个尝试:

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

对移位很慢的CPU有好处。< /P>你是指代码> C <代码>还是<代码> C++ >代码>?我怀疑这个问题应该有两个标签。如果你有一个10位的符号值,你想把它转换成int,你只需要投,就没有别的。符号扩展只意味着增加比特数,同时保留值和符号。所以,如果这个值是PAR。结构位域的t,您可以通过简单地将其声明为有符号位域来简化它-C/C++将自动执行所有转换。@Fredrik我的意思是,10位将被解释为有符号位,而不是它填充整个单词。如果不清楚,很抱歉。@Fredrarson这是真的,我的测试程序不会编译为C,但这个想法对b是有效的我把它改为:struct{intv:10;}f;f.v=u;v=f.v;MSVC生成的移位与方法2相同,但gcc从10位移到16位,符号在那里扩展。@jkjyuio这是一件好事。写下你的意思,并相信编译器能有效地完成它。现在优化器非常聪明。谢谢。我添加了你的建议。位域可能就是这样。我喜欢它!Method#1的动机是慢移位,但我不喜欢这个测试。这更好。一些旧CPU一次只能移位1,需要移位循环,所以这是最好的方法。不确定这些CPU上会生成什么位字段。

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