?1.1.1 按位與運算替代求余運算優化場景

在計算機編程中,使用按位與運算(&)替代求余運算(%)可以提高效率的特殊場景是:當除數是 2 的整數次冪(即 ( b = 2^n ),其中 ( n ) 為自然數)時。例如,( b = 2, 4, 8, 16, 32, 64 ) 等。此時,求余運算 ( a % b ) 可以等價轉換為按位與運算 ( a & (b - 1) )。下面我將詳細解釋原理、運算過程、效率優勢及適用場景。

為什么這種等價成立?

● 數學原理:當 ( b = 2^n ) 時,求余運算 ( a % b ) 的本質是獲取 ( a ) 的二進制表示中的最低 ( n ) 位。因為:
○ ( b = 2n ) 的二進制形式是 1 后跟 ( n ) 個 0(例如,( 16 = 24 ) 的二進制是 10000)。
○ ( a ) 除以 ( b ) 時,高位的值被 ( b ) 整除,余數只取決于最低 ( n ) 位。
● 位運算原理:
○ ( b - 1 ) 的二進制形式是 ( n ) 個 1(例如,( 16 - 1 = 15 ) 的二進制是 01111)。
○ 按位與運算 ( a & (b - 1) ) 會保留 ( a ) 的最低 ( n ) 位,而將高位清零,這正好等于余數。
● 公式:
[
a % (2n) = a & (2n - 1)
]

詳細運算過程(以 ( a = 23 ), ( b = 16 ) 為例)

  1. 求余運算 ( 23 % 16 ):
    ○ ( 23 ) 的二進制:10111(假設 5 位表示)。
    ○ ( 16 ) 是 ( 2^4 ),所以求余是取最低 4 位。
    ○ 計算:( 23 \div 16 = 1 ) 余 ( 7 )(因為 ( 16 \times 1 = 16 ), ( 23 - 16 = 7 ))。
    ○ 結果:( 7 )。
  2. 按位與運算 ( 23 & (16 - 1) = 23 & 15 ):
    ○ ( 23 ) 的二進制:10111。
    ○ ( 15 ) 的二進制:01111(( 16 - 1 = 15 ),即 4 個 1)。
    ○ 按位與操作(逐位比較,同 1 則 1,否則 0):
    23: 1 0 1 1 1
    & 15: 0 1 1 1 1

   0 0 1 1 1   → 二進制 `00111` = 十進制 7

○ 結果:( 7 ),與 ( 23 % 16 ) 相同。
關鍵點:
● 最低 4 位(0111)被保留,高位(10)被清零。
● 這等價于取 ( a ) 的二進制表示中的最低 ( n ) 位(這里 ( n = 4 ))。

為什么能提高效率?

  1. 硬件操作差異:
    ○ 求余運算 %:通常由 CPU 的除法指令實現,涉及多步計算(如減法、移位),開銷較大(可能需要數十個時鐘周期)。
    ○ 按位與運算 &:是 CPU 的單一指令,直接在位級別操作,通常只需 1 個時鐘周期,速度極快。
  2. 優化效果:當 ( b ) 是 2 的次冪時,& 比 % 快 10 倍以上(具體取決于架構),尤其在循環或高頻調用場景中(如哈希計算、位處理)。
    適用場景舉例
  3. 哈希表桶索引計算:
    ○ 如果桶大小 ( \text{size} = 2^n )(如 32、64),計算索引:index = hash % size → index = hash & (size - 1)。
    ○ 例如:hash = 123, size = 32(( 2^5 )),則 123 % 32 = 27 等價于 123 & 31 = 27。
  4. 位掩碼提取:
    ○ 提取顏色值(如 RGB 中的低 8 位):blue = color & 0xFF(等價于 color % 256)。
    ○ 檢查奇偶性:a % 2 → a & 1(因為 ( 2 = 2^1 ),b - 1 = 1)。
  5. 環形緩沖區或循環隊列:
    ○ 當緩沖區大小為 2 的次冪時,索引回繞:next_index = (current + 1) % buffer_size → next_index = (current + 1) & (buffer_size - 1)。

注意事項

● 嚴格條件:僅當 ( b = 2^n ) 時成立!如果 ( b ) 不是 2 的次冪(如 ( b = 10 )),則不能直接用 & 替代(需其他方法,如查表或乘法)。
● 負數處理:在編程語言中,% 和 & 對負數的行為可能不同(如 -7 % 16 可能為 -7 或 9,取決于語言)。建議先確保 ( a ) 為非負數,或使用位掩碼強制轉換。
● 編譯器優化:現代編譯器(如 GCC、Clang)在 b 為常量 2 的次冪時,可能自動將 % 轉換為 &,但顯式使用可確保優化。
總結
● 場景:當除數是 ( 2^n ) 時,用 ( a & (b - 1) ) 替代 ( a % b )。
● 原因:位運算直接提取二進制低位,避免昂貴的除法。
● 效率:& 是 O(1) 操作,遠快于 % 的 O(log a) 復雜度。
通過這種優化,可以在底層系統編程、游戲開發、嵌入式系統等對性能敏感的領域顯著提升速度。

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

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

相關文章

CentOS 7 環境中部署 LNMP(Linux + Nginx + MySQL 5.7 + PHP)

在 CentOS 7 環境中部署 LNMP(Linux Nginx MySQL 5.7 PHP) 環境的詳細步驟如下。此方案確保各組件版本兼容,并提供完整的配置驗證流程。 1. 更新系統 sudo yum update -y 2. 安裝 MySQL 5.7 2.1 添加 MySQL 官方 YUM 倉庫 由于MySQL并不…

UniApp微信小程序自定義導航欄實現

UniApp微信小程序自定義導航欄 在UniApp開發微信小程序時,頁面左上角默認有一個返回按鈕(在導航欄左側),但有時我們需要自定義這個按鈕的樣式和功能,同時保持與導航欄中間的標題和右側膠囊按鈕(藥丸屏&…

Java大師成長計劃之第35天:未來展望與個人總結

引言 作為一門歷史悠久的編程語言,Java自1995年問世以來,經歷了多個版本的迭代與演進,依然在當今技術生態中占據著重要地位。從早期的Java SE、Java EE到后來的Java Spring框架,再到現代的微服務架構與云原生應用,Jav…

Ubuntu開機自動運行Docker容器中的Qt UI程序

Ubuntu開機自動運行Docker容器中的Qt UI程序 引言為什么需要這樣配置?解決方案概覽詳細實現步驟1. 創建容器啟動腳本2. 創建系統服務3. 配置自動登錄和顯示設置常見問題解決方案1. 程序無法顯示(X11權限問題)2. 分辨率設置不生效3. 服務啟動失敗安全注意事項結語附錄:完整文…

Scratch節日 | 龍舟比賽 | 端午節

端午節快樂! 這款專為孩子們打造的Scratch游戲——《龍舟比賽》,讓你在掌控龍舟的競速中,沉浸式體驗中華傳統節日的魅力! 🎮 游戲亮點 節日氛圍濃厚:化身龍舟選手,在波濤洶涌的河流中展開刺激競…

(五)MMA(OpenTelemetry/Rabbit MQ/ApiGateway/MongoDB)

文章目錄 項目地址一、OpenTelemetry1.1 配置OpenTelemetry1. 服務添加2. 添加服務標識3. 添加請求的標識4. 添加中間價 二、Rabbit MQ2.1 配置Rabbit MQ1. docker-compose2. 添加Rabbit MQ的Connect String 2.2 替換成Rabbit MQ1. 安裝所需要的包2. 使用 三、API Gateways3.1 …

格恩朗超聲波水表 助力農業精準灌溉與振興?

在農業現代化的征程中,水資源的精準利用至關重要,而這離不開高精度計量設備的支持。大連格恩朗品牌積極響應國家全面推進鄉村振興、加快農業農村現代化的號召,精心打造的超聲波水表,憑借其超高精度,成為綠色灌溉領域的…

微信小程序頁面嵌套web-view點擊系統導航返回時進行彈窗處理

實現效果:微信小程序頁面嵌套web-view點擊系統導航返回時進行彈窗處理 首先在web-view里是不可實現的(據我了解下來) 參考小程序文檔:page-container 大致邏輯: 1、page-container可實現頁面離開前攔截 2、由于web-vie…

設計模式25——中介者模式

寫文章的初心主要是用來幫助自己快速的回憶這個模式該怎么用,主要是下面的UML圖可以起到大作用,在你學習過一遍以后可能會遺忘,忘記了不要緊,只要看一眼UML圖就能想起來了。同時也請大家多多指教。 中介者模式(Mediat…

Java基礎 Day25

一、線程通信 1、簡介 確保線程能夠按照預定的順序執行并且能夠安全地訪問共享資源 使多條線程更好的進行協同工作 2、常用方法 void wait() 使當前線程進入等待狀態 void notify(); 隨機喚醒單個等待的線程(可以空喚醒) void notifyAll(); 喚醒…

WebSocket與實時對話式AI服務的集成

WebSocket與實時對話式AI服務的集成 在現代對話式AI系統中,傳統的HTTP請求-響應模型已難以滿足實時交互的體驗需求。特別是用戶對響應速度、逐字輸出、會話上下文保持等方面提出更高要求時,需要一種能夠建立持久連接并支持雙向通信的協議。WebSocket正是在這一背景下,成為A…

iOS 集成網易云信IM

云信官方文檔在這 看官方文檔的時候&#xff0c;版本選擇最新的V10。 1、CocoPods集成 pod NIMSDK_LITE 2、AppDelegate.m添加頭文件 #import <NIMSDK/NIMSDK.h> 3、初始化 NIMSDKOption *mrnn_option [NIMSDKOption optionWithAppKey:"6f6568e354026d2d658a…

人工智能100問?第37問:什么是擴散模型?

目錄 ??一、通俗解釋 二、專業解析?? 三、權威參考 擴散模型是一種??通過系統性地添加再去除噪聲來生成新數據(如圖像)的生成式AI技術??,其核心機制分為兩個階段:正向擴散??:對原始數據(如清晰圖片)逐步添加噪聲,直至完全變成隨機噪點(類似老照片逐漸模糊…

傳輸層核心技術解析

目錄 一、端口號機制 二、網絡診斷工具 1. netstat命令 2. pidof工具 三、UDP協議詳解 協議特征 典型應用場景 四、TCP協議深度解析 核心機制 狀態轉換模型 特殊狀態說明 五、協議對比分析 六、開發實踐要點 一、端口號機制 核心作用&#xff1a;標識主機唯一進程…

IO Vs NIO

一、IO(傳統阻塞式) 全稱?&#xff1a;Input/Output(輸入/輸出) 定義?&#xff1a;Java 1.0 引入的基礎 I/O 模型&#xff0c;基于流&#xff08;Stream&#xff09;的同步阻塞操作&#xff0c;線程在讀寫數據時會阻塞直到操作完成。 二、NIO(新式非阻塞式) ?全…

基于原生JavaScript前端和 Flask 后端的Todo 應用

Demo地址&#xff1a;https://gitcode.com/rmbnetlife/todo-app-js-flask.git Python Todo 應用 這是一個使用Python Flask框架開發的簡單待辦事項(Todo)應用&#xff0c;采用前后端分離架構。本項目實現了待辦事項的添加、刪除、狀態切換等基本功能&#xff0c;并提供了直觀…

005 ElasticSearch 許可證過期問題

ElasticSearch 許可證過期問題 項目啟動報錯 org.elasticsearch.client.ResponseException: method [GET], host [http://127.0.0.1:9200], URI [/_cluster/health/], status line [HTTP/1.1 403 Forbidden] {"error":{"root_cause":[{"type":…

哪些崗位最易被AI替代?

隨著AI技術高速演進&#xff0c;一場“職場大洗牌”正悄然上演。當ChatGPT出口成章、機器人能精準執勤&#xff0c;AI時代的“就業焦慮”已不再是空談。你是否認真思考過&#xff0c;自己所處的崗位是否也正面臨被AI邊緣化的風險&#xff1f; 以下幾類職業&#xff0c;已成為AI…

信號槽中 sender() 的作用

好的,sender() 是 Qt 框架中的一個重要函數,它用于獲取觸發當前槽函數的對象。在 Qt 的信號和槽機制中,一個信號可以連接到多個槽函數,而一個槽函數也可以被多個信號觸發。sender() 函數允許你在槽函數中確定是哪個對象觸發了當前信號。 信號和槽機制 在 Qt 中,信號和槽…

深度學習|pytorch基本運算

【1】引言 pytorch是深度學習常用的包&#xff0c;顧名思義&#xff0c;就是python適用的torch包&#xff0c;在python里面使用時直接import torch就可以調用。 需要注意的是&#xff0c;pytorch包與電腦配置、python版本有很大關系&#xff0c;一定要仔細閱讀安裝要求、找到…