zoukankan      html  css  js  c++  java
  • 判断一个正整数是否是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 ;

    由此证得命题!

  • 相关阅读:
    训练总结
    图论--最短路--SPFA模板(能过题,真没错的模板)
    图论--最短路-- Dijkstra模板(目前见到的最好用的)
    The 2019 Asia Nanchang First Round Online Programming Contest B Fire-Fighting Hero(阅读理解)
    关于RMQ问题的四种解法
    The Preliminary Contest for ICPC Asia Xuzhou 2019 徐州网络赛 K题 center
    The Preliminary Contest for ICPC Asia Xuzhou 2019 徐州网络赛 XKC's basketball team
    The Preliminary Contest for ICPC Asia Xuzhou 2019 徐州网络赛 D Carneginon
    ZOJ 3607 Lazier Salesgirl (枚举)
    ZOJ 3605 Find the Marble(dp)
  • 原文地址:https://www.cnblogs.com/haiq/p/4550716.html
Copyright © 2011-2022 走看看