我有一个功课问题(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 票数:1

IMO:你的方法会奏效。

让我们简化问题。

uint16_t提升为uint32_t并将int16_tint32_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_tuint32_t将首先将int16_t提升为int32_t ,然后提升为uint32_t (实际上我认为它首先将int16_tintint32_t然后int16_t uint32_t如果sizeof int <= sizeof int32_t 。)因此代码在使结果成为无符号整数之前执行符号扩展。

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

注意:当我说“转换”时,我可以使用“提升”。

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

  ask by CptSupermrkt translate from so

未解决问题?本站智能推荐: