weixin_43249053 2018-09-21 13:30 采纳率: 100%
浏览 474
已采纳

关于char类型变量以%u和赋给int输出的位扩展问题

图片说明

129的二进制为10000001
4294967169的二进制为11111111111111111111111110000001

按我了解到的位扩展方式理解。
当无符号i=4294967169 (二进制 11111111 11111111 11111111 10000001)
那么有符号的i应该为 -2147483521(二进制 1111111 11111111 11111111 10000001)
可用VS运行得出的是-127,也就是没有前面24个1得出来的。
寻求大神解释详细原因。

(顺带问一句,以%u输出,就是以无符号的int输出,所以才需要位扩展吗?)

  • 写回答

2条回答 默认 最新

  • threenewbee 2018-09-22 02:48
    关注

    你有一些最基本的概念还不清楚。
    首先,负数在计算机里是怎么表示的,这个要搞清楚,是符号位1+补码,而不是原码
    我们用最简单的4位数字表示
    -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 的二进制分别如下:
    1000 1001 1010 1011 1100 1101 1110 1111 0000 0001 0010 0011 0100 0101 0110 0111
    可以概括出如下结论:
    0的二进制是0
    负数的二进制符号位是1,其余是 取反(原码-1),比如-2,它的原代码是 010,-1就是001,取反就是110,所以最后就是1110
    因此,-2147483521的二进制表示应该是10000000000000000000000001111111,而不是1111111111111111111111110000001
    如果我们把有符号、无符号的数字按照相同的二进制对照下,还是4位,那么就是
    -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7
    对应
    8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7
    我们可以发现,对于负数,16+有符号数=无符号数。比如16-8=8,16-7=9...
    其中16是2的4次方
    我们也可以推广到32位,此时我们需要算出2的32次方,就是4294967296, 那么就是
    有符号的-127转换为无符号的数就是4294967296-127=4294967169,它的二进制就是11111111111111111111111110000001了。

    最后,上机验证下:
    刚才说了,10000000000000000000000001111111才是-2147483521
    它可以拆分成4个字节,分别是10000000 000000000 0000000 01111111,用16进制表示分别是0x80 0x0 0x0 0x7f
    在x86处理器里,整数的字节顺序是倒过来的,也就是0x7f,0,0,0x80

     int _tmain(int argc, _TCHAR* argv[])
    {
        unsigned char arr[] = {0x7f,0,0,0x80};
        int* i = (int *)arr;
        printf("%d\n", *i);
        return 0;
    }
    

    输出
    -2147483521
    Press any key to continue . . .

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料