判断一个正整数是否是2的N次方的简洁算法及其证明
在写代码时遇到了“判断一个正整数是否是2的N次方”的问题,不想调用 java.lang 的 Math 类库进行浮点运算,觉得转换为浮点不是个好办法。
遂在网上搜索了一下,发现有人列出来好几种写法,列举几种:
1、通过循环除2;这种方法不值一提,略过;
2、针对32位/64位只有有限个 2 的N次方的常量值,逐个进行比较;额。。。这个也略过;
3、通过正则表达式进行文本匹配,判断是否2的后面都是 0 ;这个绕得更远了。。。
最后,有一种最简洁优雅的写法:(value & (value -1)) == 0;
喔,的确是简洁优雅!!!
不过,等等,接下来有人提出,似乎“所有2的N次方的结果都符合这个表达式”这点很容易证明;
可是如何证明符合条件“(value & (value -1)) == 0”的一定就是 2 的 N 次方呢?(N 是整数且大于等于0)。
想了一下,证明也不难,遂在此记下:
1、首先,记 A = value; B = value - 1;
2、既然 A & B == 0,那么意味着,A和B的二进制形式中,每一位都不相同;(例外的情况只有“两者都是 0” ,否则存在相同位的两个数的按位相与的结果不可能为 0)
3、由于 B = A - 1,即 A > B;基于第2点,A 和 B 每一位都不同,则可以推断出只有两种情况:
(1)以二进制形式, A 最高位 1 与 B 的最高位 1 的位数相差 1 ;(x表示后面跟随的位数是 0 位到多位)
A: 10xxxxxxx
B: 01xxxxxxx
(2)第二种情况就是:A = 1,B = 0;
显然第二种情况是符合命题的,因为 N = 0 ,2 的 N 次方的结果为 1 ; 接下来继续针对第一种情况做推导。
4、由于 A 与 B 仅相差1,那意味着在 B 的二进制的末尾加上 1 ,将会连续地向高位产生进位,最终导致 B 的最高位 01 进位为 10 ;
注意,二进制形式中,能够“连续向高位产生进位”的情况只有一种,即 xxxxxxx 全部都是 1 ,也就是说 B 的全部是 1 ;
由此,基于第2点,A 和 B 的每一位都不同,那么 A 除了最高位 1 之外,所有低位都是 0 ;
由此证得命题!
判断一个正整数是否是2的N次方的简洁算法及其证明的更多相关文章
- 判断一个整数是否是2的n次方
参考:http://bbs.csdn.net/topics/370058619 如题,如何判断一个整数是否是2的N次方,我能想到的方法有两个 1.一直除2,看最后是否等于1.(最笨的方法) 2.转换成 ...
- 『转载』判断一个正整数是不是素数,时间复杂度为O(根号n)
原文链接:https://blog.csdn.net/liangdagongjue/article/details/77895170#commentsedit PS:新手上路,实在找不到怎么转载,所以 ...
- 009 Palindrome Number 判断一个正整数是否是回文数
详见:https://leetcode.com/problems/palindrome-number/description/ 实现语言:Java 方法一: class Solution { publ ...
- 几种判断一个整数是否是2的n次方幂的方法
1:简单除法 int i = 128: //待判断的整数 int count = 1: //待判断的整数是2的count次方while (i){if (2 == i){printf("Y ...
- C语言:判断t所指字符串中的字母是否由连续递增字母组成。-判断一个输入的任何整数n,是否等于某个连续正整数序列之和。-将一副扑克牌编号为1到54,以某种方式洗牌,这种方式是将这副牌分成两半,然后将他们交叉,并始终保持编号1的牌在最上方。
//判断t所指字符串中的字母是否由连续递增字母组成. #include <stdio.h> #include <string.h> void NONO(); int fun( ...
- 【C语言】输入一个正整数,判断其是否为素数
素数的定义: 素数(prime number)又称质数,有无限个. 素数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数,这样的数称为素数.代码1: #include<stdio.h& ...
- 任意给定一个正整数N,求一个最小的正整数M(M>1),使得N*M的十进制表示形式里只含有1和0。
题目:任意给定一个正整数N,求一个最小的正整数M(M>1),使得N*M的十进制表示形式里只含有1和0. 解法一:暴力求解.从1开始查找M,然后判断M*N=X这个数字是否只含有0,1. 解法二:由 ...
- Js判断一个字符串是否包含一个子串
Js中经常遇到判断一个字符串是否包含一个子串,java语言中有containes的方法,直接调用就可以了.除非引用第三方数据库,Js中没有contains方法. 为了实现更java语言中contain ...
- python 判断一个字符串是否是小数
"""练习判断一个小数1.判断是否合法2.合法需要有一个小数点3.小数点左边必须是个整数,右边必须是个正整数 """ def xiaoshu ...
随机推荐
- Ubuntu下用matplotlib作图时显示中文
之前在Ubuntu下用matplotlib作图的时候发现无法正常显示中文,查了一番以后发现是Ubuntu系统和matplotlib库没有共同可显示的中文字体库的原因.用此文章的方法可以解决这一问题. ...
- mongodb的一些性能管理工具
1.db.serverStatus()//查看实例运行状态,例如查看当前的连接数之类的 2. mms云平台 //由10gen提供的云管理平台//mms=mongo manage service htt ...
- js获取iframe里面的元素
直接获取不行 var win2 = document.querySelector('iframe[width = "1280" ]').contentWindow; var lo ...
- MySQL------如何关闭打开MySQL
1.win+R打开运行窗口,输入services.msc 2.在其中查看mysql的服务名,我的是MySQL57 3.以管理员身份打开cmd 停止: 输入net stop MySQL57 启动: 输入 ...
- JAXB XML到java object的转换
JAXB是Java Architecture for XML Binding的缩写.使用JAXB注解将Java对象转换成XML文件.在这篇教程中,我们将会展示如何使用JAXB来做以下事情: 1. ma ...
- 【RF库Collections测试】lists should be equal
场景一:msg=None 场景二:自定义msg 场景三:自定义msg和values,且values为布尔类型False或者字符串False和No Values 场景四:自定义msg和values,且v ...
- 【RF库XML测试】Element Attribute Should Be
Name:Element Attribute Should BeSource:XML <test library>Arguments:[ source | name | expected ...
- mybatis 之 resultType="Integer"
public class EcPromoteRuleAdditionalNew extends BaseBO { private String[] promoteRuleIds; public Str ...
- AngularJs HTML DOM、AngularJS 事件以及模块的学习(5)
今天的基础就到了操作DOM,事件和模块的学习,其实我个人感觉学习起来AngularJS并没有想象中的那么的艰难,可能是因为这个太基础化吧,但是我们从初学开始就应该更加的自信一些,后来我可能会写一个小的 ...
- PyQt4程序图标
程序图标就是一个小图片,通常显示在程序图标的左上角(ubuntu gnome在最上侧). #!/usr/bin/python # -*- coding:utf-8 -*- import sys fro ...