• 特殊表达式的意义[c++ special expressions]


    【本文链接】

    http://www.cnblogs.com/hellogiser/p/special-expressions.html

    • x&(x-1)表达式的意义: 统计二进制中1的个数。
     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    int func(int x)
    {
        
    int countx = 0;
        
    while(x)
        {
            countx++;
            x = x & (x - 
    1);
        }
        
    return countx;
    }

    假定x = 9999即 10011100001111

    答案: 8

    思路: 将x转化为2进制,看含有的1的个数。

    注: 每执行一次x = x&(x-1),会将x用二进制表示时最右边的一个1变为0,因为x-1将会将该位(x用二进制表示时最右边的一个1)变为0。

    • (x&y)+((x^y)>>1)的功能是取两个数的平均值 (x+y)/2。

    (x&y)+((x^y)>>1)的功能是取两个数的平均值 (x+y)/2 很牛X的一个思路,虽然不算高效,但如果在汇编中的话,这种方法可以不产生高位溢出。

    大概思路应该是这样: x=x1+x2+x3,y=y1+y2+y3. (x+y)/2=(x1+y1)/2+(x2+y2)/2+(x3+y3)/2. 把x和y里对应的每一位(指二进制位)都分成三类,每一类分别计算平均值,最后汇总。其中,一类是x,y对应位都是1,用x&y计算其平均值;一类是x,y中对应位有且只有一位是1,用(x^y)>>1计算其平均值;还有一另是x,y中对应位均为0,计算得0。

    下面我再分别说明一下前两种情况是怎样计算的:

    1) 第一部分,x,y对应位均为1,相加后再除以2还是原来的数,如两个00001111相加后除以2仍得00001111。

    2) 第二部分,x,y对应位有且只有一位为1,用“异或”运算提取出来,然后>>1(右移一位,相当于除以2),即到到第二部分的平均值。

    3) 第三部分,x,y对应位均为零,因为相加后再除以二还是0,所以不用计算。

    4) 三部分汇总之后就是(x&y)+((x^y)>>1)。

    顺便解释一下前面说到可以避免溢出。 假设x,y均为unsigned char型数据(0~255,占用一字节),显然,x,y的平均数也在0~255之间,但如果直接x+y可能会使结果大于255,这就产生溢出,虽然最终结果在255之内,但过程中需要额外处理溢出的那一位,在汇编中就需要考虑这种高位溢出的情况,如果(x&y)+((x^y)>>1)计算则不会。

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    // return half of sum of x and y
    unsigned char half(unsigned char x, unsigned char y)
    {
        
    return (x & y) + ((x ^ y) >> 1);
        
    // return (x+y)/2; // may be overflow
    }

    void test_half()
    {
        printf(
    "%d ", half(28)); // 5
        printf("%d ", half(55)); // 5
        printf("%d ", half(56)); // 5
        printf("%d ", half(255255)); // 255
    }
    • (int&)a和(int)a的区别
     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    void test_a()
    {
        
    // (int&)a treat a memory as a integer
        float a = 1.0f;
        cout << (
    int)a << endl;  // 1
        cout << (int &)a << endl; // 1065353216
        cout << boolalpha << ( (int)a == (int &)a ) << endl; // false

        
    float b = 0.0f;
        cout << (
    int)b << endl; // 0
        cout << (int &)b << endl; // 0
        cout << boolalpha << ( (int)b == (int &)b ) << endl; // true
    }

    (int)a实际上是以浮点数a为参数构造了一个整型数,该整数的值是1。

    (int&)a则是告诉编译器将a当作整数看(并没有做任何实质上的转换)。因为1以整数形式存放和以浮点形式存放其内存数据是不一样的,因此两者不等。

    对b的两种转换意义同上,但是0的整数形式和浮点形式其内存数据是一样的,因此在这种特殊情形下,两者相等(仅仅在数值意义上)。

    注意,程序的输出会显示(int&)a=1065353216,这个值是怎么来的呢?前面已经说了,1以浮点数形式存放在内存中,按ieee754规定,其内容为0x0000803F(已考虑字节反序)。这也就是a这个变量所占据的内存单元的值。当(int&)a出现时,它相当于告诉它的上下文:“把这块地址当做整数看待!不要管它原来是什么。”这样,内容0x0000803F按整数解释,其值正好就是1065353216(十进制数)。

    【本文链接】

    http://www.cnblogs.com/hellogiser/p/special-expressions.html

    个人学习笔记,欢迎拍砖!---by hellogiser

    Author: hellogiser
    Warning: 本文版权归作者和博客园共有,欢迎转载,但请保留此段声明,且在文章页面明显位置给出原文连接。Thanks!
    Me: 如果觉得本文对你有帮助的话,那么【推荐】给大家吧,希望今后能够为大家带来更好的技术文章!敬请【关注】
  • 相关阅读:
    VA插件突然不能使用,彈出“the security key for....”
    【WIN10】Segoe MDL2 Assets
    【WIN10】WIN2D——圖層
    【WIN10】WIN2D——圖像處理
    【WIN10】WIN2D——繪製文字
    【WIN10】WIN2D——基本圖形的繪製
    為你的文件夾添加“使用CMD命令打開”菜單
    【WIN10】移植opencc到WIN10-UWP,實現自己的繁簡轉換工具
    【WIN10】判斷程序運行在哪個平台
    【WIN10】使用VS生成appx安裝包,並安裝測試
  • 原文地址:https://www.cnblogs.com/hellogiser/p/special-expressions.html
Copyright © 2020-2023  润新知