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 ;

    由此证得命题!

  • 相关阅读:
    哈夫曼(Huffman)编码
    面向对象的3个基本要素和5个基本设计原则(整理)
    面向对象设计原则OO
    Java多线程中start()和run()的区别
    HBase入门
    SparkGraphXTest.scala
    IntellijIdea中常用的快捷键
    SparkSQLTest.scala
    SparkStreamingTest.scala
    (转)理解POST和PUT的区别,顺便提下RESTful
  • 原文地址:https://www.cnblogs.com/haiq/p/4550716.html
Copyright © 2011-2022 走看看