转自:https://blog.csdn.net/wuxianglonghaohao/article/details/21602305

http://www.newhottopic.com/2014/03/20/reverse-bits/

把一个无符号整数的比特位反转顺序。
有很多种方法来实现这个。我们这里给出一个算法:通过异或运算来交换,然后用分治方法来优化它。

提示:

你怎么把第i个和第j个位置的bit给交换了呢?如果你能用异或来实现,试着给出算法。

异或交换的小技巧:

如果一共有n个bit,反转它可以通过最少n/2次交换,最多n次交换来完成。技巧就在于实现一个交换函数swapBits(i,j),用来交换位置在i和j的两个bit。你应该还记得异或运算:0 ^ 0 == 0, 1 ^ 1 == 0, 0 ^ 1 == 1, 和 1 ^ 0 == 1。
我们只要在第i位和第j位的bit不同时交换就行了。我们用异或来检测这两位bit是否相同。然后我们还需要切换这两个位置的bit值,我们可以再次用异或来完成操作。通过异或,两个位置的值都可以被切换了。
  1. typedef unsigned int uint;
  2. uint swapBits(uint x, uint i, uint j) {
  3. uint lo = ((x >> i) & 1);
  4. uint hi = ((x >> j) & 1);
  5. if (lo ^ hi) {
  6. x ^= ((1U << i) | (1U << j));
  7. }
  8. return x;
  9. }
  10. uint reverseXor(uint x) {
  11. uint n = sizeof(x) * 8;
  12. for (uint i = 0; i < n/2; i++) {
  13. x = swapBits(x, i, n-i-1);
  14. }
  15. return x;
  16. }

(译者注:上面的其中一行代码:x ^= ((1U < < i) | (1U << j));是为了切换两个位置的bit值,可以看个例子:x = 1001,–> x ^= ((1U < < 1) | (1U << 3)) –> x = 1001 ^ (1010) –> x = 0011 )

用这种异或方法来反转bit位的时间复杂度是O(n),n是传入的无符号整数的比特位数。

分而治之:

记得归并排序是怎么做的吧?让我们看一下当n=8(一字节)时是怎么样的:
  1. 01101001
  2. / \
  3. 0110 1001
  4. / \ / \
  5. 01 10 10 01
  6. /\ /\ /\ /\
  7. 0 1 1 0 1 0 0 1
第一步是交换所有奇数和偶数位置的bit。然后交换连续成对的bit,依此类推……
因此,一共只要log(n)次操作就能完成。
下面的代码展示了一个特定的当n==32时的例子——当然,它也能很简单的去适配当n更大时的情况。
  1. uint reverseMask(uint x) {
  2. assert(sizeof(x) == 4); // special case: only works for 4 bytes (32 bits).
  3. x = ((x & 0x55555555) << 1) | ((x & 0xAAAAAAAA) >> 1);
  4. x = ((x & 0x33333333) << 2) | ((x & 0xCCCCCCCC) >> 2);
  5. x = ((x & 0x0F0F0F0F) << 4) | ((x & 0xF0F0F0F0) >> 4);
  6. x = ((x & 0x00FF00FF) << 8) | ((x & 0xFF00FF00) >> 8);
  7. x = ((x & 0x0000FFFF) << 16) | ((x & 0xFFFF0000) >> 16);
  8. return x;
  9. }

小记:

这不是反转bit位的唯一方法,也不是效率最高的。你想要探索更多关于反转bit位的算法/灵感,请访问这里:Bit Twiddling Hacks(译者注:该链接里真的很多好东东)。
英文原文在这里。

转载于:https://www.cnblogs.com/sky-heaven/p/10039709.html

反转比特位(文章最后有干货)【转】相关推荐

  1. Java字节转换为比特位及相关

    文章目录 字节转换为比特位字串 直接上代码: 测试: 说明: 字节(byte).比特位.整型(int) 原码.反码和补码 移位运算符 >> 有符号,右移 >>> 无符号, ...

  2. C语言移位操作之增删对应比特位

    在实际开发中,常常用移位操作代替乘除法,因为一般情况下: 1.从效率上看,使用移位指令有更高的效率,因为移位指令占2个机器周期,而乘除法指令占4个机器周期. 2.从硬件上看,移位对硬件更容易实现,所以 ...

  3. c语言比特和字节,详解 比特(位,bit),字节(Byte),字符的区别 *(转)

    比特(位):英文bit,是计算机晶体管的一种状态(通电与断电).就是0与1,真与假,是计算机最基本的传输单位. 示例: 2bit : 10; 4bit : 1111; 8bit : 1111 1111 ...

  4. Rowhammer漏洞致“比特位翻转”,如何解决?

    读者们也许会觉得Rowhammer和比特位翻转是音乐及舞蹈行业的专业术语,但其实他们指的是存在于动态随机访问存储(DRAM)--大多数电子设备中都存在的一种核心组件中的某种非常严重的漏洞.随着驱动器中 ...

  5. 《LeetCode力扣练习》第338题 比特位计数 Java

    <LeetCode力扣练习>第338题 比特位计数 Java 一.资源 题目: 给你一个整数 n ,对于 0 <= i <= n 中的每个 i ,计算其二进制表示中 1 的个数 ...

  6. CAN 总线 之六 BOSCH CAN 比特位填充(编码规则)、归零编码(RZ)和不归零编码(NRZ)

    帧格式   在 CAN 总线中,为了确保足够的转换以保持同步,在相同极性的 5 个连续位之后使用位填充.下面以 标准格式来进行说明,先看下面标准格式的帧的图示: 在某些文档中,将 CAN 帧分为以下部 ...

  7. 数字图像处理图像反转的实现_使用8086微处理器反转16位数字

    数字图像处理图像反转的实现 Problem statement: 问题陈述: Write an assembly language program in 8086 microprocessor to ...

  8. 数字图像处理图像反转的实现_反转8位数字| 8085微处理器

    数字图像处理图像反转的实现 Problem statement: 问题陈述: To reverse 8 bits number using 8085 microprocessors. 使用8085微处 ...

  9. Intel 64/x86_64/IA-32/x86处理器 - 通用指令(9/E) - 比特位操控指令(BMI1 BMI2)

    Bit Manipulation Instructions (BMI1 & BMI2) 指令 描述 ANDN 格式: ANDN r32a, r32b, r/m32 第一源操作数(r32b)取反 ...

最新文章

  1. Shine Button动画效果 类似Tinder APP的卡片界面
  2. Oracle高效分页存储过程实例
  3. 职场:5种幼稚表现,好多工作十年的人还在犯
  4. 三十三、基本分段存储管理方式
  5. 路由跟踪命令.查看DNS、IP、Mac等
  6. 用JavaScript玩转游戏物理(一)运动学模拟与粒子系统
  7. linux红帽子桌面模式ftp,Linux操作系统配置Vsftp的方法
  8. 40亿条/秒!Flink流批一体在阿里双11首次落地的背后
  9. 微信lbs开发 php,【LBS】基于地理位置的搜索之微信 附近的人 简单实现
  10. 第三方软件源_最强软件管家!要啥有啥,吊打全网~
  11. Cover团队在Kovan以太坊测试网部署xCOVER智能合约
  12. C++之左值引用与右值引用
  13. 怎么在ASP.NET 2.0中使用Membership (转载)
  14. 股票数据下载-下载股票历史数据
  15. 如何在不知道密码的情况下卸载趋势防毒墙网络版
  16. 迅为4412开发板上的步进电机小知识
  17. Chrome安装插件Hackbar
  18. uni-app开发和常规Vue开发
  19. arcgis取消投影_【坐标系杂谈】投影后的数据如何去除投影?
  20. html引用less文件报错,vue-cli import less文件报错

热门文章

  1. C++中指向类成员指针的用法
  2. 吴恩达老师深度学习视频课笔记:优化算法
  3. 【Python】解决print不能立即打印的问题
  4. java写exe程序实例,java实现可安装的exe程序实例详解
  5. 用友u8 php,php 访问用友u8数据
  6. hive sql练习_SQL语句+语法 I 数据分析面试必备
  7. html 语言 gif 动画,动效篇(1)--从简单CSS3动画片段代码,到生成gif动图~
  8. java基础入门传智播客 源码_Java-_2020年版Java零基础视频教程(Java 0基础,Java初学入门)魔鬼讲师老杜出品...
  9. linux里运行windows,在Linux上运行Windows应用程序
  10. java线程的优先级是数字越大优先级越高_《深入理解Java虚拟机》5分钟速成:12章(Java内存模型与线程)...