zoukankan      html  css  js  c++  java
  • 取反运算符 和 位移运算符

    我其实是有疑惑在里面, 下面会提到。

    首先来段代码:

    void test2()
    {
    	int i1 = ~0; 
    	int i2 = i1>>1; 
    	unsigned int u1 = ~0; 
    	unsigned int u2 = u1>>1; 
    	printf("int         : %X -> %X, %d -> %d
    ", i1, i2, i1, i2);
    	printf("unsigned int: %X -> %X, %u -> %u
    ", u1, u2, u1, u2);
    }
    
    /*** Print *****/
    
             int : FFFFFFFF -> FFFFFFFF,         -1 -> -1
    unsigned int : FFFFFFFF -> 7FFFFFFF, 4294967295 -> 2147483647
    
    /****/
    

      

    取反运算符(~):

      计算变量的反码。

    位移运算符(<<  或  >>):

      将一个数的各二进制位左或右移若干位。

      左移运算符(<<):  各二进制位左移若干位,移动的位数由右操作数指定,操作数不为负数, 右边空出的位用0填补,高位左移溢出则舍弃该高位。

      右移运算符(>>):  各二进制位右移若干位,移动的位数由右操作数指定,操作数不为负数, 移到右端的低位被舍弃,高位填补有以下情况:

                对于无符号数,高位补0。即右移时左边高位移入0;

                对于有符号数,某些机器将对左边空出的部分用符号位填补(“算术移位”),而另一些机器则对左边空出的部分用0填补(“逻辑移位”)。

                       如果原来符号位为0(该数为正),则左边也是移入0。

                       如果原来符号位为1(该数为负),则左边移入0还是1,要取决于所用的计算机系统。有的系统移入0,有的系统移入1。移入0的称为“逻辑移位”,即简单移位;移入1的称为“算术移位”。

    Note: 计算机中0的原码有+0和-0, 我实在CentOS测试的, 这里的0原码是-0(至于为什么不是+0, 我这真不知道, 这就是我想提问的问题,也求解答)。系统右移操作为“算数位移”。

    我解析以下上面的代码:

     

    [-0]有符号型 = [1000 0000 0000 0000 0000 0000 0000 0000]原

           = [1111 1111 1111 1111 1111 1111 1111 1111]反

           = [0000 0000 0000 0000 0000 0000 0000 0000]补

    [-1]有符号型 = [1000 0000 0000 0000 0000 0000 0000 0001]原

           = [1111 1111 1111 1111 1111 1111 1111 1110]反

           = [1111 1111 1111 1111 1111 1111 1111 1111]补

    [4294967295]无符号型 =  [1111 1111 1111 1111 1111 1111 1111 1111]原、反、补码

    [2147483647]无符号型 =  [0111 1111 1111 1111 1111 1111 1111 1111]原、反、补码

    void test2()
    {
        int i1 = ~0; //取得0的反码。 这时 i1 的二进制数为 [1111 1111 1111 1111 1111 1111 1111 1111] = [-1]补码 , 这里是有符号的
        int i2 = i1>>1; //有符号变量右移操作,这里是算数位移。这时 i2 的二进制数为 [1111 1111 1111 1111 1111 1111 1111 1111] = [-1]补码 , 这里是有符号的
        unsigned int u1 = ~0; //取得0的反码。这时u1 的二进制数为 [1111 1111 1111 1111 1111 1111 1111 1111] = [4294967295]原码, 这里是无符号的
        unsigned int u2 = u1>>1; //无符号变量右移操作,高位直接上0, 这时u2 二进制数为 [0111 1111 1111 1111 1111 1111 1111 1111] = [2147483647]原码, 这里是无符号的,高位直接上0
        printf("int         : %X -> %X, %d -> %d
    ", i1, i2, i1, i2); //输出十六进制,十进制, 计算机以补码形式存储负数, 所以i1 = i2 = -1;
        printf("unsigned int: %X -> %X, %u -> %u
    ", u1, u2, u1, u2); //输出十六进制,十进制,  
    }
    

      

    可能说的不太清晰, 自己认真去想想还是能懂的。 

    我的关键问题在于为什么这里0不是+0.

    如果有错误请指正, 也可以吐槽。

  • 相关阅读:
    NYOJ41三个数从小到大排序
    HDUOJ2115I Love This Game
    NYOJ56阶乘因式分解(一)
    NYOJ65另一种阶乘问题
    HDUOJ1234开门人和关门人
    NYOJ74小学生算术
    NYOJ11奇偶数分离
    HDUOJ3980取模运算
    HDUOJ2014 青年歌手大奖赛_评委会打分
    HDUOJ1860 统计字符
  • 原文地址:https://www.cnblogs.com/jluzhsai/p/3550227.html
Copyright © 2011-2022 走看看