将unsigned int转换为signed int C.

dar*_*sky 19 c int unsigned-integer

我试图65529从一个转换unsigned int为签名int.我尝试做这样的演员:

unsigned int x = 65529;
int y = (int) x;
Run Code Online (Sandbox Code Playgroud)

但是y当它应该返回-7时仍然返回65529.这是为什么?

Mys*_*ial 33

看起来你期待intunsigned int成为一个16位整数.显然情况并非如此.最有可能的是,它是一个32位整数 - 足够大,可以避免你所期望的环绕.

请注意,没有完全符合C的方法来执行此操作,因为在符号/无符号值之间进行超出范围的值是实现定义的.但在大多数情况下,这仍然有效:

unsigned int x = 65529;
int y = (short) x;      //  If short is a 16-bit integer.
Run Code Online (Sandbox Code Playgroud)

或者:

unsigned int x = 65529;
int y = (int16_t) x;    //  This is defined in <stdint.h>
Run Code Online (Sandbox Code Playgroud)

  • 有一种大多数符合C标准的方法:`y = x <32767?(int)x:(x> 32768? - (int)-x:-32768);`(唯一的问题是`-32768`不一定代表一个有符号的int,所以你必须决定如何对待它). (3认同)
  • 如果你可以保证`short`是一个16位整数,则是,int`y =(short)x;`将起作用.或者,如果编译器具有`<stdint.h>`标头,则可以使用`int16_t`. (2认同)

Sub*_*ent 6

我知道这是一个老问题,但它是一个很好的问题,那么这个怎么样?

unsigned short int x = 65529U;
short int y = *(short int*)&x;

printf("%d\n", y);
Run Code Online (Sandbox Code Playgroud)

  • 你能在这里解释一下吗?谢谢你。 (2认同)

Joe*_*ish 5

@Mysticial 明白了。Short 通常是 16 位,将说明答案:

int main()  
{
    unsigned int x = 65529;
    int y = (int) x;
    printf("%d\n", y);

    unsigned short z = 65529;
    short zz = (short)z;
    printf("%d\n", zz);
}

65529
-7
Press any key to continue . . .
Run Code Online (Sandbox Code Playgroud)


更详细一点。这都是关于带符号的数字如何存储在内存中的。搜索二进制补码表示法以获取更多详细信息,但这里是基础知识。

让我们看一下十进制的 65529。它可以用十六进制表示FFF9h。我们还可以用二进制表示为:

11111111 11111001

当我们声明 时short zz = 65529;,编译器将 65529 解释为有符号值。在二进制补码表示法中,最高位表示有符号值是正还是负。在这种情况下,您可以看到最高位是 a 1,因此它被视为负数。这就是为什么它打印出来-7

对于unsigned short,我们不关心符号,因为它是unsigned。因此,当我们使用 打印出来时%d,我们使用了所有 16 位,因此它被解释为65529