可以通过施法来完成签名/零扩展吗?

时间:2014-04-19 22:40:18

标签: c casting integer mips bit

我有一个功课问题(MIPS模拟器),例如我们需要采用16位“立即”值并对其进行符号和/或零扩展至32位。我的印象是,这可以通过强制转换轻松完成,例如:

uint32_t imm = (uint16_t)IMM_FIELD(instruction); # Zero extend to 32-bits

uint32_t imm = (int16_t)IMM_FIELD(instruction); # Sign extend to 32-bits

但后来我遇到了一段代码在线,在同一个项目上工作的人编写了自己的“sign_extension8to16”,“sign_extension16to32”函数,这些函数通过将8位数字右移7来评估是否有效或者不是最重要的位(现在在一个位置)是1,然后返回一个被转换为(uint16_t)的数字,相应地将高8位屏蔽为0或1。

这种方法真的有必要吗?我认为当然铸造已经解决了这个问题。我问的原因是我有非常奇怪的错误信息,我无法查明问题,所以我认为原因可能是我错误地归零并签署了扩展......

1 个答案:

答案 0 :(得分:0)

IMO:你的方法会奏效。

让我们简化问题。

uint16_t推广到uint32_t以及将int16_t推广到int32_t很容易理解,并且会出现预期的结果。零填充无符号整数和符号扩展有符号整数。

int main() {
  uint16_t u = 65535;
  int16_t i = -1;
  printf("%" PRIu32 "\n", (uint32_t) u);
  printf("%" PRId32 "\n", (int32_t) i);
  return 0;
}

65535
-1

int16_t推广到uint32_t会先将int16_t推广到int32_t,然后推广到uint32_t。 (实际上我认为首先推广到int16_tintint32_t然后再推广到uint32_t如果sizeof int <= sizeof int32_t。)因此代码会先进行符号扩展使结果成为无符号整数。

uint16_t升级为int32_t会将uint16_t直接宣传为int32_t。一个简单的零扩展。

注意:我可以使用&#34;推广&#34;,当我应该说&#34;转换&#34;。

int main() {
  uint16_t u = 65535;
  int16_t i = -1;
  printf("%" PRIu32 "\n", (uint32_t) i);
  printf("%" PRId32 "\n", (int32_t) u);
  return 0;
}

4294967295
65535