你所不知道的補碼

某君不無興奮地跟我說他有個重大發(fā)現(xiàn): java里最小負整數(shù)的絕對值等于它本身! 程序員朋友可以試試以下判斷:

Math.abs(int.MIN_VALUE) == int.MIN_VALUE

不管怎樣, 取絕對值后一定是個正數(shù), 怎么可能等于一個負數(shù)呢.乍一看, 太二和尚摸不著頭腦. 向來以精準著稱計算機世界, 怎么會得出如此可笑的結(jié)論?

其中一定有什么隱情! 憑直覺, 這應(yīng)該和補碼有關(guān). 補碼, 初中時代的知識, 不出意外地, 忘得差不多了, 先溫故一下, 沒準能知新.

正數(shù)的補碼等于它自己, 負數(shù)的補碼等于其反碼+1.

計算機是以二進制方式表示數(shù)字的, 其中負數(shù)又以補碼的方式表示. 當回憶起這點的時候, 有一個問題吸引了我:為什么負數(shù)要用補碼表示呢?, 這似乎是一個和1+1為什么等于2一樣傻的問題, 所以當年聰明的我沒敢問老師為什么. 如今智商越發(fā)下降, 類似的問題也越來越多, 然后, 像小孩子發(fā)現(xiàn)更好玩的玩具一樣, 開頭那個問題就被晾在一邊了…

大概一開始人們也沒設(shè)計出補碼這玩意兒, 畢竟誰會上來就找麻煩搞這么復(fù)雜的東西. 應(yīng)該是很自然地第一位是符號位, 0表示正數(shù), 1表示負數(shù), 剩下是表示值的多少. 當然, 對于人類輕而易舉想到的答案, 上帝一般是要發(fā)笑的. 這個方案會有什么問題呢? 讓我們簡單地假定整數(shù)是用3個比特表示的, 其表示的所有數(shù)字, 排列組合如下:

000: 0, 001: 1, 010: 2, 011: 3, 100: -0, 101: -1, 110: -2, 111: -3

這樣也能work. 但很顯然的不足是, 0有兩種表示法, 有點浪費空間了. 還有一個更隱蔽的缺點, 用一道題來說明. 按上述規(guī)則計算下1-1, 也就是1+(-1)的結(jié)果.

001+101=110

110就是-2, 顯然不對. 那么如何設(shè)計才能讓同時彌補上述兩個缺點呢? 這時候, 補碼就隆重登場了. 按補碼的規(guī)則重新窮舉上述排列:

000: 0, 001: 1, 010: 2, 011: 3, 100: -4, 101: -3, 110: -2, 111: -1

0不再重復(fù)了, 表示的空間從[-3, 3], 擴大到[-4, 3]. 而且1-1的計算, 變得簡單自然, 絲般順滑(最高位溢出):

001+111=000

因此, 不必為加法和減法設(shè)計兩套計算電路! 兩個看似不同, 甚至對立的邏輯, 得到了統(tǒng)一. 設(shè)計之巧妙, 令人嘆服. 看似很傻的問題, 細細研究, 原來這般微妙, 優(yōu)雅得簡直像藝術(shù)品, 不得不佩服提出補碼那位兄臺.

繞了個圈, 回到最開始的問題. 絕對值的計算大家都清楚: 正數(shù), 直接返回它自己, 負數(shù), 返回其相反數(shù). 而java計算相反數(shù), 就是取其補碼. 仍然拿3比特的為例, 最小的負數(shù)是100(-4), 取反是011, 加1后是100, 還是-4. int類型一般是32比特, 但演算過程是一樣的.

寫代碼如何能少出bug? 做架構(gòu)如何能更靈活適應(yīng)需求的變化? 一個共同的答案是, 發(fā)現(xiàn)和歸納事物的規(guī)律, 通過巧妙的設(shè)計, 或更高的抽象, 減少差異性, 提高普適性.

設(shè)計行業(yè)里流行少即是多的理念. 我想, 少不是刻意刪除, 不是空洞無物. 少, 是在充分理解的前提下, 找到那個支點, 四兩撥千斤, 用最小的付出, 撬動最大的收益. 九九歸一, 少得下來, 一定是看透了規(guī)律, 抓住了本質(zhì).

上面對補碼的理解, 足夠概括和普適了嗎? 并沒有.

先試試在進制上做點延展. 小學生都會的減法, 能否統(tǒng)一成加法呢? 答案是肯定的. 事實上,

兩整數(shù) A撬即、B 用同一個正整數(shù) M (M 稱為模)去除而余數(shù)相等,則稱 A度迂、B 對 M同余,記作: A=B (MOD M). 具有同余關(guān)系的兩個數(shù)為互補關(guān)系,其中一個稱為另一個的補碼.

那么, 一個更加概括的理解是:減去一個數(shù), 等于加上這個數(shù)的補碼.

數(shù)學源于生活, 讓我們舉個日常生活的例子. 時鐘連3歲小孩都能看懂, 比11點早3小時是8點, 比11點晚9小時也是8點, 嘿嘿, 說的就是這個理, 只不過這里的模是12. 而計算機用的是二進制, 以2為模: 1-1 = 1+1 = 2+0 = 0 (2被抹掉了).

所以下回教小孩子做減法可以這么說: 7-3 = 7+7 = 10+4 = 4. 當然, 要解釋為什么10被任性地抹掉了, 也挺費勁.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市跨琳,隨后出現(xiàn)的幾起案子迹辐,更是在濱河造成了極大的恐慌奄薇,老刑警劉巖荣病,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件舟茶,死亡現(xiàn)場離奇詭異,居然都是意外死亡茬高,警方通過查閱死者的電腦和手機兆旬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來怎栽,“玉大人丽猬,你說我怎么就攤上這事⊙椋” “怎么了脚祟?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長强饮。 經(jīng)常有香客問我由桌,道長,這世上最難降的妖魔是什么邮丰? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任行您,我火速辦了婚禮,結(jié)果婚禮上剪廉,老公的妹妹穿的比我還像新娘娃循。我一直安慰自己,他們只是感情好斗蒋,可當我...
    茶點故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布捌斧。 她就那樣靜靜地躺著笛质,像睡著了一般。 火紅的嫁衣襯著肌膚如雪捞蚂。 梳的紋絲不亂的頭發(fā)上妇押,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天,我揣著相機與錄音洞难,去河邊找鬼舆吮。 笑死,一個胖子當著我的面吹牛队贱,可吹牛的內(nèi)容都是我干的色冀。 我是一名探鬼主播,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼柱嫌,長吁一口氣:“原來是場噩夢啊……” “哼锋恬!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起编丘,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤与学,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后嘉抓,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體索守,經(jīng)...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年抑片,在試婚紗的時候發(fā)現(xiàn)自己被綠了卵佛。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,567評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡敞斋,死狀恐怖截汪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情植捎,我是刑警寧澤衙解,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站焰枢,受9級特大地震影響蚓峦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜济锄,卻給世界環(huán)境...
    茶點故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一枫匾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧拟淮,春花似錦、人聲如沸谴忧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至委造,卻和暖如春戳鹅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背昏兆。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工枫虏, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人爬虱。 一個月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓隶债,卻偏偏與公主長得像,于是被迫代替她去往敵國和親跑筝。 傳聞我的和親對象是個殘疾皇子死讹,可洞房花燭夜當晚...
    茶點故事閱讀 45,585評論 2 359

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

  • 網(wǎng)站亂碼問題我們會經(jīng)常碰到,大多見于非英文的中文字符或其他字符亂碼曲梗,而且赞警,這類問題常常是因為編碼方式問題,主要原因...
    波段頂?shù)?/span>閱讀 2,890評論 1 9
  • 本篇文章講解了計算機的原碼, 反碼和補碼. 并且進行了深入探求了為何要使用反碼和補碼, 以及更進一步的論證了為何可...
    yang2yang閱讀 2,254評論 1 13
  • 前些日子虏两,抽空做了一下所謂的微3D效果的控件愧旦,然后我給他取名叫JECalourseView,由于本人比較忙定罢,比比較...
    一個野指針閱讀 3,423評論 4 8
  • 圖/木槿 文/木槿 春花秋月 夏日冬雪 極美引颈、醉人情 一輪逍遙游歷 來日暖席煮酒 索然心事愁歡 癡纏千幕景 留戀萬...
    癡人一念閱讀 259評論 2 18
  • 一個女人的自述 我想我就是個名副其實的“破鞋”吧耕皮。從我畢業(yè)到現(xiàn)在八年了,我有過六個男朋友蝙场,還有一個旅行是遇見的“艷...
    可憐人Loser閱讀 8,487評論 2 0