<?xml version="1.0" encoding="utf-8"?>
1.2 c語言中的移位運算
1.3 整數表示
1.1.1 交換兩個值
void inplace_swap(int *x,int *y)這種交換方式並沒有效能上的優勢,僅僅是個智力遊戲
步驟*x
*y初始ab
第一步a
a^b第二步
ba^b
第三步ba
網路資料 :異或運算的作用
0異或任何數=任何數
1異或任何數-任何數取反
任何數異或自己=把自己置0
按位異或的幾個常見用途:
10100001^00000110 = 10100111
1.1.2 習題2.12
x的最低有效位元組,其他位置均置為0
x=0xff&x
除了x的最低有效位元組外,其他的位都取補,最低有效位元組保持不變
x=x^~0xff
x的最低有效位元組設定成全1,其他位元組都保持不變
x=0xffx
1.1.3 習題2.13
設bic(x,m)為在m為1的每個位置,將x對應的位設定為0,則bic(x,m) == x&~m
x^y=(x&~y)|(~x&y)
邏輯右移
在左端補k個0
算術右移
在左端補k個最高有效位的值
移動k位,這裡k很大
c語言標準很小心地規避了說明在這種情況下該如何做。實際上位移量就是通過計算k mod w得到的,例如w=32,即32位機,右移36位即4位,左移32位即0位,右移40位即8位
補碼的範圍是不對稱的:|tmin|=|tmax|+1,也就是說tmin沒有與之對應的正數。之所有有這樣的不對稱性,是因為一半的位模式(符號位設定為1的數)表示負數,而一半的數(符號位設定為0的數)表示非負數。因為0是非負數,也就意味著能表示的正數比負數少乙個。第二,最大的無符號數值剛好比補碼的最大值的兩倍大一點:umaxw=2tmaxw+1。補碼表示中所有表示負數的位模式在無符號表示中都變成了正數。注意-1和umax有同樣的為表示——乙個全1的串。數值0在兩種表示中都是全0的串。
數字長8
umaxw
0xff
255tminw
0x80
-128
tmaxw
0x7f
127-1
0xff
00x00
c庫中的檔案定義了一組常量,來限定編譯器執行這台機器的不同整型資料型別的取值範圍。比如,它定義了常量int_max、int_min和uint_max,它們描述了有符號和無符號整數的範圍。iso c99標準在檔案stdint.h中引入了另一類整數型別。這個檔案定義了一組資料型別,它們的宣告形如intn_t和uintn_t,指定的是n位有符號和無符號整數。n的具體值與實現相關,但是大多數編譯器允許的值為8,16,32和64。
1.3.1 有符號數和無符號數之間的轉換
強制型別轉換的結果保持位值不變,知識改變了解釋這些位的方式。-12345的16位補碼表示與53191的16位無符號表示是完全一樣的。
在c語言中,當執行乙個運算時,如果它的乙個運算數是有符號的而另乙個是無符號的,那麼c語言會隱式地將有符號引數強制轉換為無符號數,並假設這兩個數都是非負的,來執行這個運算。
這種方法對於標準的算術運算來說並無多大差異,但是對於像《和》這樣的關係運算子來說,會導致非直觀的結果。
表示式型別
求值0 == 0u
無符號1
-1 < 0
有符號1
-1 < 0u
無符號0*
2147483647 > -2147483647-1
有符號1
2147483647u > -2147483647-1
無符號0*
2147483647 > (int) 2147483648u
有符號1*
-1 > -2
有符號1
(unsigned) -1 > 2
無符號1
注:非直觀的情況標註了"*"
1.3.2 習題2.21
表示式型別
求值-2147483647-1 == 2147483648u無1*
-2147483647-1 < 2147483647有1
-2147483647-1u < 2147483647無0*
-2147483647-1 < -2147483647有1
-2147483647-1u < -2147483647無0*
1.3.3 擴充套件乙個數字的位表示
將乙個無符號數轉換為乙個更大的資料型別,我們只需要在表示的開頭新增0,這種運算稱為零擴充套件
。將乙個補碼數字轉換為乙個更大的資料型別可以執行符號擴充套件
,規則是在表示中新增最高的有效位的值的副本。設short x=-12345,把short轉換為unsigned時,我們先要改變大小,之後再完成從有符號到無符號的轉換,也就是說(unsigned)x等價於(unsigned)(int)sx,求值得到4294954951,而不等價於(unsigned)(unsigned short)x,後者求值得到53191。事實上,這個規則是c語言標準要求的。
1.3.4 習題2.27
這個函式是對確定無符號加法是否溢位的規則的直接實現。如果引數x和y相加不會產生溢位,這個函式就返回1。
int uadd_ok(unsigned x,unsigned y)
1.3.5 習題2.30
這個函式是對確定補碼加法是否溢位的規則的直接實現
int tadd_ok(int x,int y)
1.3.6 習題2.32
補碼減法溢位
int tsub_ok(int x,int y)
1.3.7 補碼非的位級表示
對每一位求補,再對結果+1,在c語言中,我們可以確定對於任意整數值x,計算表示式-x和~x+1得到的結果完全一樣。
1.3.8 習題2.34模式x
yx*y
截斷的x*y
無符號數
4 100
5 101
20 010100
4 100
補碼-4 100
-3 101
12 001100
-4 100
無符號數
2 010
7 111
14 001110
6 110
補碼2 010
-1 111
12 111110
-2 110
無符號數
2 010
7 111
14 001110
6 110
補碼2 010
-1 111
12 111110
-2 110
我們可以看出,w位數字上的無符號運算和補碼運算是同構的——加減乘在位級上有相同的結果。
date: 2014-02-26t10:21+0800
author: kirchhoff
org version 7.9.3f with emacs version 24
validate xhtml 1.0
csapp2e 家庭作業 5 16
void inner5 vec ptr x,vec ptr y data t dest long int i int length vec length x data t xdata get vec start x data t ydata get vec start y data t sum da...
CSAPP讀書筆記1
匯流排 相當於一顆線連線在各個部分,在各個部分傳遞資訊 i o裝置 input和ouput,除了鍵鼠,還有顯示器,磁碟,可執行程式就放在磁碟上 主存 暫時儲存資料的,這裡我理解為記憶體,不知道行不行 處理器 cpu從記憶體讀取指令,執行操作,然後使其指向下一條指令 在i o中輸入.hello,暫存器...
CSAPP讀書筆記,其一
不是所有的書都需要寫筆記,比如 大全這種就是需要經常讀讀,結合專案自我體驗昇華。但是對於某些涉及大量細節,或者繁雜的邏輯的書,如果只是順序的往下讀,基本上只是過眼即忘,更好的方法是仔細的看一遍,認真的做完習題,然後自己再總結一下脈絡梗概。如果時間比較匆忙,習題沒時間做也最好認真的做筆記,腦子裡面有一...