ARTS 挑戰打卡的第9天 --- 如何知道一個數是否為2的若干次冪(Algorithm)

前言

(1)今天看到一個有意思的問題,如何判斷一個數字是否為2的若干次冪。這個問題并不難,但是對于我們的C語言功底還是有一點點的考驗的。
(2)希望各位可以先自行思考,實在想不出來再看后面的講解。提示,C語言的位運算是一個好東西。

解析

2的若干次冪數所存在的特征點

(1)首先,我們需要知道2的若干次冪所存在的特征點。當我們知道了這個特征點之后,就可以將這個特征點與其他數進行分離了。
(2)我們都知道,計算機是2進制系統。如果讓一個數字乘以2,我們是不是可理解為,讓這個二進制數右移動一位呢?

在這里插入圖片描述

(3)既然我們知道了,在計算機中乘以2就是進行一次右移操作。那么2的n次冪,是不是就是二進制數1進行右移n次呢?例如,數字2換成二進制是10,而十進制的數字2恰好就是2的1次冪,因而二進制的1進行一次右移操作。
(4)好,我們再進行擴展,既然2的n次冪就是數字1進行右移n次。那么2的n次冪在二進制中是不是有一個特點,那就是只有一個位為1!(不理解的同學可以看一下下面這幾個例子,我們發現2的n次冪的數8和4只有一個位為1)

在這里插入圖片描述

如何提取這個特征點

(1)現在我們知道了2的若干次冪在二進制中,只會有一個位是1,其他位是數字0。因此,我們是不是得想個辦法,判斷一個二進制數只存在一個1。
(2)于是,我們可以想到"&"運算。他的特點在于,有0出0。假設我們的二進制數是100,那么讓100減去1變成011。這樣原來那個存放唯一數字1的地方就會變成0了。
(3)然后100&011,就會變成0。最后邏輯取反即可。

!((x)&(x-1))

在這里插入圖片描述

(4)但是肯定有朋友會想舉其他例子嘗試反駁,很不幸的是你找不到的。
(5)為什么這么說呢?因為,我們要抓住這個方法的巧妙之處,我們是將唯一的存放1的位變成0。
(6)但是,我們假設有一個可以反駁的數1010。(注意,這里是假設)1010-1=1001,有沒有發現一個問題,這里的最高位的數字1永遠無法被消除。因此,進行如上操作之后,最終還是可以分辨出這不是2的n次冪。

上述代碼存在bug?

bug1 — 不承認1為2的若干次冪

(1)看到上述代碼,有一些東西肯定想到了一個刁鉆的角度。數字1經過上述代碼,最終輸出的也是1啊。所以你這個代碼有問題!這個時候我建議還是重新學一下小學數學啊(苦笑)。1就是2的0次冪呀
(2)但是有一些朋友就是不承認1怎么辦呢?也很簡單,判斷這個數是不是1唄。

x == 1 ? 0 : !((x)&(x-1))

bug2 — 數字0所導致的問題

(1)數字1導致的問題解決了,我們角度再刁鉆一點,假設這個數字是0呢?真的可以嗎?
(2)我們在Linux中執行如下代碼。

#include <stdio.h>
#include <stdlib.h>#define if_2_equation(x)  !((x)&(x-1))int main(int argc,char** argv)
{char i;//如果輸入參數小于2個,打印本程序使用方法if(argc < 2){printf("Usage: \r\n");printf("%s <string> \r\n",argv[0]);return -1;}i = strtol(argv[1], NULL, 0);printf("number = %d \r\n",i);if(if_2_equation(i)){printf("yes\r\n");}else{printf("no\r\n");}return 0;
}

在這里插入圖片描述

(3)執行發現,數字0也被當成了2的若干次冪,這個從數學的角度上來看,怎么也說不清楚啊。為什么會發生這種情況呢?很簡單,0&所有的數,都是0。因此,這里就存在bug。
(4)怎么處理呢?很簡單,進行一次判斷唄。

#define if_2_equation(x)  x == 0 ? 0 : !((x)&(x-1))

(5)但是有些騷年會想,我1和0這兩個數都不打算當成2的若干次冪來判斷,這個怎么處理呢?也很簡單,進行兩次判斷唄。

#define if_2_equation(x)  x == 0 ? 0 : (x == 1 ? 0 : !((x)&(x-1)))

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/37147.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/37147.shtml
英文地址,請注明出處:http://en.pswp.cn/news/37147.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【es6】具名組匹配

1、組匹配 正則表達式使用圓括號進行組匹配&#xff0c;如&#xff1a;const RE_DATE /(\d{4})-(\d{2})-(\d{2})/;,三個圓括號形成了三個組匹配。 代碼&#xff1a; const RE_DATE /(\d{4})-(\d{2})-(\d{2})/;const matchObj RE_DATE.exec(1999-12-31); const year matchO…

rabbitmq的消息應答

消費者完成一個任務可能需要一段時間&#xff0c;如果其中一個消費者處理一個長的任務并僅只完成 了部分突然它掛掉了&#xff0c;會發生什么情況。RabbitMQ 一旦向消費者傳遞了一條消息&#xff0c;便立即將該消 息標記為刪除。在這種情況下&#xff0c;突然有個消費者掛掉了…

數據分析兩件套ClickHouse+Metabase(一)

ClickHouse篇 安裝ClickHouse ClickHouse有中文文檔, 安裝簡單 -> 文檔 官方提供了四種包的安裝方式, deb/rpm/tgz/docker, 自行選擇適合自己操作系統的安裝方式 這里我們選deb的方式, 其他方式看文檔 sudo apt-get install -y apt-transport-https ca-certificates dirm…

魔改 axuanup 的 aardio和python 猜拳游戲 代碼

根據 axuanup 的 aardio和python 猜拳游戲 代碼&#xff0c;魔改了一個風格不一樣的代碼。 爭取做到代碼盡量“簡”&#xff0c;但還沒到“變態簡”的程度&#xff0c;因為還能看懂。 原文&#xff1a;aardio和python 猜拳游戲-自由交流樂園-Aardio資源網 代碼如下&#xff…

【Flutter】【基礎】CustomPaint 繪畫功能(一)

功能&#xff1a;CustomPaint 相當于在一個畫布上面畫畫&#xff0c;可以自己繪制不同的顏色形狀等 在各種widget 或者是插件不能滿足到需求的時候&#xff0c;可以自己定義一些形狀 使用實例和代碼&#xff1a; CustomPaint&#xff1a; 能使你繪制的東西顯示在你的ui 上面&a…

競賽項目 酒店評價的情感傾向分析

前言 &#x1f525; 優質競賽項目系列&#xff0c;今天要分享的是 酒店評價的情感傾向分析 該項目較為新穎&#xff0c;適合作為競賽課題方向&#xff0c;學長非常推薦&#xff01; &#x1f9ff; 更多資料, 項目分享&#xff1a; https://gitee.com/dancheng-senior/post…

解決QTabelView無法立即刷新問題

解決QTabelView無法理解刷新問題 在某些時候&#xff0c;Qt的奇葩現象&#xff0c;調試中QTabelView的相關model數據變更了&#xff0c;界面卻沒立即刷新&#xff0c;然而&#xff0c;點擊標題欄等才刷新&#xff0c;奇葩。很多網上資料說QTabelView::update()和QTabelView::r…

用Python做一個滑雪小游戲

游戲是讓人娛樂和放松的好方式&#xff0c;而編寫和玩自己的游戲則是一種特別有趣的體驗。在本文中&#xff0c;我們將使用Python和pygame庫來創建一個簡單的滑雪小游戲。通過這個小游戲項目&#xff0c;我們將學習如何使用Python編程語言來制作自己的游戲&#xff0c;并且享受…

IT運維:使用數據分析平臺監控深信服防火墻

概述 深信服防火墻自身監控可以滿足絕大部分需求&#xff0c;比如哪個應用占了最大帶寬&#xff0c;哪個用戶訪問了哪些網站&#xff1f;這里我們為什么使用鴻鵠呢&#xff1f;因為我們要的是數據的處理和分析&#xff0c;比如某個用戶在某個事件都做了哪些行為&#xff0c;這個…

【設計模式】前端控制器模式

前端控制器模式&#xff08;Front Controller Pattern&#xff09;是用來提供一個集中的請求處理機制&#xff0c;所有的請求都將由一個單一的處理程序處理。該處理程序可以做認證/授權/記錄日志&#xff0c;或者跟蹤請求&#xff0c;然后把請求傳給相應的處理程序。以下是這種…

基于鯤鵬平臺Ceph深度性能調優

劉亮奇 架構師技術聯盟 2021-04-12 07:50 摘自&#xff1a; https://mp.weixin.qq.com/s/o9HH-8TF0DbMqHrvsFh1NA 隨著 IOT、大數據、移動互聯等應用的暴漲&#xff0c;產生的數據也越來越多&#xff0c;整個存儲市場總量也逐年增長&#xff0c;預計到 2021 年分布式存儲會占到…

UNIX基礎知識:UNIX體系結構、登錄、文件和目錄、輸入和輸出、程序和進程、出錯處理、用戶標識、信號、時間值、系統調用和庫函數

引言&#xff1a; 所有的操作系統都為運行在其上的程序提供服務&#xff0c;比如&#xff1a;執行新程序、打開文件、讀寫文件、分配存儲區、獲得系統當前時間等等 1. UNIX體系結構 從嚴格意義上來說&#xff0c;操作系統可被定義為一種軟件&#xff0c;它控制計算機硬件資源&…

CTFshow 限時活動 紅包挑戰7、紅包挑戰8

CTFshow紅包挑戰7 寫不出來一點&#xff0c;還是等了官方wp之后才復現。 直接給了源碼 <?php highlight_file(__FILE__); error_reporting(2);extract($_GET); ini_set($name,$value);system("ls ".filter($_GET[1])."" );function filter($cmd){$cmd…

【圖像分類】理論篇(2)經典卷積神經網絡 Lenet~Densenet

1、卷積運算 在二維卷積運算中&#xff0c;卷積窗口從輸入張量的左上角開始&#xff0c;從左到右、從上到下滑動。 當卷積窗口滑動到新一個位置時&#xff0c;包含在該窗口中的部分張量與卷積核張量進行按元素相乘&#xff0c;得到的張量再求和得到一個單一的標量值&#xff0c…

Java 集合擴容概括

參考博文&#xff1a; java集合的擴容機制_這個名字先用著的博客-CSDN博客 # ArrayList 可隨著元素的增長而自動擴容&#xff0c;正常擴容的話&#xff0c;每次擴容到原來的 1.5倍。 # ArrayList 和Vector擴容機制總結&#xff1a; ArrayList 和Vector,底層都是Object數組…

SQL- 每日一題【1327. 列出指定時間段內所有的下單產品】

題目 表: Products 表: Orders 寫一個解決方案&#xff0c;要求獲取在 2020 年 2 月份下單的數量不少于 100 的產品的名字和數目。 返回結果表單的 順序無要求 。 查詢結果的格式如下。 示例 1: 解題思路 1.題目要求我們獲取在 2020 年 2 月份下單的數量不少于 100 的產品的…

如何重置樹莓派 Pico(重置外圍設備失敗)

有時候需要重置樹莓派 Pico&#xff0c;一種方法是按住 Pico 上的“BOOTSEL”按鈕再插入 USB&#xff1b;或者用按鈕連接“RUN”和“GND”針腳&#xff0c;然后同時按下這個按鈕和“BOOTSEL”按鈕。這樣就可以進入 USB 模式&#xff0c;這樣從一定程度進行了重置。 但是這種方…

IO多路復用

常見的網絡IO模型 網絡 IO 模型分為四種&#xff1a;同步阻塞 IO(Blocking IO, BIO)、同步非阻塞IO(NIO, NewIO)、IO 多路復用、異步非阻塞 IO(Async IO, AIO)&#xff0c;其中AIO為異步IO&#xff0c;其他都是同步IO 同步阻塞IO 同步阻塞IO&#xff1a;在線程處理過程中&am…

劍指Offer10-I.斐波那契數列 C++

1、題目描述 寫一個函數&#xff0c;輸入 n &#xff0c;求斐波那契&#xff08;Fibonacci&#xff09;數列的第 n 項&#xff08;即 F(N)&#xff09;。斐波那契數列的定義如下&#xff1a; F(0) 0, F(1) 1 F(N) F(N - 1) F(N - 2), 其中 N > 1. 斐波那契數列由 0 和 …