Is it possible to sign / zero expansion can be done only by casting?

I have a home problem (MIPS simulator), which requires, for example, that we take a 16-bit "immediate" value and the sign and / or zero expand it to 32 bits. I got the impression that this can be easily done simply by casting, for example:

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

and

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

But then I stumbled upon a piece of code online where someone who worked on the same project wrote their own functions sign_extension8to16, "sign_extension16to32", and these functions worked by shifting the 8-bit number to the right by 7 and evaluating, or not the most significant bit (now in one place) was 1, and then it returned a number that was cast for (uint16_t), which masks the upper 8 bits to 0 or 1, respectively.

Is such an approach really necessary? I thought that was true. The reason I ask is that I have very strange error messages and I can’t pinpoint the problem, so I think the reason may be that I am incorrectly null and signing the extension ...

+4
source share
1 answer

IMO: your method will work.

Simplify the problem.

Promotion uint16_tup uint32_tand promotion int16_tis int32_teasy to understand and achieve the expected results. Zero fills in unsigned integers and the sign extends the signed integers.

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_t int int32_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
0

Source: https://habr.com/ru/post/1537241/


All Articles