-1

好的,我已经阅读了很多关于符号扩展的内容,但我对 C 以及所有“位运算符”都是全新的,所以我仍然无法弄清楚我应该如何在 C 中实际实现它。

我有一个调用的函数getField,它应该返回一个较大位中的一大块位的值。它需要三个整数:valuehilo加上一个 bool:isSigned作为参数。例如,此调用应返回 2:

return getField(9, 5, 2, 0);

我的功能有效,除非数字签名。在阅读了符号扩展后,我认为我的理解是,如果isSigned是,true那么我需要在位中添加一个,因此在上面的示例中,解决方案 ( 0010) 将变为 ( 111...0010)。这是我处理使数字签名的代码(result等于函数将返回的内容,如果isSignedfalse):

if (isSigned) {
    return (~result) + 1;
}

如果我应该返回 2s 补码有符号整数,这将起作用,但遗憾的是这不是我应该做的。任何帮助表示赞赏。

编辑:这是该方法的完整代码...

int getField (int value, int hi, int lo, bool isSigned) {
int mask;

//Make Sure 'hi' is the high value
if (hi < lo) {
    int temp = hi;
    hi = lo;
    lo = temp;
}
int numberOfBits = (hi - lo) + 1;

mask = ((1 << numberOfBits) - 1) << lo;
int result = value & mask;

//Get rid of LSB if value is zero
result = result >> lo;

if (isSigned) { //Sign Extension instead of Twos Complement
    return (~0) << numberOfBits | result;
}
else {
    return result;
}

}

(注:我确实看到过类似的帖子,我读了它,但我仍然很困惑,所以我决定写一个不同的。对不起,如果这违反了规则。)

4

2 回答 2

-1

您可能应该使用机器自己的符号扩展功能,您可以通过一些数据类型的转换来完成

int getField(unsigned int data, int from, int to, int s)
{
    // assuming 32 bit ints, add error check, ymmw
    data <<= 32-from;
    if (s)
       return ((int)data) >> (32-(from-to));
    return (data >> (32-(from-to)));
}
于 2017-09-09T23:39:57.820 回答
-1

所以我不太明白你的函数在做什么,但你可以通过以下按位运算得到答案:

int ones = ~0;                  // should give 1111...111111
int shifted_ones = (ones << 4); // should give 1111...110000
result = shifted_ones | result; // should give 1111...110010

// or in one line
result = ((~0) <<4) | result;

我不确定这是否能回答你的问题。显然,班次的数量需要是一个变量。

编辑

好的,所以第一个答案在数学上正确时确实会发出警告(至少对于 GCC)。编译器检测到从数字末尾移开的位 (1)。可能不是真正的生产解决方案,但有点有趣。原始解决方案没有该警告。

int ones = 0b1111; // make the number of ones the same size as the answer.
result = ~ones | result;
于 2017-09-09T23:21:07.297 回答