神奇的x -x,Lowbit函數的實現方式!

文章目錄

  • -x
  • x & -x,當x為偶數時
  • x & -x,當x為奇數時
  • x&-x 的實際用途


-x

-x 在二進制里表示對 x 的二進制按位取反(~x)之后再加 1 ,即

-x = ~x+1

x & -x,當x為偶數時

在執行 x & -x 時,若 x 為偶數,最后結果肯定有如下兩個特征:

  1. 這個結果只有一位值是1, 其他位均是0
  2. 這個值的末位0的個數與原值保持一致

從數學上推導,因為 偶數 的二進制末尾一定由 k0 構成,如:110(6) 100(4)。
那么對其按位取反一定得到 k1 ,當再對 ~x 進行 加一 操作后,一定能得到 1個1k個0 ,而在 1 前面的數已經全部 按位取反 ,唯有 1 后面的數經過 取反->加一進位(形同再次取反) ,變回了原來的數,但我們知道,1 后面原本就是 k個0 ,因此, 證得上述兩個特征。

用幾個實例來證明:

x = 4
x:100
~x: 011
-x=~x+1: 100
x & -x: 100x = 6
x: 110
~x: 001
-x: 010
x & -x: 010x = 10
x: 1010
~x: 0101
-x: 0110
x & -x: 0010

而這個結果有什么用呢?實際上這個結果是能整除這個偶數的最大的2的冪, 即:
m = n & -n ,則 n % m = 0 , 且 m = 2 ^ k


x & -x,當x為奇數時

x 為奇數時就比較簡單了, 因為奇數取反后的值一定是偶數, 也就是有 k個0 。對其進行 加一 操作也就是變成了 k-1個01個1 ,形如:00…001(k-1個0),不會發生進位,因此只有最后一位變成了原本的數,也就是 1 ,因此 x&-x 值為 1

用幾個實例來證明:

x = 3
x:11
~x: 00
-x=~x+1: 01
x & -x: 01x = 5
x: 101
~x: 010
-x: 011
x & -x: 001x = 11
x: 1011
~x: 0100
-x: 0101
x & -x: 0001

x&-x 的實際用途

實際上如果用過 Lowbit函數 ,那么此時已經會恍然大悟了,沒錯, x & -x 正是 Lowbit函數 的一種實現方式。

這里簡單說一下什么是 Lowbit函數 ?Lowbit函數用來返回參數轉為二進制后,最后一個1的位置所代表的數值。例如,Lowbit(34)的返回值將是2;而Lowbit(12)返回4;Lowbit(8)返回8;參數為任何奇數時返回1。

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

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

相關文章

JAVA實現把指定文件夾下的所有文件壓縮成zip包

1.代碼如下: package cn.gov.csrc.base.util;import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import…

樹狀數組的相關知識 及 求逆序對的運用

文章目錄樹狀數組概念前綴和和區間和樹狀數組原理區間和——單點更新前綴和——區間查詢完整代碼離散化sort函數unique函數去重erase函數僅保留不重復元素通過樹狀數組求逆序對樹狀數組概念 樹狀數組又名二叉索引樹,其查詢與插入的復雜度都為 O(logN),其…

二叉搜索樹相關知識及應用操作

文章目錄概念查找二叉搜索樹的第k大節點概念 二叉查找樹(Binary Search Tree),(又名:二叉搜索樹,二叉排序樹)——它或者是一棵空樹,或者是具有下列性質的二叉樹: 若它的…

二叉樹相關知識及求深度的代碼實現

文章目錄樹二叉樹滿二叉樹和完全二叉樹二叉樹的性質代碼實現求二叉樹的深度樹 樹是一種非線性的數據結構,它是由n個有限結點組成一個具有層次關系的集合。 樹的相關名詞: 根節點:沒有前驅結點的結點。父節點,子節點&#xff1a…

平衡樹相關知識及如何判斷一棵樹是否平衡

文章目錄概念代碼實現判斷一棵二叉樹是否為平衡樹概念 平衡樹(Balance Tree,BT) 指的是,任意節點的子樹的高度差都小于等于1。 常見的符合平衡樹的有: B樹(多路平衡搜索樹)AVL樹(二叉平衡搜索樹&#xf…

大端小端存儲模式詳解及判斷方法

文章目錄大小端模式的概念兩種模式出現原因兩種模式的優劣大小端的應用情景判斷機器的字節序大小端模式的概念 當我們查看數據在內存中的存儲情況時,我們經常會發現一個很奇怪的現象,什么現象呢? int main() {int i 12;return 0; }數據在內…

Linux 內存管理 | 物理內存、內存碎片、伙伴系統、SLAB分配器

文章目錄物理內存物理內存分配外部碎片內部碎片伙伴系統(buddy system)slab分配器物理內存 在Linux中,內核將物理內存劃分為三個區域。 在解釋DMA內存區域之前解釋一下什么是DMA: DMA(直接存儲器訪問) 使用物理地址訪問內存&am…

Linux 內存管理 | 虛擬內存管理:虛擬內存空間、虛擬內存分配

文章目錄虛擬地址空間用戶空間內核空間用戶空間內存分配malloc內核空間內存分配kmallocvmalloc虛擬地址空間 在早期的計算機中,程序是直接運行在物理內存上的,而直接使用物理內存,通常都會面臨以下幾種問題: 內存缺乏訪問控制&a…

Linux | 編譯原理、gcc的命令參數、自動化構建工具 make/Makefile

文章目錄編譯原理預處理編譯匯編鏈接gcc的常用命令參數make 和 Makefile 的概念make的運行通配符自動化變量偽目標.PHONE:【命令】編譯原理 在解釋 makefile 前,首先解釋一下 .c 文件變成 .exe 文件要經過的四個步驟——預處理、編譯、匯編和鏈接(參考來…

全排列變種:限定 排列的差值范圍 及 排列中的元素個數

文章目錄題目描述思路代碼實現題目描述 詳細描述:字節跳動2019春招研發部分編程題——萬萬沒想到之抓捕孔連順 輸入描述: 第一行包含空格分隔的兩個數字 N和D(1?≤?N?≤?1000000; 1?≤?D?≤?1000000) 第二行包含N個整數(取值區間為…

Linux | 進程概念、進程狀態(僵尸進程、孤兒進程、守護進程)、進程地址空間

文章目錄進程和程序操作系統如何控制和調度程序進程控制塊–PCB子進程進程狀態僵尸進程孤兒進程守護進程(精靈進程)進程地址空間引言頁表進程和程序 程序: 一系列有序的指令集合(就是我們寫的代碼)。進程:…

Linux 進程控制 :進程創建,進程終止,進程等待,程序替換

文章目錄進程創建進程等待程序替換進程終止進程創建 fork函數: 操作系統提供的創建新進程的方法,父進程通過調用 fork函數 創建一個子進程,父子進程代碼共享,數據獨有。 當調用 fork函數 時,通過 寫時拷貝技術 來拷貝…

Linux 內存管理 | 連續分配方式 和 離散分配方式

文章目錄前言連續分配單一連續分配分區式分配固定分區分配動態分區分配可重定位分區分配離散分配分段分頁多級頁表快表(TLB)段頁式Linux前言 Linux 內存管理 | 虛擬內存管理:虛擬內存空間、虛擬內存分配 Linux 內存管理 | 物理內存、內存碎片、伙伴系統、SLAB分配器…

操作系統 | 用戶態和內核態的切換(中斷、系統調用與過程(庫函數)調用)

文章目錄中斷過程調用系統調用過程調用和系統調用的區別中斷 用戶態、內核態之間的切換是怎么實現的? 用戶態→內核態 是通過中斷實現的。并且 中斷是唯一途徑 。核心態→用戶態 的切換是通過執行一個特權指令,將程序狀態字 (PSW) 的標志位設置為 用戶態 。 中斷…

管道實現父子進程的信息傳遞(二)【標準流和其文件描述符、fwrite函數、perror函數】

文章目錄代碼實現標準流 和 標準流文件描述符代碼中用到的函數fwrite()perror()在復習進程間的通信方式時又寫了一遍,和 管道實現父子進程的信息傳遞(一)【fork函數、pipe函數、write/read操作、wait函數】 的區別不是特別大,只是…

JAVA隨機生成文件名:當前年月日時分秒+五位隨機數

代碼如下: package cn.gov.csrc.util;import java.text.SimpleDateFormat; import java.util.Date; import java.util.Random;public class RandomUtil {/*** 生成隨機文件名:當前年月日時分秒五位隨機數* * return*/public static String getRandomFile…

命名管道實現進程的信息傳遞【mkfifo函數、open函數】

文章目錄代碼實現mkfifo函數open函數代碼實現 #include<fcntl.h> // open() #include<sys/wait.h> // wait() #include<sys/types.h> // mkfifo() #include<sys/stat.h> // mkfifo() #include<iostream> #include<unistd.h> // fork()usi…

Linux 進程 | 進程間的通信方式

文章目錄管道匿名管道 pipe命名管道 FIFO共享內存共享內存的使用流程&#xff1a;消息隊列信號量套接字在之前的博客中講過&#xff0c;虛擬空間出現的其中一個目的就是解決 進程沒有獨立性&#xff0c;可能訪問同一塊物理內存 的問題。因為這種獨立性&#xff0c;進程之間無法…

Linux網絡編程 | socket介紹、網絡字節序與主機字節序概念與兩者的轉換、TCP/UDP 連接中常用的 socket 接口

文章目錄套接字socket 地址通用 socket 地址專用 socket 地址網絡字節序與主機字節序地址轉換TCP/UDP 連接中常用的 socket 接口套接字 什么是套接字&#xff1f; 所謂 套接字 (Socket) &#xff0c;就是對網絡中 不同主機 上的應用進程之間進行雙向通信的端點的抽象。 UNIX/L…

網絡協議分析 | 傳輸層 :史上最全UDP、TCP協議詳解,一篇通~

文章目錄UDP概念格式UDP如何實現可靠傳輸基于UDP的應用層知名協議TCP概念格式保證TCP可靠性的八種機制確認應答、延時應答與捎帶應答超時重傳滑動窗口滑動窗口協議后退n協議選擇重傳協議流量控制擁塞控制發送窗口、接收窗口、擁塞窗口快速重傳和快速恢復連接管理機制三次握手連…