国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C > 正文

C語言判斷一個數是否是2的冪次方或4的冪次方

2020-01-26 14:34:04
字體:
來源:轉載
供稿:網友

快速判斷一個數是否是2的冪次方,若是,并判斷出來是多少次方!
將2的冪次方寫成二進制形式后,很容易就會發現有一個特點:二進制中只有一個1,并且1后面跟了n個0; 因此問題可以轉化為判斷1后面是否跟了n個0就可以了。

如果將這個數減去1后會發現,僅有的那個1會變為0,而原來的那n個0會變為1;因此將原來的數與去減去1后的數字進行與運算后會發現為零。

最快速的方法:

   (number & number - 1) == 0

原因:因為2的N次方換算是二進制為10……0這樣的形式(0除外)。與上自己-1的位數,這們得到結果為0。例如。8的二進制為1000;8-1=7,7的二進制為111。兩者相與的結果為0。計算如下:

     1000   & 0111    -------    0000

使用遞歸來實現的代碼如下:

#include "stdio.h" #include "stdlib.h"  int log2(int value)  //遞歸判斷一個數是2的多少次方 {   if (value == 1)     return 0;   else     return 1+log2(value>>1); }  int main(void) {   int num;   printf("請輸入一個整數:");   scanf("%d",&num);   if(num&(num-1)) //使用與運算判斷一個數是否是2的冪次方     printf("%d不是2的冪次方!/n",num);   else     printf("%d是2的%d次方!/n",num,log2(num));   system("pause");   return 0; } 

使用非遞歸來實現的代碼如下:

#include "stdio.h" #include "stdlib.h"  int log2(int value)  //非遞歸判斷一個數是2的多少次方 {   int x=0;   while(value>1)   {     value>>=1;     x++;   }   return x; }  int main(void) {   int num;   printf("請輸入一個整數:");   scanf("%d",&num);   if(num&(num-1))   //使用與運算判斷一個數是否是2的冪次方     printf("%d不是2的冪次方!/n",num);   else     printf("%d是2的%d次方!/n",num,log2(num));   system("pause");   return 0; } 

擴展:求一個數n的二進制中1的個數。
非常巧妙地利用了一個性質,n=n&(n-1) 能移除掉n的二進制中最右邊的1的性質,循環移除,直到將1全部移除,這種方法將問題的復雜度降低到只和1的個數有關系。代碼如下:

int Func3(int data) {  //利用了data&(data-1)每次都能移除最右邊的1,移除了多少個1,就是包含了幾個1   int count = 0;   while (data)   {     data = data & (data-1);     count++;   }   return count; } 

擴展問題二:

A和B的二進制中有多少位不相同。這個問題可以分為兩步,(1)將A和B異或得到C,即C=A^B,(2)計算C的二進制中有多少個1。


快速判斷一個數是否是4的冪次方,若是,并判斷出來是多少次方!
將4的冪次方寫成二進制形式后,很容易就會發現有一個特點:二進制中只有一個1(1在奇數位置),并且1后面跟了偶數個0; 因此問題可以轉化為判斷1后面是否跟了偶數個0就可以了。

4的整數次冪的二進制數都為 (4)100、(16)10000、(64)1000000......

另外,4的冪次方4^n也可以寫為2^(2*n),即也可以寫為2的冪次方,當然就滿足2的冪次方的條件了,即num & num-1==0。

思路:首先用條件num & num-1==0來判斷是否為2的冪次方,若不滿足,則不是。若滿足,在用條件num & 0x55555555來判斷,若為真,則這個整數是4的冪次方,否則不是。

使用遞歸來實現的代碼如下:

#include "stdio.h" #include "stdlib.h"  bool fn(unsigned int x)   //判斷x是否是4的冪次方 {  if ( x & (x - 1) )     //判斷x是否為2的冪次方    return false;  return x & 0x55555555;   //判斷1是否在奇數位置上 }  int log4(int value)   //遞歸判斷一個數是4的多少次方 {   if (value == 1)     return 0;   else   {     value>>=1;    //往右移位     return 1+log4(value>>1);    //往右移位   } }  int main(void) {   int num;   printf("請輸入一個整數:");   scanf("%d",&num);   if(fn(num))   //使用與運算判斷一個數是否是2的冪次方     printf("%d是4的%d次方!/n",num,log4(num));   else     printf("%d不是4的冪次方!/n",num);   system("pause");   return 0; } 

使用非遞歸來實現的代碼如下:

#include "stdio.h" #include "stdlib.h"  bool fn(unsigned int x)   //判斷x是否是4的冪次方 {  if ( x & (x - 1) )     //判斷x是否為2的冪次方    return false;  return x & 0x55555555;   //判斷1是否在奇數位置上 }  int log4(int value)  //非遞歸判斷一個數是4的多少次方   {   int x=0;   while(value>1)   {     value>>=1;   //往右移位     value>>=1;     x++;   }   return x; }   int main(void) {   int num;   printf("請輸入一個整數:");   scanf("%d",&num);   if(fn(num))   //使用與運算判斷一個數是否是2的冪次方     printf("%d是4的%d次方!/n",num,log4(num));   else     printf("%d不是4的冪次方!/n",num);   system("pause");   return 0; } 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 阜阳市| 锦州市| 文化| 朝阳市| 龙井市| 孟连| 双鸭山市| 麻栗坡县| 襄垣县| 丹阳市| 黑河市| 长葛市| 冷水江市| 旺苍县| 新蔡县| 安康市| 鹿邑县| 静海县| 西安市| 当阳市| 柳林县| 定远县| 洛宁县| 合水县| 奉新县| 仁布县| 商河县| 交城县| 瓦房店市| 滦平县| 张家港市| 四会市| 泾阳县| 乳山市| 新化县| 来凤县| 莲花县| 渝北区| 来凤县| 繁昌县| 旌德县|