為什么
while(~scanf())
等效于
while(scanf()!=EOF)
看懂就知道了假哎。
我們已經(jīng)知道計算機中瞬捕,所有數(shù)據(jù)最終都是使用二進制數(shù)表達。
我們也已經(jīng)學(xué)會如何將一個10進制數(shù)如何轉(zhuǎn)換為二進制數(shù)舵抹。
不過肪虎,我們?nèi)匀粵]有學(xué)習(xí)一個負數(shù)如何用二進制表達。
比如惧蛹,假設(shè)有一 int 類型的數(shù)扇救,值為5,那么香嗓,我們知道它在計算機中表示為:
00000000 00000000 00000000 00000101
5轉(zhuǎn)換成二制是101迅腔,不過int類型的數(shù)占用4字節(jié)(32位),所以前面填了一堆0靠娱。
現(xiàn)在想知道沧烈,-5在計算機中如何表示?
在計算機中像云,負數(shù)以其正值的補碼形式表達锌雀。
什么叫補碼呢?這得從原碼迅诬,反碼說起腋逆。
原碼:一個整數(shù),按照絕對值大小轉(zhuǎn)換成的二進制數(shù)侈贷,稱為原碼惩歉。
比如 00000000 00000000 00000000 00000101 是 5的 原碼。
反碼:將二進制數(shù)按位取反俏蛮,所得的新二進制數(shù)稱為原二進制數(shù)的反碼撑蚌。
取反操作指:原為1,得0嫁蛇;原為0锨并,得1。(1變0; 0變1)
比如:將00000000 00000000 00000000 00000101每一位取反睬棚,得11111111 11111111 11111111 11111010。
稱:11111111 11111111 11111111 11111010 是 00000000 00000000 00000000 00000101 的反碼。
反碼是相互的抑党,所以也可稱:
11111111 11111111 11111111 11111010 和 00000000 00000000 00000000 00000101 互為反碼包警。
補碼:反碼加1稱為補碼。
也就是說底靠,要得到一個數(shù)的補碼害晦,先得到反碼,然后將反碼加上1暑中,所得數(shù)稱為補碼壹瘟。
比如:00000000 00000000 00000000 00000101 的反碼是:11111111 11111111 11111111 11111010。
那么鳄逾,補碼為:
11111111 11111111 11111111 11111010 + 1 = 11111111 11111111 11111111 11111011
所以稻轨,-5 在計算機中表達為:11111111 11111111 11111111 11111011。轉(zhuǎn)換為十六進制:0xFFFFFFFB雕凹。
再舉一例殴俱,我們來看整數(shù)-1在計算機中如何表示。
假設(shè)這也是一個int類型枚抵,那么:
1线欲、先取1的原碼:00000000 00000000 00000000 00000001
2、得反碼: 11111111 11111111 11111111 11111110
3汽摹、得補碼: 11111111 11111111 11111111 11111111
可見李丰,-1在計算機里用二進制表達就是全1。16進制為:0xFFFFFF
請定義一個宏逼泣,比較兩個數(shù)a嫌套、b的大小,不能使用大于圾旨、小于踱讨、if語句。
一看到這種不能用乘除砍的、if等常規(guī)方法痹筛。那我們就要想到位運算;
在計算機中常用的就是與廓鞠、或帚稠、非、異或床佳、左移滋早、右移運算等。
右移的情況比較復(fù)雜砌们,假如是無符號數(shù)杆麸,那么右移搁进,左邊空出的位補0;
假如是有符號負數(shù)(正數(shù))昔头,那么右移饼问,左邊會補1(補0);
所以建議使用左移揭斧;
a和b相減莱革,如果結(jié)果大于0,最高位為0讹开;否則盅视,為負數(shù)最高位為1;
因為 在計算機中是使用補碼存儲的旦万;下面的1<<31位闹击,就是用1去與上最高位; */
define cmp(a,b) (((a)-(b))&(1<<31))==1?-1:1;
//也可以這樣寫