国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

你不知道的按位運算

luoyibu / 1184人閱讀

摘要:相信大家都知道二進制數(shù)按位運算的規(guī)則來看一些簡單的例子單純的二進制位之間的這些運算相當(dāng)簡單,但對我們實際編程并沒有直接幫助,因為編程過程中需要的經(jīng)常是數(shù)字間的運算,比如。

先來看LeetCode上的Divide Two Integers題目要求:

Divide two integers without using multiplication, division and mod operator.

就是說不用乘法,除法,求模運算來實現(xiàn)兩個整數(shù)相除,看起來很簡單,我可以用除數(shù)減去被除數(shù),直到除數(shù)小于被除數(shù),記錄減法操作的次數(shù)即可。假設(shè)是計算m/n,那么時間復(fù)雜度為O(m/n)。用Python實現(xiàn)后,Time Limit Exceeded。我們考慮有沒有更加優(yōu)化的算法呢?

如果很難想得到,那就先來回憶下二進制數(shù)按位運算的一些知識。

二進制數(shù)按位運算

計算機里面所有數(shù)據(jù)都存儲為0,1串,所有的運算歸根到底都轉(zhuǎn)為二進制數(shù)的運算。相信大家都知道二進制數(shù)按位運算的規(guī)則:

來看一些簡單的例子:

1010 & 1100 = 1000
1010 | 1100 = 1110
1010 ^ 1100 = 0110
1010 << 2   = 101000
1010 >> 2   = 10
~1010       = 0101

單純的二進制位之間的這些運算相當(dāng)簡單,但對我們實際編程并沒有直接幫助,因為編程過程中需要的經(jīng)常是數(shù)字間的運算,比如 5*(2^4) 。真的是這樣嗎?接著往下看!

計算機中數(shù)字的存儲方式

我們都知道計算機中萬物皆為0、1,將萬物變?yōu)?、1的過程叫做編碼,這里我們只討論將數(shù)字編碼為0、1的過程。

計算機中對數(shù)字的表示有三種方式:原碼,反碼,補碼:

原碼表示法在數(shù)值前面增加了一位符號位(即最高位為符號位):正數(shù)該位為0,負(fù)數(shù)該位為1。比如十進制3如果用8個二進制位來表示就是 00000011, -3就是 10000011。

反碼表示方法:正數(shù)的反碼是其本身;負(fù)數(shù)的反碼是在其原碼的基礎(chǔ)上,符號位不變,其余各個位取反。

補碼表示方法:正數(shù)的補碼是其本身;負(fù)數(shù)的補碼是在其原碼的基礎(chǔ)上,符號位不變,其余各位取反,最后+1。 (即在反碼的基礎(chǔ)上+1)

原碼容易被人腦直接識別并用于計算,但是對于計算機來說并不友好。所以在計算機系統(tǒng)中,數(shù)值一律用補碼來表示、運算和存儲。使用補碼,可以將符號位和數(shù)值域統(tǒng)一處理,將加法和減法統(tǒng)一處理。此外,補碼與原碼相互轉(zhuǎn)換,其運算過程是相同的,不需要額外的硬件電路。詳細(xì)的解釋可以參考原碼, 反碼, 補碼詳解。

數(shù)字的按位運算

計算機中數(shù)字存儲為補碼形式,各個數(shù)之間的運算也是對它們的補碼做運算,而且得到的結(jié)果也是補碼,如下圖:

各種編程語言都提供了對補碼的二進制位直接進行運算的方法。以Python為例:

>>> 0b1010 & 0b1100
8   #1000
>>> 0b1010 | 0b1100
14  #1110
>>> 0b1010 ^ 0b1100
6   #0110
>>> 0b1010 << 2
40  #101000
>>> 0b1010 >> 2
2   #10
>>> ~0b1010
-11 #10000000 00000000 00000000 00001011
>>> type(0b1010)

上面0b開頭的0、1串表示整型數(shù)字,在32位操作系統(tǒng)中,Python中int類型一般占32個二進制位,以最后一個求反運算為例子,1010的補碼為

00000000 00000000 00000000 00001010

求反操作后為:

11111111 11111111 11111111 11110101

即為-11(原碼為:10000000 00000000 00000000 00001011)的補碼。(對一個數(shù)的補碼求補碼即可得到該數(shù)的原碼)

另辟蹊徑的按位運算

那么按位運算在實際編程中可以扮演哪些角色呢?簡單點地,可以用來判斷奇、偶數(shù):num & 0x1,或者對一個數(shù)變換符號:~num + 1;復(fù)雜點的可以用來交換兩個數(shù),求絕對值等等。

> 不用額外的變量實現(xiàn)兩個數(shù)字互換。

def swap(num_1, num_2):
    num_1 ^= num_2
    num_2 ^= num_1
    num_1 ^= num_2
    return num_1, num_2

證明很簡單,我們只需要明白異或運算滿足下面規(guī)律:

0^a = a;

a^a = 0;

a^b^c = a^c^b;

巧妙運用異或可以高效解決很多問題,比如 找出數(shù)組中只出現(xiàn)了一次的數(shù)(除了一個數(shù)只出現(xiàn)一次外,其他數(shù)都是出現(xiàn)兩次),以及它的升級版:數(shù)組中只出現(xiàn)1次的兩個數(shù)字(百度面試題)。

> 不用判斷語句來實現(xiàn)求絕對值。

def bit_abs(num):
    negative = num >> 31
    return (num ^ negative) - negative

這里假設(shè)程序運行環(huán)境中操作系統(tǒng)為32位,int型整數(shù)(不考慮整數(shù)溢出)用32位存儲,因此可以用 num>>31 取出符號位,后面的部分留給大伙證明。

Leetcode 題目思路

回到文章開始提到的題目中,我們對除數(shù)減去被除數(shù)的過程稍作改進。假設(shè)求m/n,我們不一次次的 m-n,而是找到n的一個倍數(shù),使得m-x*n盡可能小,這樣能減少循環(huán)減法的次數(shù),進而提高效率。我們知道在按位操作中,n << k相當(dāng)于 n * 2^k,因此可以用2^k 來找合適的x。

我們需要這樣的一個數(shù)字k,它使得n 2^k < m < n 2^(k+1), 然后用m - n*2^k,得到新的m"。再找相應(yīng)的k",做減法,如此循環(huán)即可。代碼放在這里。

原文地址

相關(guān)閱讀
Pyhon wiki: BitwiseOperators
位操作基礎(chǔ)篇之位操作全面總結(jié)

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/37621.html

相關(guān)文章

  • js中按位運算

    摘要:中的數(shù)字也是按照的標(biāo)準(zhǔn)存儲的,按位存儲,但是操作符不會直接去操作位,會將位數(shù)轉(zhuǎn)換成位整數(shù)操作,完成運算后再轉(zhuǎn)換成位,這個位對用戶來說是透明的。雖然經(jīng)常寫,但是還是對一些按位運算比較迷茫。 javascript中的數(shù)字也是按照IEEE754的標(biāo)準(zhǔn)存儲的,按64位存儲,但是操作符不會直接去操作64位,會將64位數(shù)轉(zhuǎn)換成32位整數(shù)操作,完成運算后再轉(zhuǎn)換成64位,這個64位對用戶來說是透明的。...

    cnio 評論0 收藏0
  • 【譯】 JavaScript中按位操作符的有趣應(yīng)用

    摘要:檢查設(shè)定位操作符還有一些其他有用的位屏蔽應(yīng)用。請注意,位掩碼中的位將有效地關(guān)閉十進制數(shù)中的相應(yīng)位,因為。 原文標(biāo)題:Interesting use cases for JavaScript bitwise operators原文地址:https://blog.logrocket.com/in... 本文首發(fā)于公眾號:符合預(yù)期的CoyPan JavaScript提供了幾種運算符,可以對...

    oneasp 評論0 收藏0
  • java學(xué)習(xí)筆記-位運算

    摘要:位運算符位運算符與邏輯運算符類似,但是位運算符是對每一位進行計算。上面說到的按位取反加,就可以寫成移位運算符右移與無符號右移相似,是將整數(shù)所有的位向右移動位,拋棄個低位。空出來的低位用的最高位值補全。 定點數(shù)據(jù)再計算機中的表示方法 例如一個整數(shù)類型(int)的數(shù)據(jù)在內(nèi)存中占用了32位。通俗的講就是在內(nèi)存中挖了32個坑,每一個坑里可以放一個0或者1. 00000000 11111111 ...

    galaxy_robot 評論0 收藏0
  • websocket 二進制數(shù)據(jù)傳輸基礎(chǔ)準(zhǔn)備工作

    摘要:例如,十進制數(shù),用二進制表示則為。按位操作符操作數(shù)字的二進制形式,但是返回值依然是標(biāo)準(zhǔn)的數(shù)值。不同為真相同為假二進制按位異或運算從左到右按位非為真,為假對每一項進行非操作,遇真則假,遇假則真。 二進制與十六進制 二進制用 0 1 表示 2= 10十六進制 前綴0x 用0123456789ABCDEF表示 2= 0x2二進制與十六進制的轉(zhuǎn)換十六進制的每位 等于二進制的四位 十六進制 0x...

    LeviDing 評論0 收藏0
  • JavaScript字符串轉(zhuǎn)數(shù)字的5種方法及其陷阱

    摘要:例如注意字符串中的負(fù)十六進制數(shù)字是一個特殊情況,如果你用解析,結(jié)果是不正確的。轉(zhuǎn)換十六進制數(shù)時要小心,如果你不知道要轉(zhuǎn)換對象的類型,不要使用。字符串轉(zhuǎn)換為數(shù)字的方式總結(jié)負(fù)十六進制數(shù)字符串轉(zhuǎn)換為數(shù)字時。 摘要 :JavaScript 是一個神奇的語言,字符串轉(zhuǎn)數(shù)字有 5 種方法,各有各的坑法! 原文: Converting Strings to Number in Javascript...

    shengguo 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<