鍍金池/ 問答/PHP  Python  C  HTML/ 關(guān)于移位運(yùn)算的一些疑惑

關(guān)于移位運(yùn)算的一些疑惑

對(duì)于任意w位的二進(jìn)制,進(jìn)行k位的移動(dòng)時(shí),真實(shí)的位移量為k mod w

32bit的例子

1 << 1 結(jié)果2 1 mod 32 => 1
1 << 32 結(jié)果1 32 mod 32 => 0
1 << 33 結(jié)果2 33 mod 32 => 1

為什么不設(shè)計(jì)為 更直觀的(個(gè)人想法) 直接移動(dòng)k位

1 << 33 => 0
1 << 666 => 0

k mod w的這種設(shè)計(jì)是有什么特殊意義嗎?

回答
編輯回答
情未了

許多機(jī)器在做位移操作的時(shí)候都是只出理低log(w)位,也就是所說的w%k位

(但是,具體有哪些機(jī)器我沒有了解過)

那么,這么處理的原因,在我看來,是由CPU對(duì)位移指令的實(shí)現(xiàn)所決定的。就32位機(jī)器而言,Intel CPU(具體是從哪一代開始我記不清了)會(huì)對(duì)位移量截取低五位。

那么反映到高級(jí)語言層面上,有一些語言標(biāo)準(zhǔn)會(huì)遵循這個(gè)操作,其對(duì)應(yīng)的編譯器或者解釋器便會(huì)按照標(biāo)準(zhǔn)來處理,位移的時(shí)候截取位移量的低log(w)位,比如JavaScript的解釋器。

但是有一些語言規(guī)范是規(guī)避了這個(gè)問題的,比如C語言,這個(gè)操作就是未定義行為,它的編譯器在處理時(shí)就如上面有答主所說過的,將按自己的理解來處理。

非常典型的一點(diǎn)你可以嘗試一下,在C語言中用gcc編譯器試一下這段代碼

int a = 33;
printf("%d", 1 << a); // 2
printf("%d", 1 << 33); // 0

第一種情況,在編譯過程中,由于gcc編譯器不知道變量a的值,所以,位移量為33,CPU執(zhí)行時(shí),會(huì)截取低5位,答案是2
第二種情況,在編譯過程中,如果加上-Wall編譯選項(xiàng),gcc編譯器會(huì)提醒你,位移量大于類型的寬度,所以,按照gcc自己處理的來,得到的答案是0,就是你的想法。

至于為什么要截取低log(W)位,這大概是和CPU處理字長(zhǎng)有關(guān)

我的理解是這樣,如果有錯(cuò)誤,忘請(qǐng)指正

2017年4月23日 10:52
編輯回答
久礙你

C語言里,如果位移量大于等于被操作數(shù)的位數(shù),是標(biāo)準(zhǔn)未定義行為。就是編譯器怎么處理都可以。
In any case, the behavior is undefined if rhs is negative or is greater or equal the number of bits in the promoted lhs.

所以,沒什么特殊意義了哦,要問就問編譯器廠商吧。編譯器廠商:“滾”

2017年8月27日 22:30
編輯回答
忘了我

因?yàn)樵谖贿\(yùn)算的常見場(chǎng)景(C,C++中)整數(shù)的大小是固定的,32位或者64位,
而移位運(yùn)算事實(shí)上也不是為了進(jìn)行數(shù)值計(jì)算,而是正經(jīng)的位運(yùn)算,通過移位運(yùn)算得到大整數(shù)也不是很推薦的行為,
Python的整數(shù)類型是不限制大小的,完全可以通過2 ** 66獲取很大的整數(shù)。

2018年4月5日 21:00
編輯回答
熟稔

計(jì)算機(jī)是按照8字節(jié)存儲(chǔ)的,11111111=255,超過255即需要16字節(jié)以上,所以移位均是以8的倍數(shù)移位的

2017年9月12日 09:59