CSAPP實驗之Data Lab

來源:互聯網
上載者:User

標籤:語句   output   including   負數   div   val   argument   opera   class   

0.上手指南

一共 12 個需要補充的函數,所有的工作都只需修改 bits.c 檔案,測試的話有三種方式:btest, dlc, 和 BDD checker。

一些小技巧:

在函數開始時聲明所有變數
}應該在第一列
注意運算子號的優先順序,使用括弧確保順序的正確
關注 !, 0, TMin 等

任務指引還是比較清晰的,主要有以下一些說明:

整型的範圍是 0 到 255(0xFF),不允許用更大
只能包含參數和局部變數
一元操作符 ! ~
二元操作符 & | + << >>

不允許的操作有:

使用任何條件控制語句
定義和使用宏
定義其他的函數
調用函數
使用其他的操作符
使用類型轉換
使用除 int 之外的類型(針對整型)
使用除 int, unsigned 之外的類型(針對浮點數)

可以認為機器:

使用 2’s complent,32位
執行算術右移
移動超過字長的位元會出問題

其他需要注意的事情有:

使用 dlc(data lab checker) 來檢測代碼的合法性(有沒有使用不給使用的符號文法等等)
每個函數都有運算元的上限值,注意 = 不算
使用 btest 來測試結果的正確與否
使用 BDD checker 來正規測試你的函數

顯示32位int整型的show方法
void show(int x){    /*    Show 32 Bits Integer By Binary    */    for (int i = 0; i < 32; ++i)    {        if (i != 0 && i % 4 == 0)            cout << " ";        cout << ((x >> 31) & 1);        x <<= 1;    }    cout << endl;}

該方法用於檢驗函數是否寫的正確以及調試的方便性

1.thirdBits

題目要求:return word with every third bit (starting from the LSB) set to 1
允許操作:! ~ & ^ | + << >>
運算元限制:8
分值:1

int thirdBits(){    /*    Desired output: 0100 1001 0010 0100 1001 0010 0100 1001     step 1:         0000 0000 0000 0000 0000 0000 0100 1001  0x49    step 2:         0000 0000 0000 0000 1001 0010 0100 1001    step 3:         0000 0000 1001 0100 1001 0010 0100 1001    step 4:         0100 1001 0010 0100 1001 0010 0100 1001     */    int a = 0x49;    int b = (a << 9);    int c = a + b;    return (c << 18) + c;}
2.isTmin

題目要求:returns 1 if x is the minimum, two’s complement number, and 0 otherwise
允許操作:! ~ & ^ | +
運算元限制:10
分值:1

該題用於檢驗INT_MIN 該題用到INT_MIN+INT_MIN溢出後為0的技巧 但也要注意0+0也為0

int isTmin(int x){    /*    Return 1 if x is the minimum, two’s complement number, and 0 otherwise.    */    return !(x + x) & !!(x);}
3.isNotEqual

題目要求:return 0 if x == y, and 1 otherwise
例如: isNotEqual(5,5) = 0, isNotEqual(4,5) = 1
允許操作:! ~ & ^ | + << >>
運算元限制:6
分值:2

該題用異或即可,不同則不為0,相同則0,隨後用到了!!將int值轉化為bool值的技巧

int isNotEqual(int x, int y){    /*    Return 0 if x == y, and 1 otherwise    */    return !!(x^y);}
4.anyOddBit

題目要求:return 1 if any odd-numbered bit in word set to 1
例如: anyOddBit(0x5) = 0, anyOddBit(0x7) = 1
允許操作:! ~ & ^ | + << >>
運算元限制:12
分值:2

該題的想法是想聲明一個值為0xaa的變數隨後將其擴充到32位,最後與x做與操作即可得到答案

int anyOddBit(int x){    /*    Return 1 if any odd-numbered bit in word set to 1    1010 1010    */    int a = 0xAA;    int b = (a << 8) + a;    int c = (b << 8) + a;    int d = (c << 8) + a;    return !!(x&d);}
5.negate

題目要求:return -x
例如:negate(1) = -1.
允許操作:! ~ & ^ | + << >>
運算元限制:5
分值:2

該題利用補碼的取反後加一即可達到要求,但是最開始沒有想到取反操作而是製造了0xffffffff這個數進行操作

int negate(int x){    /*    Return negate     eg: if x==1 return -1    Or return ~x+1    */    int mask = (1 ^ (1 << 31)) >> 31;    return (x^mask) + 1;}
6.conditional

題目要求:same as x ? y : z
例如:conditional(2,4,5) = 4
允許操作:! ~ & ^ | + << >>
運算元限制:16
分值:3

該題即三目操作符

int Conditional(int x, int y, int z){    /*    x?y:z    Better : int mask= ~!x+1;    */    int mask = (!!x) << 31;    mask >>= 31;    return (mask&y) | ((~mask)&z);}
7.subOK

題目要求:Determine if can compute x-y without overflow
例如:
subOK(0x80000000,0x80000000) = 1
subOK(0x80000000,0x70000000) = 0
允許操作:! ~ & ^ | + << >>
運算元限制:20
分值:3

該題判斷減法是否溢出,減法是否溢出,第一個取決的便是兩個數位符號,我們可以發現

同號相減是不會溢出的,而異號相減溢出時結果的符號會與被減數的符號相反,所以有下面代碼

int subOK(int x, int y){    /*    Determine if can compute x-y without overflow    */    int a = (x >> 31) & 1;    int b = (y >> 31) & 1;    int res = x + ~y + 1;    int c = (res >> 31) & 1;    return !(a^b) | !(a^c);}
8.isGreater

題目要求:if x > y then return 1, else return 0
例如:isGreater(4,5) = 0, isGreater(5,4) = 1
允許操作:! ~ & ^ | + << >>
運算元限制:24
分值:3

該題比較兩個數位大小,首先我們明確正數是比負數大的,而負數比正數小

利用該性質我們可以先由該性質判斷,隨後利用兩數相減為正數時返回1性質寫出運算式

我們需要注意的是,該地方是不需要考慮溢出的,因為溢出是異號相減的行為

int isGreater(int x, int y){    /*    if x > y then return 1, else return 0      */    int a = (x>>31) & 1, b = (y>>31) & 1;    int res = x + ~y + 1;    int c = (res>>31) & 1;    return ((!a&b) | !c)&(!a | b);}
9.bitParity

題目要求:returns 1 if x contains an odd number of 0’s
例如:bitParity(5) = 0, bitParity(7) = 1
允許操作:! ~ & ^ | + << >>
運算元限制:20
分值:4

該題要我們數出一個int整形的二進位表達中是否有奇數個0,我們可以利用異或不改變奇偶性來寫

int bitParity(int x){    /*    returns 1 if x contains an odd number of 0’s    bitParity(5) = 0, bitParity(7) = 1    */    x = (x >> 16) ^ x;    x = (x >> 8) ^ x;    x = (x >> 4) ^ x;    x = (x >> 2) ^ x;    x = (x >> 1) ^ x;    return (x & 1);}
10.howManyBits

題目要求:return the minimum number of bits required to represent x in two’s complement
例如:
howManyBits(12) = 5
howManyBits(298) = 10
howManyBits(-5) = 4
howManyBits(0) = 1
howManyBits(-1) = 1
howManyBits(0x80000000) = 32
允許操作:! ~ & ^ | + << >>
運算元限制:90
分值:4

該題要求我們返回該數字用補碼錶示時最少能用幾位來表示 我們可以用二分法來判斷有多少位

然後我們還要對特殊情況0和-1進行區分對待

值得一提的是,我們對負數要取反,但不必加一,因為補碼錶示中負數範圍是比正數大的

而最小的負數取反後剛剛好是最大的正數

int howManyBits(int x){    /*    return the minimum number of bits required to represent x in two’s complement    */    int a = ((!x) << 31) >> 31; //當x為0時,a全為1,否則全為0    int b = ((!~x) << 31) >> 31;//當x為-1時,b全為1,否則全為0    int bit_16, bit_8, bit_4, bit_2, bit_1;    int sum;    int op = x ^ (x >> 31);    bit_16 = (!!(op >> 16)) << 4;    op = op >> bit_16;    bit_8 = (!!(op >> 8)) << 3;    op = op >> bit_8;    bit_4 = (!!(op >> 4)) << 2;    op = op >> bit_4;    bit_2 = (!!(op >> 2)) << 1;    op = op >> bit_2;    bit_1 = (!!(op >> 1));    op = op >> bit_1;    sum = 2 + bit_16 + bit_8 + bit_4 + bit_2 + bit_1;    return (a & 1) | (b & 1) | (~a & ~b&sum);}
11.float_i2f

題目要求:Return bit-level equivalent of expression (float) x. Result is returned as unsigned int, but it is to be interpreted as the bit-level representation of a single-precision floating point values.
允許操作:Any integer/unsigned operations incl. ||, &&. also if, while
運算元限制:30
分值:4

該題只要懂得浮點數的表示即可寫出

unsigned float_i2f(int x){    int sign = (x >> 31) & 1;    int exponent, fraction, fraction_mask = 0x7fffff;    if (x == 0)        return 0;    else if (x == 0x8000000)        exponent = 158;    else    {        if (sign == 1)            x = ~x + 1;        int bit_16, bit_8, bit_4, bit_2, bit_1;        int sum;        int op = x ^ (x >> 31);        bit_16 = (!!(op >> 16)) << 4;        op = op >> bit_16;        bit_8 = (!!(op >> 8)) << 3;        op = op >> bit_8;        bit_4 = (!!(op >> 4)) << 2;        op = op >> bit_4;        bit_2 = (!!(op >> 2)) << 1;        op = op >> bit_2;        bit_1 = (!!(op >> 1));        op = op >> bit_1;        sum = 1 + bit_16 + bit_8 + bit_4 + bit_2 + bit_1;        if (sum > 24)            fraction = x >> (sum - 24);        else if (sum < 24)            fraction = x << (24 - sum);        fraction &= fraction_mask;        exponent = 127 + sum - 1;    }    show(fraction);    unsigned ux = (sign << 31) + (exponent << 23) + fraction;    return ux;}
12.float_f2i

題目要求:Return bit-level equivalent of expression (int) f for floating point argument f. Argument is passed as unsigned int, but it is to be interpreted as the bit-level representation of a single-precision floating point value. Anything out of range (including NaN and infinity) should return 0x80000000u.
允許操作:Any integer/unsigned operations incl. ||, &&. also if, while
運算元限制:30
分值:4

該題是11題的逆過程,值得注意的是,我們要對小數部分進行切除

int float_f2i(float f){    int*pf = (int*)&f;    int x = *pf;    show(x);    int sign = x >> 31;    int x_abs = x & 0x7fffffff;    int exponent = x_abs >> 23;    if (exponent < 127)        return 0;    show(exponent);    int fraction_mask = 0x7fffff;    int fraction = x&fraction_mask;    show(fraction);    int i = 0;    while (fraction)    {        if (fraction & 1)            break;        fraction >>= 1;         ++i;    }    cout << i << endl;    show(fraction);    fraction |= (1 << (23 - i));    show(fraction);    int len = exponent - 127 - (23 - i);    cout << len << endl;    int res;    if (len > 0)        res = fraction << len;    else        res = fraction >> -len;    cout << exponent << endl;    cout << res << endl;    if (sign == -1)        res = ~res + 1;    return res;}
結語

第一個資料實驗算是結束了,通過該實驗,我又加深了對資料的理解,尤其是各種掩碼的設計,有了更深的理解

CSAPP實驗之Data Lab

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.