好的我已经阅读了很多关于签名扩展的内容,但我对C以及所有'按位运算符'都是全新的。所以我仍然无法弄清楚我应该如何在C中实现它。
我有一个名为getField
的函数,它应该在更大的位内返回一块位的值。它需要三个整数:value
,hi
和lo
以及bool:isSigned
作为参数。例如,此调用应返回2:
return getField(9, 5, 2, 0);
除了签名号码外,我的功能有效。在阅读了符号扩展后,我认为我的理解是,如果isSigned
为true
,那么我需要添加一些,所以在上面的示例中,解决方案(0010
)会成为(111...0010
)。这是我处理数字签名的代码(result
等于函数在isSigned
为false
时返回的内容):
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;
}
}
(注意:我确实看到了一个与此相似的帖子,我读了它,但我仍然感到非常困惑,所以我决定写一个不同的。抱歉,如果这违反了规则。)
答案 0 :(得分:-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;
答案 1 :(得分:-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)));
}