内容: 记录求二进制中1的个数的另一种好方法:汉明重量计算算法

最近在看redis源码,发现redis求二进制中1的个数的方法很赞,记录一下:
代码:

int vpSWAR(int i)
{i = (i & 0x55555555) + ((i>>1) & 0x55555555);i = (i & 0x33333333) + ((i>>2) & 0x33333333);i = (i & 0x0F0F0F0F) + ((i>>4) & 0x0F0F0F0F);i = (i * 0x01010101) >> 24;return i;
}

原理解析:

SWAR算法分为四步:一:计算每两位为一组的二进制形式包含1的个数
i = (i & 0x55555555) + ((i>>1) & 0x55555555);二:计算每四位为一组的二进制形式包含1的个数i = (i & 0x33333333) + ((i>>2) & 0x33333333);三:计算每八位为一组的二进制形式包含1的个数i = (i & 0x0F0F0F0F) + ((i>>4) & 0x0F0F0F0F);四:直接计算32位包含1的个数。对于32位的数来说,可以将其按每8位一组分为4组,直接计算经过前三步计算之后得到的结果,那么要计算其总共包含多少个1,只需计算四个八位加起来是多少个1,就像:A+B+C+D。而ABCD表示的是不同的位区间范围。不过不同位置,不能直接相加,该如何快速计算A+B+C+D的值呢?就是将B、C、D分别左移8位、16位、24位,使其分别与最高位的A对齐:方法如下:将数字i分别左移0位、8位、16位、24位然后相加的结果,就是 i * 0x01010101 ,因为i + (i << 8)+ (i << 16) + (i << 24) = i * (1 + 1 << 8 + 1 << 16 + 1 << 24) = i * 0x01010101 对于32位数字来说,左移之后超过32位的部分会被舍弃,低位补0,将左移之后得到的四个数字相加,结果的高8位的值就是原32位数包含的1的个数,要得到这个值,只需要将结果右移24位,将值放在低8位即可。

使用举例:redis

redis使用这个算法和查表法两种配合来求二进制中1的个数:
1.当二进制位数小于128时,使用查表法
2.当二进制位数大于128时,使用此算法,然后按每次32bit计算来叠加

【博客177】二进制中1的个数:方法三相关推荐

  1. 剑指Offer:二进制中1的个数

    题目:输入一个整数,输出该数二进制表示中1的个数. // 二进制中1的个数 #include <stdio.h>int wrong_count_1_bits(int n) // 错误解法: ...

  2. VIPKID:笔试题(数组中和为0的一对数的数量,十进制转二进制中1的个数)

    1. 求数组中的和为0 的一对数的数量 注意,需要用到set import java.util.Scanner;public class Main{public static void main(St ...

  3. 牛客题霸 [二进制中1的个数] C++题解/答案

    牛客题霸 [二进制中1的个数] C++题解/答案 题目描述 输入一个整数,输出该数32位二进制表示中1的个数.其中负数用补码表示. 题解: 判断1的个数 x&(-x)=2^k 有点类似于树状数 ...

  4. [剑指Offer]12.二进制中1的个数

    题目 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 思路 把一个整数减去1,再和原整数做与运算,会把整数最右边一个1变成0.那么一个整数的二进制表示中有多少个1,就可以进行多次这样 ...

  5. (转)快速统计二进制中1的个数

    大牛博客插眼:https://blog.csdn.net/u013243347/article/details/52220551 证明在大牛的博客里,直接挂代码吧: 时间复杂度从logn下降到了O(二 ...

  6. 基于visual Studio2013解决面试题之0410计算二进制中1的个数

     题目 解决代码及点评 /*求一个数中,二进制表示方式中1的个数范例算法采用分治思想,通过位操作计算二进制中1的个数 */#include <iostream> using name ...

  7. C/C++求一个整数的二进制中1的个数

    求一个整数的二进制中1的个数 收藏 题目:输入一个整数,求该整数的二进制表达中有多少个1.例如输入10,由于其二进制表示为1010,有两个1,因此输出2. 分析:这是一道很基本的考查位运算的面试题.包 ...

  8. 剑指Offer #11 二进制中1的个数(想不到的骚操作)

    题目来源:牛客网-剑指Offer专题 题目地址:二进制中1的个数 题目描述 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 题目解析 对于这种涉及位运算的题目,我们首先要了解基本的位 ...

  9. 《剑指offer》-- 把数组排成最小的数、丑数、二进制中1的个数、表示数值的字符串、替换空格

    一.把数组排成最小的数: 1.题目: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为 ...

最新文章

  1. Ubuntu下如何用Empathy上QQ
  2. 写得太好了!树莓派安装docker
  3. 惠普服务器年销售额,IBM和惠普去年分列服务器收入和发货量第一
  4. java sort()怎么实现的_Java中Array.sort()的排序原理
  5. 推荐高质量的公众号,值得跟进学习!
  6. XCode10 swift4.2 适配遇到的坑
  7. 最大正方形(洛谷-P1387)
  8. 触漫机器人_触触+机器人=???
  9. Apache mod_rewrite
  10. 重新leetcode第1天——二叉树遍历算法讲解合集
  11. Ubuntu18.04/16.04 安装glog
  12. uniapp手写_uniapp 手写 Steps 步骤条
  13. html word 分页
  14. JavaScript中如何删除节点?
  15. lintcode 输出赛程表
  16. 苹果mac系统下浏览器video无法自动播放问题
  17. 手摸手写一个互联网黑话生成器
  18. “破镜”真的没办法“重圆”了吗?
  19. php反转图片颜色,PHP 图片处理类(水印、透明度、缩放、相框、锐化、旋转、翻转、剪切、反色)...
  20. CNN2019.11.22

热门文章

  1. tws蓝牙耳机什么牌子好?2023tws耳机推荐
  2. 生产力提升·快捷键肌肉训练
  3. 智能运维之时间序列预测中的经典时序模型
  4. 计算机考试要手速,抢考试名额 | 这是一场网速与手速的较量
  5. 【计算机图形学基础】第一章绪论
  6. 任正非再发表讲话:华为已进入战时状态
  7. Ubuntu16成功安装QQ2012国际版(wine1.6.2)
  8. npm run build生产环境打包部署
  9. wpa_supplicant软件架构分析
  10. 使用C语言+EasyX完成消灭星星游戏(1)