位运算的妙用_判断2的乘方和二进制1的个数

二进制乘法运算 目录1.定点数一位乘法1.1定点原码一位乘法1.2定点补码一位乘法1.3定点原码二位乘法1.4定点补码二位乘法2.浮点数加减法运算 1.定点数一位乘法 1.1定点原码一位乘法 原码相乘,积符号同号得正、异号得负,数值为两数绝对值之积。 例:X=0.1101,Y=0.1011,求两数之积 解:取双符号位 部分积右移时,乘数寄存器同时右移一位。计算用两位符号,结果保留一位符号。 X*Y=0.10001111 Cd是乘数位数的补码值,每计算一次减一次。 Cn是C寄存器中Y的最低位,为1则部分积加X, 阅读详情

本来定好每个星期写一遍算法的博客的,可是因为最近赶项目,博客停止更新一段时间了,现在抽空继续更新。本来心情挺好的,一看手机,欠费两百多,真是日了狗了,百度云没有设置只能 wifi 下下载和上传,用了我的流量来下载,我的内心是崩溃的。
扣费截图


一、判断一个整数是否是2的乘方

1.题目:实现一个方法,判断一个正整数是否是2的乘方(比如 16 是 2 的 4 次方,返回 True;18 不是 2 的乘方,返回 False )。要求性能尽可能高。

解法一:
创建一个变量 Temp ,初始值是 1 。然后进入一个循环,循环中每次让Temp和目标整数比较,如果相等,则说明目标整数是 2 的乘方;如果不相等,则让 Temp 增大乘 2 ,继续循环比较。当 Temp 大于目标整数时(所以循环的判断条件是小于等于),说明目标整数不是 2 的乘方。

    /**
     * 判断整数(number)是否是2的乘方
     * 
     * @param number
     * @return
     */
    public static boolean isPower2_ONE(int number) {
        int temp = 1;
        while (temp <= number) {
            if (temp == number) {
                return true;
            }
            temp = temp * 2;
        }
        return false;
    }

优化:
先了解一个知识点:<<(左移)乘二,>>(右移)除二

具体的介绍:

java的左移和右移不是循环移动,遵循下面的规则:

1.右移
右移运算用来将一个数的二进制位序列右移若干位。例如 x>>=2 ,使 x 的各二进制位右移两位,移到右端的低位被舍弃,最高位则移入原来高位的值。例如:x=00110111,则 x>>2 为 00001101 ; y=11010011 ,则 y>>2 为11110100

2.左移
左移运算用来将一个数的二进制位序列左移若干位。例如 x<<=2 ,使 x 的各二进制位左移两位,右边补 0 ,若x=00001111,则x<<2为00111100.最高位左移后溢出,舍弃不起作用。

右移运算相当于对这个数字除2取商,左移运算相当于对这个数字乘2,而且使用左移右移实现乘法除法比使用乘法除法运算速度要快。

注意:以上等效是在不溢出的情况下进行。对于负数运算的左移是必然会溢出的

当然,如果要实现对负数的操作,由于计算机在处理负数的时候是对补码进行操作,所以除2其实是对补码的操作,因此对负数的操作需要对补码进行处理。

注意:补码运算的时候,最与最高位符号位是要保持不变的。另外,如果左移右移大于数据类型长度时候,会先取模。比如 int i ,左移 33 ,会变为左移 1 ,也就是 33%32

因此我们可以把上面循环中的乘 2 ,换成左移一位,因为左移运算符会比乘法的效率快很多。

    /**
     * 判断整数(number)是否是2的乘方(把乘2换成左移一位)
     * 
     * @param number
     * @return
     */
    public static boolean isPower2_TWO(int number) {
        int temp = 1;
        while (temp <= number) {
            if (temp == number) {
                return true;
            }
            temp = temp << 1;
        }
        return false;
    }

虽然换成左移运算法效率会变快,可是时间复杂度还是没有变化的,也就是说本质还是没有改变。

解法二:
观察下面的图,我们可以发现什么规律呢?

十进制转二进制

通过观察我们可以发现:
(1) 凡是2的乘方的正整数,其二进制数必然是以 1 为首位,其它位都是 0
(2) 如果给它减 1 ,(在位数相同的情况下)就会变成首位是 0 ,其它位全部是 1 的结果
(3) 0 和 1 的按位与运算结果是 0 ,因此 2 的乘方和他本身减1相与,即 N & N-1,结果必然是 0;也就是说用“位与”运算,得到的结果是0,就说明这个正整数是2的乘方

所以,2 的乘方都符合一个规律,即 N&N-1 等于 0,所以直接用这个规律判断即可,但是,这个结论就一定正确吗?这只是我们通过观察部分数据得出的结果,况且我们的数据量非常的少,怎样才能保证这个结论是正确的呢?我们可以通过反证法来证明:

假设真的存在一个正整数 N,N 不是 2 的幂,但是 N 符合 N&N-1 =0。

由 N 不是 2 的幂可以推断出,N 的二进制形式并不是除了最高位是1以外,其余为全是 0 。

既然其余位不全是 0 ,那么 N-1 的结果的最高位一定不会改变,仍然是1。

既然 N-1 的最高位是 1 ,N的最高位也是 1 ,那么 N&N-1!=0,和假设矛盾。

由此证明,符合 N&N-1 =0 的正整数必然是 2 的幂。

最后我们用代码来实现:

    /**
     * 判断整数(number)是否是2的乘方(位与运算)
     * 
     * @param number
     * @return
     */
    public static boolean isPower2_THREE(int number) {
        return (number & number - 1) == 0;
    }

二、求出一个正整数转换成二进制后的数字“1”的个数

题目:求出一个正整数转换成二进制后的数字“1”的个数
如:
int 型数值为 80
转化成二进制形式:80 = 00000000 00000000 00000000 01010000
因此 1 的个数为 2

解法一:
由上面的位运算判断 2 的乘方可以知道,n&(n-1) 可以把整数二进制的最右边的数由 1 变为 0 ,利用这个我们就可以解决这个问题了。

具体实现的代码如下:

    /**
     * 计算一个int型数值中bit-1的个数
     * 
     * @param n
     * @return
     */
    public static int bitCount1(int n) {
        int count = 0;
        while (n != 0) {
            n = n & (n - 1);
            count++;
        }
        return count;
    }

解法二:

我们也可以通过移位来解决这题,因为整数的二进制与 1 进行 & 运算的时候,当最末位也就是最右边的一位为 1 的时候,结果就是 1 ,判断完最后一位,然后把整数的二进制右移一位,再判断,直到整数等于 0 结束循环


    /**
     * 计算一个int型数值中bit-1的个数
     * 
     * @param n
     * @return
     */
    public static int bitCount2(int n) {
        int count = 0;
        while (n > 0) {
            if ((n & 1) == 1) {// 如果最右边的值是1
                count++;
            }
            n >>= 1; // 向右一位
        }
        return count;
    }

可是这种做法不是太好,因为 Java 中 int 占 4 个字节,一共 32 位,那么就是说,要循环 32 次才能结束

解法三:

其实这个题目在 Java ,Integer 类中 bitCount 方法的已经解决了的,我们可以看下大神们是如何巧妙的解决的。

Jdk中Integer的bitCount源码

一开始没想明白怎么推出来的,最后上网查了一下,

推断1

推断2


欢迎转载,转载请标明来源:

优快云主页:http://blog.youkuaiyun.com/two_water
简书主页:http://www.jianshu.com/users/8ec863a03f4f/latest_articles


C# 位运算 判断是否为2的N次幂 从键盘输入一个数判断该数字是否是2的N次幂 用位运算的方法实现 立即下载

相关推荐

Ansys Zemax导入CAD文件避坑指南:STL/STEP/IGES格式选择与性能优化

本文深度解析了在Ansys Zemax中导入CAD文件的核心要点与性能优化策略。针对STL、STEP、IGES等主流格式,详细对比了其几何表示、精度与适用场景差异,并提供了基于模型特征的格式选择决策树。文章重点分享了体元、弦公差等高级参数的调优技巧,以及处理复杂装配体和避免精度陷阱的实战指南,旨在帮助光学工程师提升仿真效率与结果可靠性。

weixin_29202687的博客 436

二进制中1的个数

问题:请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。 解法一: public static void main(String[] args) { Scanner sc=new Scanner(System.in); int N=sc.nextInt(); System.out.println(Integer.toString(N,2)); int count=0; for(int i=0;i<32;i

优快云SQ2016的博客 214

【算法实战】Keystone变换:从原理到MATLAB实现的距离走动校正

本文深入解析Keystone变换在雷达信号处理中的距离走动校正应用,从原理到MATLAB实现全面讲解。通过三种实现方法(DFT+IFFT、Sinc插值、Chirp-Z变换)的对比分析,结合实战案例展示如何有效解决高速目标导致的距离单元跨越问题,提升多普勒频谱聚焦质量。

weixin_29055699的博客 292

求一个正整数转成二进制后,有多少个1?

之前,看到一个判断一个正数是否是2的乘方(比如16是2的4次方)。要求性能尽可能高。 思路一:从int temp = 1开始,每次循环比较是否与number相等,不相等就让temp增大一倍(temp = temp*2),如此循环比较,直到相等为止。 这个方法的时间复杂度是O(LogN)。 思路二:寻找是2的乘方的数,的规律。  N N-1 2  ->     10b

豪冷的博客 2961

纯相位全息图优化算法综述

除此之外,还有许多用于减少斑点噪声的非迭代方法,例如:采用下采样掩膜的采样纯相位全息图(Sampled-Phase-only Hologram)方法、模式化相位掩膜(Patterned Phase-Only Hologram)方法、双相位方法(Double-Phase Method),以及使用非随机相位掩膜的方法(Random Phase-Free Method)等。迭代算法通常由一个对目标全息图的近似出发,经过一系列的重复操作不断优化这个近似全息图,直到该近似所得到的重建图像满足一定的误差要求;

ZhongKeWeiXing的博客 1427

FIFO Generate IP核使用——FIFO写操作详解及Status Flags页配置

本文介绍了FIFO的写操作及Status Flags页的配置信息。

u011565038的博客 2284

用位运算统计一个数的二进制有几个1(统计两个数二进制有几位不同)

LeetCode应用题目: 461 统计两个数的二进制表示有多少位不同 输入: x = 1, y = 4 输出: 2 1 (0 0 0 1) 4 (0 1 0 0) ↑ ↑ 解题思路:把x和y异或,1的个数代表两个数不同的位数 统计一个二进制数字的1的位数有: 1 转换为二进制字符串统计1的个数(速度最慢) public int hammingDistance(int x, int y...

yaoayao470的博客 883

anaconda安装-超详细版

文章目录一、anaconda安装1.1 anaconda安装地址1.2 安装详细步骤检验安装是否成功更改conda源(后续安装第三方库可以加快速度) 一、anaconda安装 Anaconda 是一个用于科学计算的 Python 发行版,支持 Linux, Mac, Windows, 包含了众多流行的科学计算、数据分析的 Python 包。装anaconda,就不需要单独装python了。 anaconda优点: 1、anaconda里面集成了很多关于python科学计算的第三方库,主要是安装方便,而p

in546的博客 25万+

算法之位运算求解二进制中1的个数

对于二进制,是当时大数学家莱布尼兹研究中国的周易后,他发表了“二进制算术的阐述”,副标题为 ”关于只用0与1,兼论其用处及伏羲所用数字的意义“,该文章对200年后计算机的存储产生了重要影响。 本文主要介绍利用位运算来计算二进制中1的个数。题目如下: 二进制中1的个数 输入一个 32 位整数,输出该数二进制表示中 1 的个数。 注意: 负数在计算机中用其绝对值的补码来表示。 样例1 输入:9 输出:2 解释:9的二进制表示是1001,一共有2个1。 样例2 输入:-2 输出:31 解释:-2在计算机里会

PRML_MAN的博客 2035

Ubuntu20.04复现instant-ngp,自建数据集,导出mesh

本次仅仅记录一下自己复现instant-ngp的过程,如果里面的参考有冒犯到原博主请联系我删除,本人也是nerf的小白一枚,可以一起交流学习神经辐射场,希望大家在复现instant-ngp的时候少走一些坑,情况允许下可以去复现一下npg-pl和nerfStudio,最后希望大家一起进步。看到一些博主说葵司的npg_pl也不错,而且葵司是台湾人,在youtube上也有讲解的视频。渲染的效果还是可以的,相对于源码来说还是有点模糊,我一些参数也没有设置,直接就拉进来进行渲染,速度是非常快的。

weixin_59961223的博客 9451

利用CAT12做皮层指标的统计分析及可视化笔记记录

利用CAT12做皮层指标的统计分析及可视化 文章目录利用CAT12做皮层指标的统计分析及可视化前言一、统计步骤1.Basic Models2.Estimate Surface Models3.Results二、可视化1.t值可视化2.p值可视化 前言 本来没有打算做SBM的,因为自己是新手小白,许多操作都不太懂,但最后还是打算做一下,于是就从上周末开始将很久之前跑VBM得到的surf文件夹中的数据捡起来继续做皮层分析,因为之前看了一个博主的博客,关于如何做SBM已经讲得非常清楚了,但是在统计及可视化这里,我

weixin_52073820的博客 8094

【还没看】转载 -- 位移运算与运算的基本作用 && 位运算的妙用_判断2的乘方和二进制1的个数

位移运算与运算的基本作用 http://yangsui.me/%E4%BD%8D%E8%BF%90%E7%AE%97%E7%9A%84%E4%BD%9C%E7%94%A8/ 位运算的妙用_判断2的乘方和二进制1的个数 https://zhuanlan.zhihu.com/p/25746093    ...

liangxw1的专栏 255

31、车载通信中的可见光通信(VLC)技术解析

本文详细解析了车载通信中可见光通信(VLC)技术的应用背景、优势及发展前景。对比传统RF通信技术(如DSRC),VLC利用LED照明设备实现高效、安全的车辆与车辆、车辆与基础设施之间的通信,具有频谱资源丰富、安全性高、无电磁干扰等优势。文章还探讨了VLC在交叉口交通控制、高速公路通信、自动驾驶等场景的应用潜力,展望了其在未来智能交通系统中的重要作用。

hill8的博客 318

位运算的操作(加减乘除、负数、乘方、1的个数)

一、位运算相关规律+口诀 c++中的位运算相关规律总结和口诀 二、加减乘除 int add(int num1, int num2){ int temp; do { temp = num1 ^ num2;//不进位相加:异或 num2 = (num1 & num2) << 1;//进位:位与+左移 num1 = temp; ...

wuhuagu_wuhuaguo的博客 1155

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

while实现乘方,乘法,二进制数中的1个数

public static void main(String[] args) { System.out.println(sub(3, 12)); System.out.println(pow(3, 4)); int a = 127; System.out.println(Integer.toBinaryString(a)); System.out.println(num(a)); } /** * .

m0_48725491的博客 304

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

如何判断一个正整数是否是2的乘方

实现一个方法,判断一个正整数是否是2的乘方(比如16是2的4次方,返回True;否则返回False) 方法一:从1开始循环乘以2,直到结果第一次大于或者等于目标值,如果相等,则放回True,如果大于,则返回False 方法二:使用该数循环除以2,如果最终商是1并且余数是0,则返回True;循环中一旦出现余数不为0,则返回False 方法三:借助位运算 如果该数是2的乘方,则该数的二进制表示

Coding家园! 2948

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

[矩阵]快速幂和乘方和

给出一个n*n的矩阵A和正整数k,请求出S=A+A^2+A^3+A^4+...+A^k的值.A^x表示x个A相乘的结果.

StudyingPanda的博客 1774

使用位运算实现乘法和乘方运算

1、使用位运算乘法。 把一个乘数变为2进制后,使用位运算完成乘数的乘法。 [cpp] view plaincopy /*   * 输入:正整数k 和 正整数m   * 输出:k*m   */    __int64 km(__int64 k, __int64 m){      __int64 x = k;      int w = (in

AlienTech for better life!~ 2099

位运算基础

作者:blue时间:2024.3。

blue的博客 1001

漫画算法:判断2的乘方

最近几天有点学懵了,心态有些小小的问题,可能是受到了台风的影响亦或者是没有及时寄存好的知识, 今天学点有趣的东西,放松放松 转载自:玻璃猫大神的博客 小灰陷入回忆当中。。。。 题目:实现一个方法,判断一个正整数是否是2的乘方(比如16是2的4次方,返回True;18不是2的乘方,返回False)。要求性能尽可能高。 解法一: 创建一个中间变量Temp,初始

摩尔的博客 972

【算法精练】位运算 && 阶乘

位运算 最近碰到很多通过巧妙着`来巧妙解决复杂问题的算法,今天分享的这道题,或许能够开拓你的一些算法思维。 案例一 有一组存放 ID 的数据。并且 ID 取值为 0 - (N-1) 之间,其中只有一个 ID 出现的次数为 1,其他的 ID 出现的次数都等于 2,问如何找到这个次数为 1 的 ID ? 解法一:巧用数组下标 我的第一想法便是采用下标法来解决,把 ID 作为数组 arr 的下标,在...

码农印象 1133

判断2的乘方

给定一个整数N,判断它是不是2的乘方,比如16=2^4 在纸上写了几个例子,就发现了规律,7=0111,8=1000 N&(N-1) == 0 这就是二进制的规律吧 再说一个,给定一个整数N,把它转换成二进制,那之中有多少个数字1呢 观察上面的例子发现,每进行一次N&(N-1)运算二进制数字串都会少一个1,所以就得到答案了 int cnt = 0; while(N) {

jiang_1603的博客 337

记录一个算法题(java代码):判断整数是不是2的乘方数

package ludims.main; import java.util.Scanner; public class Compute2Power {     public static void main(String[] args) {         System.out.println("判断整数是不是2的乘方数"); //题干                 Scanner in =...

qq_35094410的博客 499

如何判断整数是否是2、3、4的乘方(幂)

在LeetCode 342. Power of Four和LeeCode 326. Power of Three中有关于如何判断整数是否是4或者是3的乘方问题,并且不用循环和递归。 如果使用循环或者递归可以很容易地通过不断地除以基数进行判断,如果要求不能使用循环或者递归,那该问题就有难度了。 乘方数的重要性质:已知整数MMM是整数nnn的乘方即M=niM=niM=n^{i},若将MMM表示为n...

zhusf的博客 927

LeetCode探索之旅(65)-231判断2的乘方

今天继续LeetCode,第231题,判断一个给定的整数是否是2的乘方。 分析: 方法一:既然是判断2的乘方,那么将这个数进行不断除2,那么除数不能整除2就不是2的乘方,如果是就继续除2,直到为1结束。这个方法思想简单,但是因为每次都要除2,那么对于一个大数的话,就会花费很多时间。 方法二:因为是2的乘方,可以利用二进制来解题,判断给定的数是否是最高位为1,其余位全部为0。那么就转换成位运算。 问...

JerryZengZ的博客 232
上一篇: Tool Resource
下一篇: Android 网络框架_目前(2016年11月7日)最流行的网络框架OKHttp3
Two_Water
博客等级 码龄12年 573粉丝 134原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值