V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
likeunix
V2EX  ›  Linux

请教一下负号的位级运算过程

  •  
  •   likeunix · 2016-10-20 14:59:09 +08:00 via Android · 2256 次点击
    这是一个创建于 2974 天前的主题,其中的信息可能已经有所发展或是发生改变。
    hello,everyone

    int a = 0xffffffff;
    int b= -a;
    结果是 a 和 b 都是 0xffffffff 。
    我知道补码不能表示-a ,但是为什么 a 和 b 的位是一样的?
    第 1 条附言  ·  2016-10-20 16:29:52 +08:00
    感谢一楼指出错误,是我晕了,重新描述一下问题。
    在 c 语言中:
    int a = 0x80000000;
    int b = -a;
    用补码是不能表示 2147483648 的,但是为什么
    int b = -a;执行之后, b 的值和 a 的值一样,都是-2147483648
    12 条回复    2016-10-20 23:36:20 +08:00
    juxingzhutou
        1
    juxingzhutou  
       2016-10-20 15:56:21 +08:00
    讲真,我不知道楼主在问什么。这是什么语言都没说,而且补码为什么不能表示-a ,楼主先把补码补一补吧。
    msg7086
        2
    msg7086  
       2016-10-20 16:05:36 +08:00 via Android
    超出范围了啊。
    简单说,因为只有 0 没有-0 ,所以负数的最小值是没有能对应的正数的。取-a 以后会比最大值大 1 ,然后绕回 a 自己了。
    wsy2220
        3
    wsy2220  
       2016-10-20 16:11:31 +08:00
    @msg7086 然而 0xffffffff = -1, 0x80000000 才没有对应的正数...
    jmc891205
        4
    jmc891205  
       2016-10-20 16:22:08 +08:00
    b 的值是 1 啊 怎么可能还是 0xffffffff
    likeunix
        5
    likeunix  
    OP
       2016-10-20 16:31:10 +08:00 via Android
    @juxingzhutou 谢谢提出错误,我改了一下问题,看下~
    likeunix
        6
    likeunix  
    OP
       2016-10-20 16:32:41 +08:00 via Android
    @jmc891205 是我描述的不对,我修改了改了一下问题,再看下哈
    irenicus
        7
    irenicus  
       2016-10-20 16:54:26 +08:00
    ...
    IC 工程师来回答问题了
    int a = 0x80;
    则 a = 0b1000_0000
    -a = ~(0b1000_0000) + 1 = 0b0111_1111 + 1 = 0b1000_0000 = 0x80;
    ... :-)
    irenicus
        8
    irenicus  
       2016-10-20 16:59:10 +08:00
    另外:
    int a = 0xff;
    则 a = 0b1111_1111;
    -a = ~(0b1111_1111) + 1 = 0b0000_0000 + 1 = 0b0000_0001 = 0x01;

    这个例子其实是 a=-1 ,那么-a 当然就是 1 了

    前一个例子, a=-128 ,但是 8 位的表示范围是-128~127 ,那么-a = 128 显然不在这个范围内,就溢出了,所以结果不对。

    你提供的例子其实是一样的情况,取反的时候溢出了
    jmc891205
        9
    jmc891205  
       2016-10-20 16:59:49 +08:00
    @likeunix 0x80000000 按位取反再+1 不就是 0x80000000 吗?不知道你是怎么算补码的?
    likeunix
        10
    likeunix  
    OP
       2016-10-20 17:03:53 +08:00 via Android
    @irenicus 原来-a 是对 a 按位取反再加一得到的,谢谢谢谢啦
    msg7086
        11
    msg7086  
       2016-10-20 23:35:17 +08:00
    @wsy2220 嗯,看题目的时候脑残了。_(:з」∠)_
    msg7086
        12
    msg7086  
       2016-10-20 23:36:20 +08:00
    @wsy2220 因为题目里提到的问题实在太典型了,所以压根没去想这个数字是不是对,就直接按照 INT_MIN 去回答了……
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   898 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 22:25 · PVG 06:25 · LAX 14:25 · JFK 17:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.