計算機會認為(-b)是(0-b)還是((-1)*b)?

在學習Computer Science Syntax Tree時想到的


- 和 + 通常既可以是 binary operator,又可以是 unary operator。

(-b) 中的 - 是 unary operator。


就是一個「取負」操作,不是減也不是乘。

在高級語言中常表現為「-x」的形式。語法樹中也是一元操作「(- (x))」。(「取正」運算符「+」亦如此,此時+和-就不是加和減了)

在一般機器底層也是一個單參數的取負指令(當然也有些例外的)。

對於整數、浮點數等基本類型基本如此,有部分機器架構例外(那些架構中底層確實是用0去減)。

而對於(支持運算符重載的)對象來說更是如此,這個則沒有例外。

一個對象類型,可以不去定義「被整數減」、「被整數乘」、「乘整數(嗯左乘右乘不一樣,交換律不是對什麼都成立的)」這些操作,但以上這些都不妨礙它擁有「取負」操作的定義。


CPU有取負數指令,直接變負。低檔的沒有取負數指令也有取邏輯反指令,再加一條遞增指令。再不濟也有邏輯運算,和全1異或再遞增。這些指令編譯器都會安排好的,所以不存在是0-還是-1*的說法,-本身就是一種運算。


查了下資料總結如下:

只針對x86,b可能是代指一個立即數,一個變數,且分整數 ,浮點數的情況:

1.如果是立即數,在編譯器編譯時,直接就是補碼。

2.如果是變數,整數就是一個 neg指令,浮點數是xorps.

neg指令在cpu中的ALU(算術邏輯單元)中,直接支持該指令,見wiki Arithmetic logic unit

"

  • Two"s complement (negate): A (or B) is subtracted from zero and the difference appears at Y.

"

而xorps是sse中的指令,不是很了解,還希望達人解釋。


C++:看成 b.operator-()


題主問: "計算機會認為(-b)是(0-b)還是((-1)*b)?"

計算機通常被理解成硬體本身, 那麼答案:

計算機完全不Care這種事兒, 這種事兒要你們人類自己寫程序處理. 計算機的CPU只Care它現在應該執行哪一段機器碼.

誰Care? 應該是語法分析(編譯器前端步驟)理解了的這個(-b)表達式是合法的, 然後最終生成的ast結構, 最後由代碼生成(編譯器後端), 生成機器碼(計算機認識的).

YY一下, 如果DIY一個簡單的編譯器:

(-b)這個表達我覺的已經能很好的生成代碼了, 但是((-1)*b)如果直接生成代碼, 會用到額外的指令, 那麼也許聰明的編譯器可以給他優化成(-b). 另外如果b是常量, 那麼它可能在代碼生成前已經被各種計算了.


問題本身有問題,應該問某種語言如何...


計算機並看不到b這種東西,具體得看編譯器怎麼做。

也就是說,如果自己寫編譯器,-b也可以被編譯成2*3*4*5*6*7*8*9*10/10/9/8/7/6/5/4/3/2*b - 2*b,(不過這種設計會出問題)


補碼,嵌入式一般為0-b


編譯器不想和你說話並向你扔了一顆氰化鉀蘋果


-b會被看成!b+1。

------------------修改-------------------

取反的符號是~嗎?那就是~b+1。


請先學習二進位,符號位,反碼,補碼


對於計算機來說,-b與b的關係:

對於整形來說,是補碼。

對於浮點數,是符號位相異。

對於自定義類型,是自定義operator-決定的。

其實就是沒什麼關係,因為都是二進位。b不一定是b,取決於你的上下文。


b的二進位的補碼


c的話,認為是求補,寫成彙編是negl指令。


底層有專門的符號位


正負號有特定的表示方法,說到底就是用0和1的特定組和來區分正負數啦


編譯器級別的問題吧,會有詞法解析


-號即使一目運算符也是二目運算符


一般來說,如果是數值,就只會把符號位變一下,不是0-b或者-1*b


推薦閱讀:

怎麼從零學起成為一名黑客?
寫代碼上癮是一種什麼樣的體驗?
能推薦國外大學適合自學的CS課程(自帶源碼與資料)嗎?非coursera/edx
真·二本學校的計算機類專業尖子生的專業能力可能超過985名校的優秀學生嗎?
英特爾的CPU性能幾年內也沒什麼進步,蘋果CPU是如何每年獲得巨大進步的呢?

TAG:計算機 | 計算機科學 |