百度做网站,电商网站建设开发的语言有哪些,网页升级访问新区域,优量汇广告平台稳住心态不要慌#xff0c;如果考试周冲突的话#xff0c;可以直接复制这篇博客和上一篇博客西工大计算机学院计算机系统基础实验一#xff08;函数编写1~10#xff09;-CSDN博客最后的代码#xff0c;然后直接提交#xff0c;等熬过考试周之后回过头再慢慢做也可以。
第…稳住心态不要慌如果考试周冲突的话可以直接复制这篇博客和上一篇博客西工大计算机学院计算机系统基础实验一函数编写1~10-CSDN博客最后的代码然后直接提交等熬过考试周之后回过头再慢慢做也可以。
第11个函数rempwr2要求计算x%(2^n)其中0n30。比如rempwr2(15,2) 3, rempwr2(-35,3) -3。什么意思呢意思是15%(2^2)15%43-35%(2^3)-35%8-3。那么我们该怎么做呢先考虑正数当x为15并且n为2时15可写作1111B15%(2^2)即相当于取1111B的低2个比特位即11B正如答案中的3。接着考虑负数-35可写作0xFFFF FFFF FFFF FFDD-3可写作0xFFFF FFFF FFFF FFFD如果像处理正数那样直接截取0xFFFF FFFF FFFF FFDD的第3个比特位的话得到的应该是101B也就是5而不是-3所以负数不能像正数那样被处理。最简单的方法是分类讨论但是那样会使用蛮多的运算符所以尝试使用一种新的思路去处理这个问题。我们可不可以这样子先计算35%(2^3)3然后再把3变为-3呢也就是说先把一个数变成它自己的绝对值然后参与%运算最后再根据最开始这个数的符号位调整最终的结果呢按照这个思路我们首先将x变成它的绝对值可以通过(x(x31))^(x31)来实现当为正时(x(x31))^(x31)的结果仍为x当x为负数时比如x-350xFFFF FFDD那么x310xFFFF FFFFx(x31)的结果是0xFFFF FFDE接着0xFFFF FFDE与0xFFFF FFFF异或得到了0x0000 0023也就是35。当x为负数时(x31)相当于-1接着与x31异或相当于全取反就是根据负数原码求补码的逆过程只不过考虑到表达式(x(x31))^(x31)也综合了x是正数的情况所以不方便直白的写减一后全取反接着当n2时如何产生0000... ...0011当n3时如何产生0000... ...0111呢可以通过(~0)(1n)来产生。~0为0xFFFF FFFF当n3时13为0x8~0(13)即得到了0x0000 0007。这时让((x(x31))^(x31))与~0(1n)进行位与操作即可完成%操作。此时若x是正数则所有步骤已完成但是当x为负数时还需要将最后的结果加一个负号。怎么加负号呢各位取反加1先与x31做异或操作完成各位取反最后减去x31完成加1。结合上述的讲解我们给出代码如 图1编写第11个函数rempwr2 所示。接着仿照前10个函数相同的检查流程如 图2检查第11个函数rempwr2 所示。 int s x31;
x (xs)^s;
x ((~0)(1n));
return (x^s)~s1;
图1编写第11个函数rempwr2 图2检查第11个函数rempwr2 第12个函数satMul2执行算术乘法乘2。怎么做呢如果x为小于0x4000 0000的正数或者为0或者为大于C000 0000的负数那么直接返回x1即可。而当x超出这个范围时就不能直接返回x1了。那如何判断什么时候可以直接返回x1什么时候不能直接返回x1呢发现可以引入变量int x2x1x2表示x*2再引入变量int sx2(x2)31表示x*2的符号位一旦x的符号位与x1的符号位不相同即(x^x2)31的结果为0xFFFF FFFF时就不能直接返回x1而如果x的符号位与x1的符号位相同即(x^x2)31的结果为0x0时就可以直接返回x1所以可以引入变量int flag(x^x2)31并以此作为判断条件。根据已有的知识可以写出下面的大框架
(flag( )) | (~flag( x2 ))
接着如果x的符号位与x1的符号位不相同即(x^x2)31的结果为0xFFFF FFFF不能直接返回x1时该返回什么呢易知此时只需返回0x8000 0000或者0x7FFF FFFF。该如何得知该返回0x8000 0000还是该返回0x7FFF FFFF呢发现这时当x为很大的正数并且x2的符号位为1时sx2为0xFFFF FFFF加上0x8000 0000之后即为0x7FFF FFFF即应该返回的值当x为很小的负数并且x2的符号位为0时sx2为0x0000 0000加上0x8000 0000之后即为0x8000 0000即应该返回的值。而0x8000 0000可写作131。根据这个分析我们进一步完善大框架
(flag( sx2(131) )) | (~flag( x2 ))
这时再思考能不能想办法进行优化以减少运算符使用的个数呢发现当flag为0xFFFF FFFF时(~flag( x2 )中的x2不一定一定为0当~flag为0xFFFF FFFF时(flag( sx2(131) ))中的sx2(131)也不一定一定为0所以不能像第9个函数那样进行优化。因此第12题最终的代码为如 图3编写第12个函数satMul2 所示。 int x2x1;int sx2x231;int flag(x^x2)31;int tmin131;return ((~flagx2)(flag(sx2tmin)));
(图3编写第12个函数satMul2) 然而这道题似乎有问题。为什么呢其实只要简单的return x1就能通过白白耗费我们这么多时间。如 图4检查第12个函数satMul2 所示。 图4检查第12个函数satMul2 第13个函数subOK如果x减去y的值能被int类型大小的变量装得下就返回1否则返回0。接着我们发现当x与y同号时不可能出现装不下也就是溢出的问题只有当x与y异号时才可能会用装不下也就是溢出的问题顺着这个思路我们可以分成两类来讨论。而分类的依据则是x^~y当x与y同号时x^~y的符号位为1当x与y异号时x^~y的符号位为0。顺着这个思路写出下面的大框架
(( (x^~y)( ) | ( ~(x^~y)( ) ) ) 31)1
当x与y同号时x与~y异号x^~y的符号位为1此时x减去y的值一定能被int类型大小的变量装得下所以此时返回1即可。这时大框架即为
(( (x^~y) | ( ~(x^~y)( ) ) ) 31)1
而当x与y异号时x与~y同号x^~y的符号位为0此时如果x与x-yx~y1异号那么必定发生了溢出x减去y的值一定不能被int类型大小的变量装得下所以选择表达式~(x^(x~y1))当x与x-y同号时说明可以装得下应该返回1而~(x^(x~y1))的符号位恰好就是1当当x与x-y异号时说明不可以装得下应该返回0而~(x^(x~y1))的符号位恰好就是0。所以最终的大框架即为
(( (x^~y) | ( ~(x^~y)( ~(x^(x~y1)) ) ) ) 31)1
代码如 图5编写第13个函数subOK 所示。检查过程如 图6检查第13个函数subOK 所示。 int flagx^~y;return ((flag|(~flag(~(x^(x~y1)))))31)1;
图5编写第13个函数subOK 图6检查第13个函数subOK 第14个函数float_twice在这里限制被释放条件判断可以被使用while语句也可以被使用||和也可以被使用而且也可以创建unsigned型的局部变量。那么这个函数要求我们做到什么呢这个函数要求我们对于一个浮点数f计算2*f。举个例子来讲如果f0.625那么其在计算机内部的表示形式为0x3F20 0000计算2*f可以得到0x3FA0 0000而这个0x3FA0 0000就是期待我们返回的值。对不起大家在这里作者实在有点累了所以没办法今天就讲完了。代码如 图7编写第14个函数float_twice 所示。检查第14个函数的过程如 图8检查第14个函数float_twice 所示 unsigned sign 0, enow 0, fnow 0;unsigned pos 1 31;unsigned frule (1 23) - 1;if (uf 0) {return 0;}if (uf pos) {return uf;}sign uf pos;enow (uf 23) 0xff;if (enow 0xff) {return uf;}fnow uf frule;if (enow 0) {fnow fnow 1;if (fnow (1 23)) {fnow fnow frule;enow 1;}}else{enow 1;}return sign | (enow 23) | fnow;
图7编写第14个函数float_twice 图8检查第14个函数float_twice /* * rempwr2 - Compute x%(2^n), for 0 n 30* Negative arguments should yield negative remainders* Examples: rempwr2(15,2) 3, rempwr2(-35,3) -3* Legal ops: ! ~ ^ | * Max ops: 20* Rating: 3*/
int rempwr2(int x, int n) {int s x31;x (xs)^s;x ((~0)(1n));return (x^s)~s1;
}
/** satMul2 - multiplies by 2, saturating to Tmin or Tmax if overflow* Examples: satMul2(0x30000000) 0x60000000* satMul2(0x40000000) 0x7FFFFFFF (saturate to TMax)* satMul2(0x80034000) 0x80000000 (saturate to TMin)* Legal ops: ! ~ ^ | * Max ops: 20* Rating: 3*/
int satMul2(int x) {// int x2x1;// int sx2x231;// int flag(x^x2)31;// int tmin131;return x1;// return ((~flagx2)(flag(~(!!x2)1)(sx2tmin)));// int isx2zero!x2;// int x2notzero!isx2zero;// return ((~flagx2)(flag(~(!!x2)1)(~x2notzero(sx2tmin))));// int istmin!(x^tmin);// return ((istmin31)|((~istmin)((~flagx2)|(flag(sx2tmin)))));
}
/* * subOK - Determine if can compute x-y without overflow* Example: subOK(0x80000000,0x80000000) 1,* subOK(0x80000000,0x70000000) 0, * Legal ops: ! ~ ^ | * Max ops: 20* Rating: 3*/
int subOK(int x, int y) {int flagx^~y;return ((flag|(~flag(~(x^(x~y1)))))31)1;
}
/* * float_twice - Return bit-level equivalent of expression 2*f for* floating point argument f.* Both the argument and result are passed as unsigned ints, but* they are to be interpreted as the bit-level representation of* single-precision floating point values.* When argument is NaN, return argument* Legal ops: Any integer/unsigned operations incl. ||, . also if, while* Max ops: 30* Rating: 4*/
unsigned float_twice(unsigned uf) {unsigned sign 0, enow 0, fnow 0;unsigned pos 1 31;unsigned frule (1 23) - 1;if (uf 0) {return 0;}if (uf pos) {return uf;}sign uf pos;enow (uf 23) 0xff;if (enow 0xff) {return uf;}fnow uf frule;if (enow 0) {fnow fnow 1;if (fnow (1 23)) {fnow fnow frule;enow 1;}}else{enow 1;}return sign | (enow 23) | fnow;
}