3 回答

TA貢獻(xiàn)1869條經(jīng)驗(yàn) 獲得超4個(gè)贊
您應(yīng)該知道此代碼取決于簽名類型上右位移的實(shí)現(xiàn)定義行為。gcc承諾始終提供理智的行為(符號(hào)位擴(kuò)展),但I(xiàn)SO C允許實(shí)現(xiàn)對(duì)高位進(jìn)行零填充。
解決這個(gè)問題的一種方法:
#ifdef HAVE_SIGN_EXTENDING_BITSHIFTint const mask = v >> sizeof(int) * CHAR_BIT - 1;#elseint const mask = -((unsigned)v >> sizeof(int) * CHAR_BIT - 1);#endif
您Makefile
或config.h
等等可以HAVE_SIGN_EXTENDING_BITSHIFT
在構(gòu)建時(shí)定義,具體取決于您的平臺(tái)。

TA貢獻(xiàn)1852條經(jīng)驗(yàn) 獲得超1個(gè)贊
CHAR_BIT
是的位數(shù)char
。目前,幾乎所有架構(gòu)每字節(jié)使用8位,但并非總是如此。一些舊機(jī)器曾經(jīng)有7位字節(jié)。
它可以在<limits.h>
。

TA貢獻(xiàn)2011條經(jīng)驗(yàn) 獲得超2個(gè)贊
試圖在原始問題中回答顯式問題(什么是CHAR_BIT)和隱含問題(這是如何工作的)。
C和C ++中的char表示C程序可以處理的最小內(nèi)存單元*
C和C ++中的CHAR_BIT表示char中的位數(shù)。由于char類型的其他要求,它必須始終至少為8。在所有現(xiàn)代通用計(jì)算機(jī)的實(shí)踐中,它恰好是8但是一些歷史或?qū)I(yè)系統(tǒng)可能具有更高的值。
Java沒有CHAR_BIT或sizeof,因此不需要它,因?yàn)镴ava中的所有基本類型都是固定大小,并且對(duì)象的內(nèi)部結(jié)構(gòu)對(duì)程序員來說是不透明的。如果將此代碼轉(zhuǎn)換為Java,您只需將“sizeof(int)* CHAR_BIT - 1”替換為固定值31即可。
在此特定代碼中,它用于計(jì)算int中的位數(shù)。請(qǐng)注意,此計(jì)算假定int類型不包含任何填充位。
假設(shè)您的編譯器選擇對(duì)有符號(hào)數(shù)的位移進(jìn)行符號(hào)擴(kuò)展,并假設(shè)您的系統(tǒng)使用2s補(bǔ)碼表示負(fù)數(shù),這意味著“MASK”對(duì)于正值或零值為0,對(duì)于負(fù)值為-1。
為了否定二進(jìn)制補(bǔ)碼數(shù),我們需要按位執(zhí)行,然后再添加一個(gè)。等價(jià)地,我們可以減去一個(gè)然后按位否定它。
再次假設(shè)二進(jìn)制補(bǔ)碼表示-1由全1表示,所以異或或-1與按位否定相等。
因此,當(dāng)v為零時(shí),數(shù)字保持不變,當(dāng)v為1時(shí),它被否定。
需要注意的是C和C ++中的帶符號(hào)溢出是未定義的行為。因此,對(duì)最負(fù)面的值使用此ABS實(shí)現(xiàn)會(huì)導(dǎo)致未定義的行為。這可以通過添加強(qiáng)制轉(zhuǎn)換來修復(fù),以便在unsigned int中計(jì)算程序的最后一行。
*通常但不是與硬件可以解決的最小內(nèi)存單元相同。實(shí)現(xiàn)可以潛在地將多個(gè)硬件可尋址存儲(chǔ)器單元組合成一個(gè)程序可尋址存儲(chǔ)器單元,或者將一個(gè)單元的硬件可尋址存儲(chǔ)器分成多個(gè)可編程存儲(chǔ)器單元。
- 3 回答
- 0 關(guān)注
- 2405 瀏覽
添加回答
舉報(bào)