显式转换问题,C

发布于 2024-12-19 14:54:26 字数 631 浏览 3 评论 0原文

我在 C 中有这个 case 语句:

case GOTO: {
    int o1 = (int)P[pc+1];
    unsigned int o2 = (unsigned)P[pc+2];
    int offset =(o1<<8) | o2;
    pc = pc + (int)offset;
    break;
}

现在关于代码: P[pc+x] 将给出一个 1 字节整数。 基本上在最后,我想将 pc 设置为有符号的 4 字节 int。然而它并没有这样做。它所做的就是获取 1 字节,将其移位,然后获取第二个字节,然后按位或,然后简单地将其相加。它没有考虑 o1 的符号。因此,如果 P[pc+1] = FFP[pc+2] = E1,则发生的情况是 offset = 0000FFE1 。然而,我想要的是 offset = FFFFFFE1。基本上,前 2 字节应采用 P[pc+1] 的符号。但这并没有发生。我做错了什么?

I have this case statement in C:

case GOTO: {
    int o1 = (int)P[pc+1];
    unsigned int o2 = (unsigned)P[pc+2];
    int offset =(o1<<8) | o2;
    pc = pc + (int)offset;
    break;
}

Now about the code:
P[pc+x] will give a 1 byte integer.
And basically at the end of this, I want to set pc to a signed 4 byte int. It's not doing that however. What it is doing is taking the 1 byte, shifting it over, then taking the second byte and then bitwise or, and simply adding it. It is not taking into account the sign of o1. So, if P[pc+1] = FF, and P[pc+2] = E1, what is happening is offset = 0000FFE1. What I want however, is offset = FFFFFFE1. Basically, the first 2 bytes should take the sign of P[pc+1]. But this is not happening. What am I doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

放赐 2024-12-26 14:54:26

看看这是否对您有意义:
#包括

int main(void) {
  short pc1= 0xFF;
  short pc2= 0xE1;
  int pc = 0;

  unsigned int highbits = 0xFFFFFFFF;

  // Check for sign bit, if true OR with highbits
  // to set all remaining bits to high
  int o1 = pc1 & 0xF0 ? pc1 | highbits : pc1;
  int offset = (int)( (o1<<8) | pc2 );
  pc = pc + (int)offset;
  printf("\npc1=%x pc2=%x pc=%x", pc1, pc2, pc);
  printf("\n");

  return 0;
}

输出:

pc1=ff pc2=e1 pc=ffffffe1

Check this out if this makes sense for you:
#include

int main(void) {
  short pc1= 0xFF;
  short pc2= 0xE1;
  int pc = 0;

  unsigned int highbits = 0xFFFFFFFF;

  // Check for sign bit, if true OR with highbits
  // to set all remaining bits to high
  int o1 = pc1 & 0xF0 ? pc1 | highbits : pc1;
  int offset = (int)( (o1<<8) | pc2 );
  pc = pc + (int)offset;
  printf("\npc1=%x pc2=%x pc=%x", pc1, pc2, pc);
  printf("\n");

  return 0;
}

OUTPUT:

pc1=ff pc2=e1 pc=ffffffe1
撩动你心 2024-12-26 14:54:26

我没有看到 P 的声明,但是当你说它是一个字节数组时,我假设它的特定类型是 unsigned char。

如果它被签名,则强制转换将按照您想要的方式运行,因为,例如,-1 char 将变为 -1 int,符号位会移动,其余位将根据需要反转。但是,当您从 unsigned char 转换为signed int 时,结果将始终是正 int。

因此,要解决这个问题,一种方法是在取消引用指针/数组之前对其进行强制转换,它将给出所需的结果:

int o1 = (int)(((char *)P)[pc+1]);

另一件事:位移位不适用于有符号值,因为它只会移走符号位。它在你的例子中是有效的,因为你有 0xFF,但如果你有 0x80,它将是 0x80000000 作为 int,并在移位后变为 0x00000000。

因此,不要进行 8 位移位,而是进行乘法:

int offset =(int)( (o1 * 256) + o2 );

I didn't see the declaration of P, but when you say it's a byte array, I'm assuming the specific type it has is unsigned char.

If it were signed, the cast would behave the way you wanted, because, for instance, a -1 char would become -1 int, the sign bit shifted and the remaining bits inverted as required. But when you cast from unsigned char to signed int the result will always be a positive int.

So, to solve the problem, one way is to cast the pointer/array before dereferencing it, and it'll give the desired result:

int o1 = (int)(((char *)P)[pc+1]);

One other thing: a bit shift won't work well with signed values, because it'll simply shift away the sign bit. It would work in your example, because you have 0xFF, but if you had 0x80 it'd be 0x80000000 as int, and become 0x00000000 after the shift.

So, instead of an 8-bit shift, do a multiplication:

int offset =(int)( (o1 * 256) + o2 );
ぃ双果 2024-12-26 14:54:26

您应该检查编译器如何在 C 中执行无符号转换,反之亦然。
如果我没记错的话(抱歉,如果我错了),一旦在像 A = B 这样的操作中至少有一个 UNSIGNED 变量(其中 A 接收 B 的值),编译器就会将这两个值都作为 UNSIGNED 值处理。

这可能会扰乱你的代码。
让我以某种方式知道答案,如果我弄清楚为什么会发生这种情况,我会在这里发表评论

You should check how your compiler perform Unsigned-signed and vice versa castings in C.
If i remember right (sorry if im wrong),once you have at least one UNSIGNED variable in a operation like A = B (where A receives the value of B), the compiler will deal with both values as UNSIGNED Values.

This is probably messing with your code.
Let me know the answer one way or another,i will comment here if i figure out why this happens

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文