信息的表示和處理(2):整數(shù)表示

精確定義如何編碼和操作整數(shù)的數(shù)學(xué)術(shù)語:

整數(shù)數(shù)據(jù)和算術(shù)術(shù)語表

1.1 整數(shù)數(shù)據(jù)類型

32位程序上C語言整型數(shù)據(jù)類型的取值范圍
64位程序上C語言整型數(shù)據(jù)類型的取值范圍
  • 唯一一個(gè)與機(jī)器相關(guān)的類型是long羡滑,其他類型的取值范圍在32位機(jī)器和64位機(jī)器都一樣灭翔。
  • 所有類型的取值范圍都是不對稱的队丝,負(fù)數(shù)范圍比整數(shù)范圍大1漆撞。
C語言標(biāo)準(zhǔn)中整型數(shù)據(jù)類型必須至少保證的取值范圍
  • C/C++都支持有符號(hào)數(shù)和無符號(hào)數(shù)振亮,默認(rèn)是有符號(hào)數(shù)凤类。Java只支持有符號(hào)數(shù)。

1.2 無符號(hào)數(shù)的編碼

  • 無符號(hào)數(shù)編碼的定義

    對向量\vec { x } = \left[ \begin{array} { l l l l l } { x _ { w - 1 } , } & { x _ { w - 2 } , } & { \cdots , } & { x _ { 0 } } \end{array} \right] ,

    ? B 2 U _ { w } ( \vec { x } ) \doteq \sum _ { i = 0 } ^ { w - 1 } x _ { i } 2 ^ { i }

    也就是說,一個(gè)無符號(hào)整數(shù)盗尸,等于第i位的比特值乘2 ^ i , 再將各項(xiàng)相加柑船,即得整數(shù)值。

  • 函數(shù)B2U_w 的取值范圍是泼各,[0, 2^\omega - 1]椎组。每個(gè)介于這個(gè)區(qū)間的數(shù)都有唯一一個(gè)\omega 位的值編碼。反過來历恐,每個(gè)處于這個(gè)區(qū)間的位模式寸癌,都有一個(gè)大小在這個(gè)區(qū)間的整數(shù)與之對應(yīng)。因此弱贼,B2U_w 是一個(gè)雙射蒸苇。

1.3 補(bǔ)碼編碼

  • 補(bǔ)碼是有符號(hào)數(shù)的表示方式。字的最高有效位解釋為負(fù)權(quán)吮旅。

    補(bǔ)碼的定義
    • 最高有效位x_{\omega-1} 稱為符號(hào)位溪烤,權(quán)重是-2^{\omega-1} 。是無符號(hào)表示中權(quán)重的負(fù)數(shù)庇勃。
    • 符號(hào)位被設(shè)置為1時(shí)檬嘀,值為負(fù),設(shè)置為0時(shí)责嚷,值為非負(fù)鸳兽。
  • \omega 位補(bǔ)碼,能表示的最小值是[10...0]罕拂,其整數(shù)值為T M i n _ { w } \doteq - 2 ^ { w - 1 } 揍异。最大值為[01....1],其整數(shù)值為\operatorname { TMax } _ { w } \doteq \sum _ { i = 0 } ^ { w - 2 } 2 ^ { i } = 2 ^ { w - 1 } - 1 爆班。(實(shí)際上衷掷,按照上面的定義公式,將最小值和最大值的比特位代入公式柿菩,也可得出最小值和最大值的值)戚嗅。

  • 在取值范圍內(nèi)的每個(gè)補(bǔ)碼都有一個(gè)唯一的\omega 位的補(bǔ)碼。和無符號(hào)數(shù)一樣枢舶,補(bǔ)碼編碼的函數(shù)B2T_\omega 也是一個(gè)雙射懦胞。

幾個(gè)重要位模式示意圖

重要數(shù)字取值范圍圖表
  • 補(bǔ)碼范圍不對稱,| \operatorname { TMin } | = | \operatorname { TMax } | + 1 ,即TMin沒有與之對應(yīng)的正數(shù)祟辟。因?yàn)榉?hào)位設(shè)置為1 的數(shù)表示負(fù)數(shù)医瘫,而符號(hào)位為0的數(shù)表示非負(fù)數(shù)侣肄,兩者各占一半旧困。但由于全0是非負(fù)數(shù),所以能表示的正數(shù)比負(fù)數(shù)少一個(gè)。
  • 最大的無符號(hào)數(shù)值剛好比補(bǔ)碼的最大值的兩倍多一吼具。U M a x _ { w } = 2 T M a x _ { w } + 1
  • 補(bǔ)碼表示中所有表示負(fù)數(shù)的位模式在無符號(hào)表示中都變成了正數(shù)僚纷。
  • 幾乎所有機(jī)器都是以補(bǔ)碼形式來表示有符號(hào)整數(shù)。C語言中沒有要求用補(bǔ)碼形式表示有符號(hào)整數(shù)拗盒,但是在Java中明確要求用補(bǔ)碼表示整數(shù)怖竭,單字節(jié)數(shù)據(jù)類型稱為byte。這些都是為了保證Java在任何機(jī)器上運(yùn)行都能表現(xiàn)一致陡蝇。

原碼痊臭、反碼、補(bǔ)碼

有符號(hào)數(shù)的其他表示方式(1)
有符號(hào)數(shù)的其他表示方法(2)
  • 注意區(qū)別于無符號(hào)數(shù)登夫,上圖列出的都是有符號(hào)數(shù)的表示方式广匙。即有符號(hào)數(shù)的表示方式可以有原碼、反碼恼策、補(bǔ)碼三種鸦致,而無符號(hào)數(shù)的表示方式,按照除2取余法即可得到涣楷,不存在符號(hào)位分唾。
  • 原碼、反碼狮斗、補(bǔ)碼之間的轉(zhuǎn)換關(guān)系绽乔,簡單來說,就是原碼按位取反得到反碼碳褒,反碼最低位+1得到補(bǔ)碼迄汛。
  • 用原碼或反碼表示數(shù)字0時(shí),都會(huì)存在正負(fù)0的問題骤视。但是用補(bǔ)碼表示鞍爱,正負(fù)0的值都是唯一的,不存在這個(gè)問題专酗。存在正負(fù)0的原因是符號(hào)位不同導(dǎo)致的睹逃。

1.4 有符號(hào)數(shù)和無符號(hào)數(shù)之間的轉(zhuǎn)換

  • 強(qiáng)制類型轉(zhuǎn)換的結(jié)果保持位值不變,只是改變了解釋這些位的方式祷肯。

  • 處理同樣字長的有符號(hào)數(shù)和無符號(hào)數(shù)之間相互轉(zhuǎn)換的規(guī)則是:數(shù)值可能會(huì)改變沉填,但是位模式不變(二進(jìn)制位對應(yīng)的值不變)

  • T2U(有符號(hào)數(shù)轉(zhuǎn)無符號(hào)數(shù))的一般行為:負(fù)數(shù)轉(zhuǎn)換成了大的正數(shù),非負(fù)數(shù)保持不變佑笋。U2T的一般行為:小的數(shù)(\le TMax_\omega)翼闹,從無符號(hào)到有符號(hào)的轉(zhuǎn)換將保留數(shù)字的原值。對于大的數(shù)(\gt TMax_\omega)蒋纬,數(shù)字將會(huì)被轉(zhuǎn)換成一個(gè)負(fù)數(shù)值猎荠。

    有符號(hào)數(shù)和無符號(hào)數(shù)的互相轉(zhuǎn)換圖

總結(jié):

  • 在范圍0\le x\le TMax_\omega 內(nèi)的值坚弱,T2U(x)=x, U2T(x)=x。即在這個(gè)范圍內(nèi)的數(shù)字有相同的無符號(hào)和補(bǔ)碼表示关摇。
  • 在上述范圍之外的值荒叶,轉(zhuǎn)換需要加上(T2U)或者減去(U2T) 2 ^ \omega

如何從一個(gè)負(fù)數(shù)得到它的補(bǔ)碼表示输虱?

  • 官方定義些楣,補(bǔ)碼編碼的定義如下:
補(bǔ)碼的定義

但這只是列出了從補(bǔ)碼編碼得到負(fù)數(shù)的過程,如果通過這個(gè)函數(shù)求反函數(shù)會(huì)比較困難宪睹。

  • 民間做法:
    • 對于非負(fù)數(shù)愁茁,其無符號(hào)數(shù)表示和補(bǔ)碼表示相同。則按照除2取余法得到該非負(fù)數(shù)的補(bǔ)碼表示亭病。
    • 對于負(fù)數(shù)埋市,先按照非負(fù)數(shù)的做法,求得其絕對值的原碼表示命贴。然后道宅,對原碼進(jìn)行取反,再加1胸蛛。這時(shí)再看符號(hào)位污茵,因?yàn)槭秦?fù)數(shù),符號(hào)位必定為1葬项,若求得補(bǔ)碼的最高位是1泞当,則此時(shí)得到的補(bǔ)碼即為所求。如果此時(shí)最高位是0民珍,說明此時(shí)求得的補(bǔ)碼已經(jīng)超出了位數(shù)的取值范圍襟士,需要擴(kuò)大位數(shù),再次執(zhí)行上述原碼取反加1 的過程嚷量,即可得到補(bǔ)碼表示陋桂。
  • 舉例說明

比如需要知道-5的補(bǔ)碼,用4位比特位表示蝶溶,則按照民間做法嗜历,-5 絕對值為5,5的原碼是0101抖所,按位取反加1 得1011梨州,此時(shí)最高位是1,即符號(hào)位為1田轧,則1011為-5的補(bǔ)碼暴匠。

驗(yàn)證:按照官方定義,補(bǔ)碼1011對應(yīng)的整數(shù)是:-1 * 2^3 + 0 * 2^2 + 1 * 2^1 + 1 * 2^0 = -5傻粘。

再比如需要知道-11的補(bǔ)碼每窖,如果仍用4位比特位表示帮掉,按照上述方法,絕對值原碼(1011)取反加1 岛请,則得到的絕對值的補(bǔ)碼是0101,符號(hào)位是0警绩,而負(fù)數(shù)的符號(hào)位應(yīng)該是1崇败,說明超過了-11超過了4位比特位所能表示的取值范圍。因此擴(kuò)大到8位比特位肩祥,再求絕對值原碼(0000 1011)取反加1 得 1111 0101后室。此時(shí)最高符號(hào)位是1,則1111 0101是-11 的補(bǔ)碼混狠。

驗(yàn)證:按照官方定義計(jì)算補(bǔ)碼 1111 0101 對應(yīng)的整數(shù)岸霹,得-128+64+32+16+4+1=-11。

1.5 C語言中的有符號(hào)數(shù)和無符號(hào)數(shù)

  • 當(dāng)聲明一個(gè)無符號(hào)常量時(shí)将饺,需要在數(shù)字后面加上后綴字符'U'或'u'贡避,否則就會(huì)被認(rèn)為是有符號(hào)的。

  • 當(dāng)執(zhí)行一個(gè)運(yùn)算時(shí)予弧,一個(gè)運(yùn)算數(shù)是有符號(hào)的刮吧,另一個(gè)運(yùn)算數(shù)是無符號(hào)的時(shí)候,會(huì)隱式地將有符號(hào)數(shù)強(qiáng)轉(zhuǎn)成無符號(hào)數(shù)掖蛤。對于<杀捻、>這樣的關(guān)系運(yùn)算來說就會(huì)有問題,而對于標(biāo)準(zhǔn)算術(shù)運(yùn)算來說無什么差異蚓庭。關(guān)系運(yùn)算示例如下所示:

    C語言升級規(guī)則的效果

1.6 擴(kuò)展一個(gè)數(shù)字的位表示

  • 無符號(hào)數(shù)的零擴(kuò)展:將無符號(hào)數(shù)轉(zhuǎn)換為一個(gè)更大的數(shù)據(jù)類型致讥,只需簡單地在表示的開頭添加0,這種運(yùn)算叫零擴(kuò)展器赞。
  • 補(bǔ)碼數(shù)的符號(hào)擴(kuò)展:將補(bǔ)碼數(shù)字轉(zhuǎn)換為一個(gè)更大的數(shù)據(jù)類型垢袱,只需要在開頭添加最高有效位的值,這種運(yùn)輸叫符號(hào)擴(kuò)展港柜。其本質(zhì)是惶桐,加上一個(gè)權(quán)值為-2^\omega 的位(即加上一個(gè)符號(hào)位),和將權(quán)值為-2^{\omega-1} 的位轉(zhuǎn)換為一個(gè)權(quán)值為2^{\omega-1} 的位(即將原來符號(hào)位的負(fù)權(quán)消除潘懊,但保留了該位所表示的數(shù)值)姚糊,這兩項(xiàng)運(yùn)算的綜合結(jié)果保持了原始的數(shù)值。(即-2^{\omega-1} = -2^\omega + 2^{\omega-1} )授舟。
  • 一個(gè)數(shù)據(jù)的類型大小轉(zhuǎn)換救恨,以及有符號(hào)數(shù)和無符號(hào)數(shù)的轉(zhuǎn)換,它們的相對順序會(huì)影響程序的行為释树。在C語言標(biāo)準(zhǔn)中肠槽,需要先改變大小擎淤,再完成從有符號(hào)數(shù)和無符號(hào)數(shù)的轉(zhuǎn)換。

1.7 截?cái)鄶?shù)字

  • 截?cái)酂o符號(hào)數(shù):將一個(gè)\omega 位的數(shù)截?cái)酁橐粋€(gè)k位的數(shù)(\omega \ge k )秸仙,會(huì)將\omega - k 位丟棄嘴拢,得到截?cái)嗪蟮膋位無符號(hào)數(shù)。
  • 截?cái)嘌a(bǔ)碼數(shù)值:和截?cái)酂o符號(hào)數(shù)類似寂纪,截?cái)嗪蟮玫絢位的無符號(hào)數(shù)席吴,然后將最高位轉(zhuǎn)換為符號(hào)位评甜,即得到截?cái)嘌a(bǔ)碼的值哎甲。

兩者都采用了同樣的屬性:對于任何的i\ge k, 2^i mod 2^k = 0

1.8 有符號(hào)數(shù)和無符號(hào)數(shù)的建議

  • 有符號(hào)數(shù)和無符號(hào)數(shù)在程序中的轉(zhuǎn)換可能會(huì)出現(xiàn)難以發(fā)現(xiàn)的錯(cuò)誤讲竿。避免錯(cuò)誤的一種方法是不使用無符號(hào)數(shù)拟杉。
  • 除C語言外很少有語言支持無符號(hào)整數(shù)庄涡。在Java中,支持有符號(hào)整數(shù)搬设,且要求以補(bǔ)碼運(yùn)算實(shí)現(xiàn)穴店,>> 被定義為算術(shù)右移,>>>被定義為邏輯右移拿穴。
  • 無符號(hào)數(shù)的應(yīng)用場景:用于把字看作是位的集合而沒有任何數(shù)字意義迹鹅;用于系統(tǒng)中的內(nèi)存地址;可用于實(shí)現(xiàn)模運(yùn)算和多精度運(yùn)算的數(shù)學(xué)包贞言。

其中細(xì)微的錯(cuò)誤可參照習(xí)題2.25和2.26斜棚,

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市该窗,隨后出現(xiàn)的幾起案子弟蚀,更是在濱河造成了極大的恐慌,老刑警劉巖酗失,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件义钉,死亡現(xiàn)場離奇詭異,居然都是意外死亡规肴,警方通過查閱死者的電腦和手機(jī)捶闸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拖刃,“玉大人删壮,你說我怎么就攤上這事《夷担” “怎么了央碟?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長均函。 經(jīng)常有香客問我亿虽,道長菱涤,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任洛勉,我火速辦了婚禮粘秆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘收毫。我一直安慰自己攻走,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布牛哺。 她就那樣靜靜地躺著陋气,像睡著了一般劳吠。 火紅的嫁衣襯著肌膚如雪引润。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天痒玩,我揣著相機(jī)與錄音淳附,去河邊找鬼。 笑死蠢古,一個(gè)胖子當(dāng)著我的面吹牛奴曙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播草讶,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼洽糟,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了堕战?” 一聲冷哼從身側(cè)響起坤溃,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎嘱丢,沒想到半個(gè)月后薪介,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡越驻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年汁政,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缀旁。...
    茶點(diǎn)故事閱讀 38,577評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡记劈,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出并巍,到底是詐尸還是另有隱情抠蚣,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布履澳,位于F島的核電站嘶窄,受9級特大地震影響怀跛,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜柄冲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一吻谋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧现横,春花似錦漓拾、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至姜盈,卻和暖如春低千,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背馏颂。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工示血, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人救拉。 一個(gè)月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓难审,卻偏偏與公主長得像,于是被迫代替她去往敵國和親亿絮。 傳聞我的和親對象是個(gè)殘疾皇子告喊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容