<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      博客園 首頁(yè) 私信博主 顯示目錄 隱藏目錄 管理 動(dòng)畫

      CSAPP Lab1



      CSAPP Lab1

      寫了作業(yè)水一篇(記錄一下人多菜
      博客園的三級(jí)標(biāo)題好小


      bits.c

      在bits.c中做題目
      使用make clean和make進(jìn)行編譯
      調(diào)用./btest -f funcName測(cè)試funcName函數(shù)的結(jié)果,可以在代碼中中插入printf輸出中間結(jié)果,但是要記得最后刪掉
      調(diào)用./dlc bits.c查看是否使用了非法或過多的運(yùn)算符
      重復(fù)以上步驟,最后可以直接運(yùn)行./btest輸出最后結(jié)果。

      得分圖

      本地的fitsBits的Check可能有問題,沒法過。

      補(bǔ)充一個(gè)位運(yùn)算優(yōu)先級(jí)圖。

      bitAnd

      x&y using only ~ and |
      ~x~y中同時(shí)為\(0\)的位即為x&y中為\(1\)的位,或起來取反即可。

      int bitAnd(int x, int y) {
      	return ~(~x|~y);
      }
      

      getByte

      Extract byte n from word x
      0xFF分別與x,x>>8,x>>16,x>>24即可。

      int getByte(int x, int n) {
      	return 0xFF&(x>>(n<<3));
      }
      

      logicalShift

      shift x to the right by n, using a logical shift
      簡(jiǎn)單的想法是x>>n與一個(gè)高\(n\)位為\(0\)其余全\(1\)的數(shù)\(x\)\(x\)取反就是\(\begin{matrix}\underbrace{111}..000\\n個(gè)1\ \ \ \ \ \ \ \ \ \end{matrix}\),用\(1<<31\)就可以算術(shù)右移\(n\)位得到高\(n\)位的\(1\),然后再左移\(1\)位即可。

      令一個(gè)想法是,\(111...000\)就是\(0xFFFFFFFF\)左移\(32-n\)位。
      有三個(gè)問題及前兩個(gè)的解決方法依次是:

      1. \(n=0\)時(shí)\(位移量=w=32\),先左移\(31\)位再右移\(n\)位,最后再左移\(1\)位,避免最高位的\(1\)丟失。
      2. \(0xFFFFFFFF\)右移時(shí)是邏輯右移,要轉(zhuǎn)成int或?qū)懗?span id="w0obha2h00" class="math inline">\(-1\)才是算術(shù)右移,才不丟失最高位的\(1\),但是不能有 類型轉(zhuǎn)換 和 負(fù)號(hào)及十進(jìn)制數(shù)。
        所以必須是恰好左移\(32-n\)位,解決方法是對(duì)\(31-n\)二進(jìn)制拆分(\(31-n\)的二進(jìn)制表示比\(32-n\)更容易知道),寫成\(\log n\)個(gè)與和右移,最后再左移\(1\)位。這樣改完后代碼:(x>>n)&~(0xFFFFFFFF<<(!(n&16)<<4)<<(!(n&8)<<3)<<(!(n&4)<<2)<<(!(n&2)<<1)<<(!(n&1))<<1);
      3. 常數(shù)只能是\(0x0\sim 0xFF\)(不過可以構(gòu)造出來),以及運(yùn)算符數(shù)超過了\(20\)。所以這個(gè)方法不行。
      int logicalShift(int x, int n) {
      	return (x>>n)&~(1<<31>>n<<1);
      }
      

      bitCount

      returns count of number of 1s in word
      做法是整體的分治。令\(v_1=01\ 01\ 01\ 01...,v_2=0011\ 0011...,v_3=0000\ 1111...\)直到\(v_5=0000\ 0000\ 0000\ 0000\ 1111\ 1111\ 1111\ 1111\)
      先計(jì)算每?jī)晌恢?span id="w0obha2h00" class="math inline">\(1\)的個(gè)數(shù)\(n_2\),即為\(n_2=(x\&v_1)+(x>>1\&v_1)\),每?jī)晌坏?span id="w0obha2h00" class="math inline">\(1\)的個(gè)數(shù)會(huì)存在這兩位中。
      再計(jì)算每四位中\(1\)的個(gè)數(shù),即\(n_4=(n_2\&v_2)+(n_2>>2\&v_2)\),每四位的\(1\)的個(gè)數(shù)會(huì)存在這四位中。
      同理,每八位中的\(1\)\(n_8=(n_4\&v_3)+(n_4>>4\&v_3)\),十六位為\(n_{16}=(n_8\&v_4)+(n_8>>8\&v_4)\),三十二位為\(n_{32}=(n_{16}\&v_5)+(n_{16}>>16\&v_5)\),即為答案。

      有個(gè)細(xì)節(jié)是,計(jì)算\(n_8\)時(shí)\(n_4+(n_4>>4)\)得到的每八位\(1\)的個(gè)數(shù)不會(huì)超過\(2^4=16\),即不會(huì)溢出\(v_3\)中限制的\(4\)位,所以可以先加起來再一起\(\&\)減少一次操作數(shù)。\(n_{16},n_{32}\)同理。

      還有限制常數(shù)最多為八位,所以需先構(gòu)造\(v_1'=01010101|(01010101<<8)=0x55|(0x55<<8),v_1=v_1'|(v_1'<<16)\),以及\(v_2'=00110011|(00110011<<8)=0x33|(0x33<<8),v_2=v_2'|(v_2'<<16)\),以及\(v_3'=0xF|(0xF<<8),v_3=v_3'|(v_3'<<16)\)

      int bitCount(int x) {
      	int tv1=0x55|(0x55<<8),v1=tv1|(tv1<<16);
      	int tv2=0x33|(0x33<<8),v2=tv2|(tv2<<16);
      	int tv3=0xF|(0xF<<8),v3=tv3|(tv3<<16);
      	int v4=0xFF|(0xFF<<16);
      	int v5=0xFF|(0xFF<<8);
      
      	int res=(x&v1)+(x>>1&v1);
      	res=(res&v2)+(res>>2&v2);
      	res=(res+(res>>4))&v3;
      	res=(res+(res>>8))&v4;
      	res=(res+(res>>16))&v5;
      	return res;
      }
      

      bang

      Compute !x without using !
      結(jié)果為\(1\)當(dāng)且僅當(dāng)x=0,所以問題在于怎么將一個(gè)數(shù)的\(1\)放到個(gè)位上。有個(gè)位的\(1\)后,取反與\(1\)就可以了。

      類似bitCount的分治,用x|=x>>1求出兩兩分組后的兩位中是否有\(1\)并放到低位上,然后x|=x>>2,求出四個(gè)一組的數(shù)中是否有\(1\)并放到低位上...直到x|=x>>16

      x|=x>>16開始也可,先將\(1\)匯聚到低\(16\)位上,再x|=x>>8可以將\(1\)匯聚到低\(8\)位上,...直到x|=x>>1

      還有種方法是,利用\(0\)\(-0\)~x+1)的符號(hào)位均為\(0\),而其他數(shù)中有一個(gè)\(1\)的性質(zhì),取出這個(gè)\(0\)。即:~((x|(~x+1))>>31)&1

      int bang(int x) {
      	return ~((x|(~x+1))>>31)&1;
      //Another sol:
      	// x|=x>>1;
      	// x|=x>>2;
      	// x|=x>>4;
      	// x|=x>>8;
      	// x|=x>>16;
      	// return ~x&1;
      }
      

      tmin

      return minimum two's complement integer
      1<<31

      int tmin(void) {
      	return 1<<31;
      }
      

      fitsBits

      return 1 if x can be represented as an n-bit, two's complement integer.
      \(-2^n\leq x\lt 2^n\),則\(x\)若為正數(shù),則高\(32-n\)位均為\(0\),若為負(fù)數(shù),則高\(32-n\)位均為\(1\)。所以\(x\)左移\(32-n\)位后再右移\(32-n\)位應(yīng)不變。否則\(x\)越界則\(x\)數(shù)值會(huì)改變。
      注意32-n=32+(~n+1)a==b可以改寫為!(a^b)

      int fitsBits(int x, int n) {
      	int delta=33+(~n);
      	return !(x^(x<<delta>>delta));
      }
      

      divpwr2

      Compute x/(2^n), for 0 <= n <= 30 (Round toward zero)
      \(x\)為正數(shù)則為\(x>>n\),為負(fù)數(shù)則為\(x+(1<<n)-1>>n\)
      \(1\)替換成\(x\)的符號(hào)位即可。注意若\(x\)為負(fù)則\(x>>31=-1\),提取符號(hào)位需要\(\&1\),但可以直接作為減\(1\)

      int divpwr2(int x, int n) {
      	int sign=x>>31;
      	return (x+((sign&1)<<n)+sign)>>n;
      }
      

      negate

      return -x
      ~x+1

      int negate(int x) {
      	return ~x+1;
      }
      

      isPositive

      return 1 if x > 0, return 0 otherwise
      需要判\(0\),而\(-0\)的符號(hào)位不變,所以同divpwr2中用\((-x>>31)\&1\)提取\(-x\)的符號(hào)位即可。但有個(gè)問題是\(-TMIN=TMIN\),所以還要特判\(TMIN\)否則不對(duì)。
      更簡(jiǎn)單的是直接求符號(hào)位,然后\(\&(!!x)\)來特判\(0\)

      int isPositive(int x) {
      	return (!(x>>31))&(!!x);
      }
      

      isLessOrEqual

      if x <= y then return 1, else return 0
      如果不溢出就是isPositiveOrZero(y-x)!((y-x)>>31&1)。注意到y-x溢出只發(fā)生在\(x,y\)異號(hào),而異號(hào)可以直接判斷大小。所以先求一下\(x,y\)的符號(hào)位判斷是否溢出即可。

      int isLessOrEqual(int x, int y) {
      	int sx=x>>31&1, sy=y>>31&1;
      	return ((!sy)&sx)|(!(sy^sx)&!((y+~x+1)>>31&1));
      }
      

      ilog2

      return floor(log base 2 of x), where x > 0
      即求最高位的\(1\)。最簡(jiǎn)單的方法是再最高位右邊全填上\(1\),再用bitCount-1。
      填充\(1\)類似bangx|=x>>16,x|=x>>8,...,x|=x>>1,從高位傳下來即可。也同bangx|=x>>1最后x|=x>>16都可。

      還有種方法是,先求出高\(16\)位是否有\(1\),有就加\(2^{16}\);然后再求當(dāng)前\(16\)位中高\(8\)位是否有\(1\),有就加\(2^8\)...直到最后一位。

      int ilog2(int x) {
      	int tv1=0x55|(0x55<<8),v1=tv1|(tv1<<16);
      	int tv2=0x33|(0x33<<8),v2=tv2|(tv2<<16);
      	int tv3=0xF|(0xF<<8),v3=tv3|(tv3<<16);
      	int v4=0xFF|(0xFF<<16);
      	int v5=0xFF|(0xFF<<8);
      	int res;//鍙よ€佺殑csapp鏍囧噯瑕佹眰C涓嚱鏁板0鏄庡繀欏昏鍦ㄦ渶鍓嶉潰
      
      	x=x|(x>>16), x=x|(x>>8), x=x|(x>>4), x=x|(x>>2), x=x|(x>>1);
      	res=(x&v1)+(x>>1&v1);
      	res=(res&v2)+(res>>2&v2);
      	res=(res+(res>>4))&v3;
      	res=(res+(res>>8))&v4;
      	res=(res+(res>>16))&v5;
      	return res+~1+1;
      }
      

      float_neg

      Return bit-level equivalent of expression -f for floating point argument f.
      實(shí)數(shù)取反,取反符號(hào)位即可。要特判NaN。

      unsigned float_neg(unsigned x) {
      	if((x&0x7FFFFFFF)>0x7F800000) return x;
      	return x^0x80000000;
      }
      

      float_i2f

      Return bit-level equivalent of expression (float) x
      \(x\)為負(fù)數(shù),則先將\(x\)取反;為\(0\)可直接特判。
      設(shè)最高位的\(1\)為第\(i\)位,則浮點(diǎn)數(shù)的階碼\(E\)\(i+Bias=i+127\),小數(shù)子段\(f\)則為低\(i\)位(如果小于\(23\)位則后面補(bǔ)\(0\),大于\(23\)位則舍棄并進(jìn)位,注意是向偶數(shù)舍入!)。最后再加上符號(hào)位。
      具體:
      用前面方法或循環(huán)找到最高位的\(1\),設(shè)其距第\(31\)位距離為\(d\),則直接將ux=(unsigned)x左移\(d+1\)位,使小數(shù)子段確定為\(ux\)\(31\sim 9\)位,舍棄位為\(8\sim 0\)位。
      偶數(shù)舍入兩種情況:1. 舍棄的\(9\)位大于\(2^9\),即ux&0x1FF>0x100
      2. 有效位和最高舍棄位均為\(1\),即第\(9\)位和第\(8\)位均為\(1\),即ux&0x300==0x300ux&0x3FF>=0x300。(我怎么總是忘了位是從\(0\)開始標(biāo)號(hào))

      最高符號(hào)位,加上從\(23\)位開始的\(低位個(gè)數(shù)+127\),最后加上小數(shù)子段\(ux>>9\)和進(jìn)位即為答案。

      unsigned float_i2f(int x) {
      	unsigned ux=x,sign=ux>>31,carry=0; int d=0;
      	if(!x) return 0;
      	if(sign) x=~x+1, ux=x;
      	while(!(x&0x80000000)) x<<=1, ++d;
      
      	ux<<=d+1;
      	carry=((ux&0x1FF)>0x100)|((ux&0x300)==0x300);
      	return (sign<<31)+((31-d+127)<<23)+(ux>>9)+carry;
      }
      

      float_twice

      Return bit-level equivalent of expression 2*f for floating point argument f.
      如果是規(guī)格化數(shù),直接階碼\(+1\)(直接加0x800000);
      如果是非規(guī)格化數(shù),只需將\(x\)左移\(1\)位(注意符號(hào)位)。
      特殊值則直接返回。

      unsigned float_twice(unsigned x) {
      	if((x&0x7F800000)==0x7F800000) return x;
      	else if(!(x&0x7F800000)) return (x<<1)|(x&0x80000000);
      	else return x+0x800000;
      }
      

      其它

      找出一個(gè)數(shù)中的第\(k\)個(gè)1
      https://stackoverflow.com/questions/7669057/find-nth-set-bit-in-an-int

      posted @ 2021-04-02 23:35  SovietPower  閱讀(1182)  評(píng)論(1)    收藏  舉報(bào)
      主站蜘蛛池模板: 九九热在线视频精品免费| 长寿区| 无码乱人伦一区二区亚洲| 亚洲V天堂V手机在线| 精人妻无码一区二区三区| 精品久久精品久久精品久久| av色国产色拍| 亚洲av午夜福利精品一区二区| 乱女乱妇熟女熟妇综合网| 久久国内精品一国内精品| 亚洲av永久无码精品成人| 97人人添人人澡人人澡人人澡| 午夜一区欧美二区高清三区| 深田えいみ禁欲后被隔壁人妻| 国产精品一区中文字幕| 丰满无码人妻热妇无码区| 激情国产一区二区三区四区| av深夜免费在线观看| 久久久精品波多野结衣av| 亚洲综合黄色的在线观看| 中文文字幕文字幕亚洲色| 亚洲热妇无码av在线播放| 亚洲午夜无码久久久久小说| 日韩一级伦理片一区二区| 亚洲精品无amm毛片| 久久一日本综合色鬼综合色| 国产成人精品亚洲精品日日| 91福利国产成人精品导航| 国产v综合v亚洲欧美大天堂| 国产一区二三区日韩精品| 9191国语精品高清在线| 国产对白老熟女正在播放| 国产乱码精品一区二区上| 色老板精品无码免费视频| 免费人成网站免费看视频| 亚洲精品成人综合色在线| 亚洲一区二区日韩综合久久 | 久久久久久伊人高潮影院| 德清县| 国产精品99久久免费| 久久99国产精品久久99小说|