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条)

报告相同问题?

悬赏问题

  • ¥20 Python安装cvxpy库出问题
  • ¥15 用前端向数据库插入数据,通过debug发现数据能走到后端,但是放行之后就会提示错误
  • ¥15 python天天向上类似问题,但没有清零
  • ¥30 3天&7天&&15天&销量如何统计同一行
  • ¥30 帮我写一段可以读取LD2450数据并计算距离的Arduino代码
  • ¥15 C#调用python代码(python带有库)
  • ¥15 矩阵加法的规则是两个矩阵中对应位置的数的绝对值进行加和
  • ¥15 活动选择题。最多可以参加几个项目?
  • ¥15 飞机曲面部件如机翼,壁板等具体的孔位模型
  • ¥15 vs2019中数据导出问题