zoukankan      html  css  js  c++  java
  • 用位运算反转一个字节

    刚在网上看到一个网友的位运算反转一个字节的帖子,贴过来学习积累啊...上代码:
    
    unsigned char reverse8( unsigned char c )
    {
         c = ( c & 0x55 ) << 1 | ( c & 0xAA ) >> 1;
         c = ( c & 0x33 ) << 2 | ( c & 0xCC ) >> 2;
         c = ( c & 0x0F ) << 4 | ( c & 0xF0 ) >> 4;
         return c;
    }
    上分析:
    
    它的算法是这样的: 首先是2位2位为一组,交换前一半和后一半。再4位4位为一组,交换前一半和后一半。再8位为一组,交换前一半和后一半。举个例子来看,
    将1 2 3 4 5 6 7 8 反转。
    (1)2个2个为一组,交换前一半和后一半, 变成:   2 1 4 3 6 5 8 7
    (2)4个4个为一组,交换前一半和后一半, 变成:   4 3 2 1 8 7 6 5
    (3)再8个为一组,交换前一半和后一半, 变成:   8 7 6 5 4 3 2 1
    反转成功。
    这样的算法本来很是简单,很容易用数学归纳法证明其正确。这函数, 巧妙就巧妙在作了并行计算,分组,它一次就计算完了。
    
    先看第一个语句。c = ( c & 0x55) << 1 | ( c & 0xAA ) >> 1; 
    0x55其实就是01010101, 0xAA就是10101010
    假设 c=abcdefgh
    c & 0x55 = 0b0d0f0h,     c & 0xAA = a0c0e0g0
    跟着,前者左移一位, b0d0f0h0, 后者右移一位, 0a0c0e0g, 再一个|运算,就两位两位交换了位置。
    想象一下,你有一个长纸条,分成一格一格,每格写一个字,假如你将纸条每隔一格剪一个小洞,滑一格,覆盖在原来的纸条上,你就会看到两个两个字交换了位置。
    (注: |运算可以换成+运算,想一想为什么?其实狠简单啊,一个数和0相加结果还是那个数啊...是这样的吧?)
    
    第二个语句。 c = ( c & 0x33 ) << 2 | ( c & 0xCC ) >> 2;
    0x33 = 00110011, 0xCC=11001100。 
    
    第三个语句。c = ( c & 0x0F ) << 4 | ( c & 0xF0 ) >> 4;
    0x0f = 00001111, 0xF0=11110000.
    http://www.cnblogs.com/stoneJin/archive/2011/10/26/2224935.html
  • 相关阅读:
    kafka搭建
    kafaka学习笔记
    metastore 简单说明
    二 python并发编程之多进程-理论
    文件指针偏移量
    FTP
    1 并发编程
    操作系统简介
    1 网络编程
    网络编程-osi七层
  • 原文地址:https://www.cnblogs.com/leijiangtao/p/4517252.html
Copyright © 2011-2022 走看看