深刻理解計算機系統:第一章的家庭做業

2.42 編寫一個c表達式,生成一個字,由x的最低有效字節和y中剩下的字節組成。對於對於運算數 x = 0x89ABCDEF 和 y = 0x76543210,生成的結果是0x765432EF函數

答:分析一下,測試

  a>. 這道題目主要考的是我們邏輯運算的使用,首先我們來回顧一下都有哪些邏輯運算:spa

    按位與(&):(雙目運算)相同位均爲1,結果爲1,不然結果爲0code

    按位或(|):(雙目運算)相同位有一個是1的結果爲1,不然結果爲0blog

    按位異或(^):(雙目運算)相同位值相同的結果爲0,不然爲1it

    按位取反(~):這是單目運算,有效位值是1的,結果爲0,值爲0的結果爲1io

    還有其餘的幾個運算:什麼同一運算、位移運算(左移位運算<<;右移位運算>> 又分爲正數和負數,正數跟左移位運算同樣,負數就分爲邏輯運算補0,算術運算補1的區別)class

  b>. 從結果來看0x765432EF的前三位是y的前三位0x76543200,最後一位是x的最後一位0x000000EF,可否經過邏輯運算來分別獲得呢?二進制

    0x76543200:y1 =  y & 0xffffff00 == 0x76543210 & 0xffffff00 = 0x76543200程序

    0x000000EF:x1 = x & 0x000000ff == 0x89ABCDEF & 0x000000ff = 0x000000EF

    最後兩個結果(y1 + x1 或者使用按位或運算 x1 | y1兩種方式都行)代碼以下:  

#include <stdio.h>
int main(void)
{
        int x, y;
        int x1, y1, r1;
        printf("Please is a x and y:  ");
        scanf("%x %x", &x, &y);
        printf("x = %.8x and y = %.8x\n", x, y);
        x1 = x & 0x000000ff;
        y1 = y & 0xffffff00;
        //r1 = x1 + y1;//這種是相加的方法
        r1 = x1 | y1;//這種仍是使用了邏輯運算按位或運算,相同位值有1的結果爲1,否則結果爲0
        printf("x1 = %.8x and y1 = %.8x and r1 = %.8x\n", x1, y1, r1);
        return 0;
}

2.43 只用位級和邏輯運算,編寫出c表達式,在下列描述狀況下產生1,而其餘狀況下獲得0,你的代碼應該能在因此字長的機器上運行,加上x是正數:

  A. X的任何位都等於1    B. x的任何位都等於0    C. x的最低有效字節中的位都等於1    D. X的最低有效位的字節都等於0

答:位級和邏輯運算在上一題中已經回顧,分析如下四種狀況:

  A. X的任何位都等於1:這個可使用 按位或(|)運算來實現,好比x = 0x00000001 ===> x | 0xffffffff = 0xffffffff,或者使用取反再按位異或 ~x ^ x或者取反再按位或~x | x

  B. X的任何位都等於0:使用按位異或,相同位0,反之爲1,x ^ x

  C. X的最低有效位字節位都爲1:使用按位或運算或者算術右移運算

  D. X的最低有效位字節位都爲0:左移運算或者按位與運算

2.44 編寫一個函數is_shifts_are_arithmetic(),使得這個函數在對整數使用算術右移的機器上運行時生成1,而其餘狀況下生成0,你的代碼用該能夠運行在任何字長的機器上。在幾種機器上測試你的代碼,編寫並測試過程unsigned_shifts_are_arithmetic(),該過程肯定對無符號整數使用的位移形式。

答:分析一下:這道題主要考我們位移運算:左位移、右位移(正數與左位移同樣,負數分爲邏輯運算補0、算術運算補1)

  第一種狀況:算術右移的機器上邊,經過算術右移獲得結果1,設想一下算術右移,左邊補齊有效位的是1,那麼這時候該怎麼辦呢?1 = 0 + 1這個表達式熟悉嗎?對,就是二進制補碼,設想一下,神馬狀況下經過右移,能獲得0呢?算術右移補的是1,那麼假設我們先右移sizeof(int)位,獲得的結果必然是全部的有效位都爲1,怎麼轉換成0呢????有人想到取反,那你最後怎麼加上1呢??那就是給右移後的數添加負號,仔細想一下,當全部有效位都是1的時候,添加一下負號,那結果會是什麼???我們來計算一下它x的補碼(補碼 = ~x +1),那麼結果就是咱們想要的

 

  第二種狀況:邏輯右移的機器上邊,經過邏輯右移獲得結果0,設想一下,什麼狀況下右移的結果會是0,很明顯是當你右移到全部有效位都是0的時候,結果就爲0了

        基於上邊的分析,什麼狀況下右移到整數結果所有爲0呢??只有當右移sizeof(int)位,才能獲得全爲0(右移,邏輯運算,左邊補0,右移幾位截取掉幾位,直到全部有效位都爲0爲止),因爲程序須要通用,全部獲得全部有效位全爲0的數x,添加負號變成-x,我們來計算它的補碼,-x = ~x + 1 = 0(好比是4位 -x = -0000 = 1111 + 1 = 10000,保留4位有效數字,最高位截取掉後,剩餘有效位是0000)

2.45 

相關文章
相關標籤/搜索