@
目錄
實驗要求
給出15個函數,規定了實現每個函數需要的邏輯和算術操作符(規定數量)。
只能使用規定的操作符! ˜ & ˆ | + << >>
1-12題不能使用循環或者條件語句
不能使用超過8位的常數(ff)
轉載請注明出處:https://www.cnblogs.com/ustca/p/11740382.html
實現代碼
1、pow2plus1
/*
* pow2plus1 - returns 2^x + 1, where 0 <= x <= 31
*/
int pow2plus1(int x) {
/* exploit ability of shifts to compute powers of 2 */
return (1 << x) + 1;
}
2、pow2plus4
/*
* pow2plus4 - returns 2^x + 4, where 0 <= x <= 31
*/
int pow2plus4(int x) {
/* exploit ability of shifts to compute powers of 2 */
int result = (1 << x);
result += 4;
return result;
}
3、bitXor
/* bitXor - x^y using only ~ and &
* Example: bitXor(4, 5) = 1
* Legal ops: ~ &
* Max ops: 14
* Rating: 1
*/
int bitXor(int x, int y) {
return (~(x&y))&(~(~x&~y));//列出真值表
}
4、tmin
/* tmin - return minimum two's complement integer
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 4
* Rating: 1
*/
int tmin(void) {
return 1<<31;//0x80000000
}
5、isTmax
/* isTmax - returns 1 if x is the maximum, two's complement number,
* and 0 otherwise
* Legal ops: ! ~ & ^ | +
* Max ops: 10
* Rating: 1
*/
int isTmax(int x) {
return !(x+x+2) & !!(~x);//x+1+x+1溢出並且非全一
//x: 0111 1111 1111 1111 1111 1111 1111 1111
//x+1: 1000 0000 0000 0000 0000 0000 0000 0000
//x+1+x: 1111 1111 1111 1111 1111 1111 1111 1111
//x+1+x+1:0000 0000 0000 0000 0000 0000 0000 0000
}
6、allOddBits
/* allOddBits - return 1 if all odd-numbered bits in word set to 1
* where bits are numbered from 0 (least significant) to 31 (most significant)
* Examples allOddBits(0xFFFFFFFD) = 0, allOddBits(0xAAAAAAAA) = 1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 12
* Rating: 2
*/
int allOddBits(int x) {
x = (x>>16) & x;
x = (x>>8) & x;
x = (x>>4) & x;
x = (x>>2) & x;
return (x>>1)&1;
// &運算符的“歸一性”
//1010 1010 1010 1010 1010 1010 1010 1010
//0000 0000 0000 0000 1010 1010 1010 1010
//0000 0000 0000 0000 0000 0000 1010 1010
//0000 0000 0000 0000 0000 0000 0000 1010
//0000 0000 0000 0000 0000 0000 0000 0010
// 可以反推理解:后四位四次翻轉得第一行
// 只要倒數第二位為1成立,反推后所有的奇數位都為1
}
7、negate
/* negate - return -x
* Example: negate(1) = -1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 5
* Rating: 2
*/
int negate(int x) {
return ~x+1; //帶符號位取反加一即為相反數
}
8、isAsciiDigit
/* isAsciiDigit - return 1 if 0x30 <= x <= 0x39 (ASCII codes for characters '0' to '9')
* Example: isAsciiDigit(0x35) = 1.
* isAsciiDigit(0x3a) = 0.
* isAsciiDigit(0x05) = 0.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 15
* Rating: 3
*/
int isAsciiDigit(int x) {
// 0x30 = 0011 0000b 0x39 = 0011 1001b
int a = (x>>4) ^ 0x3; // 判斷5、6位是否全1
int b0 = (x>>3) & 1; // 判斷第4位是否為1
int b1 = (x>>2) ^ 1; // 判斷第3位是否為1
int b2 = (x>>1) ^ 1; // 判斷第2位是否為1
return (!a) & ((!b0) | (b0&b1&b2));
// 如果5、6位全1 且 (4位為0或4位為1,2、3位為0)
}
9、conditional
/* conditional - same as x ? y : z
* Example: conditional(2,4,5) = 4
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 16
* Rating: 3
*/
int conditional(int x, int y, int z) {
x = !x; // 將x設置為0或1
x = (x<<31)>>31; // 將x的0或1拓展到32位全0或全1
return (~x&y) | (x&z); // x為真則~x全1返回y,為假則x全1返回z
}
10、isLessOrEqual
/* isLessOrEqual - if x <= y then return 1, else return 0
* Example: isLessOrEqual(4,5) = 1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 24
* Rating: 3
*/
int isLessOrEqual(int x, int y) {
int z,s,sx,sy;
sx = (x>>31)&1; // 取x的符號位
sy = (y>>31)&1; // 取y的符號位
z = x + ~y + 1; // z = x-y
s = ((z>>31) & 1) | (!(z^0));
// 取z的符號位,s為真時x<y或者z全0(x==y)
return ((!(sx^sy))&s) | (sx&(!sy));
// xy同號且z<=0 或 x<=0 y>=0
}
11、logicalNeg
/* logicalNeg - implement the ! operator, using all of
* the legal operators except !
* Examples: logicalNeg(3) = 0, logicalNeg(0) = 1
* Legal ops: ~ & ^ | + << >>
* Max ops: 12
* Rating: 4
*/
int logicalNeg(int x) {
// |運算符的“分裂性”
x |= x>>16; // 若高16位有1,則傳遞給低16位的對應位
x |= x>>8; // 若低16位的高8位有1,則傳遞給低8位的對應位
x |= x>>4; // 若低8位的高4位有1,則傳遞給低4位的對應位
x |= x>>2; // 若低4位的高2位有1,則傳遞給低2位的對應位
x |= x>>1; // 若低2位的高1位有1,則傳遞給最低1位
x ^= 1; // 只要x包含1,則必定會導致此時的x為1,x^=1即取反
return x&1;
}
12、howManyBits
/* howManyBits - return the minimum number of bits required to represent x in
* two's complement
* Examples: howManyBits(12) = 5
* howManyBits(298) = 10
* howManyBits(-5) = 4
* howManyBits(0) = 1
* howManyBits(-1) = 1
* howManyBits(0x80000000) = 32
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 90
* Rating: 4
*/
int howManyBits(int x) {
int s,c1,c2,c3,c4,c5,c6;
int cnt = 0; // 計數
s = (x>>31)&1; // 符號位
x = ((s<<31)>>31) ^ x; // 取反x
s = !!(x>>16); // 判斷高16位是否有1,有則s為1
c1 = s<<4; // 若高16位有1,則低16位可以計數16
x >>= c1; // 右移將已經計數的位移除,c1若為0,則用折半的長度判斷
s = !!(x>>8); // 用8位的長度去判斷,有效位的個數計入c2
c2 = s<<3;
x >>= c2;
s = !!(x>>4); // 用4位的長度去判斷,有效位的個數計入c3
c3 = s<<2;
x >>= c3;
s = !!(x>>2); // 用2位的長度去判斷,有效位的個數計入c4
c4 = s<<1;
x >>= c4;
s = !!(x>>1); // 用1位的長度去判斷,有效位的個數計入c5
c5 = s;
x >>= c5;
c6 = !!x; // 判斷最低位是否為1
cnt = c1+c2+c3+c4+c5+c6+1; // 將每次獲得的低位有效位相加,再加1位符號位
return cnt;
}
13、floatScale2
/* floatScale2 - Return bit-level equivalent of expression 2*f for
* floating point argument f.
* Both the argument and result are passed as unsigned int's, 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 floatScale2(unsigned uf) {
unsigned f = uf;
if ((f & 0x7F800000) == 0)// 如果階碼為0
f = ((f & 0x007FFFFF) << 1) | (0x80000000 & f);
// 尾數不為0則尾數左移1位,尾數第1位為1則階碼加1,尾數為0則uf為0返回0
else if ((f & 0x7F800000) != 0x7F800000)// 如果階碼不為0,且非全1
f = f + 0x00800000;// 階碼加1
return f;
}
14、floatFloat2Int
/* floatFloat2Int - 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.
* Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
* Max ops: 30
* Rating: 4
*/
int floatFloat2Int(unsigned uf) {
unsigned INF = 1<<31; // INF = MaxInt+1
int e = (uf>>23) & 0xff;// 階碼
int s = (uf>>31) & 1; // 符號位
if (uf == 0) return 0;
uf <<= 8; // 左移保留至階碼最后1位
uf |= 1<<31; // 階碼最后一位設為1
uf >>= 8; // 高八位全0
e -= 127; // 階數
if ((uf & 0x7f80000) == 0x7f80000 || e >= 32)
return INF; // 超過int范圍返回INF
if (e < 0) // 小數返回0
return 0;
if (e <= 22) // 位數小於等於22位,尾數位右移
uf >>= 23-e;
else
uf <<= e-23; // 尾數大於22位,尾數為左移
if (s)
uf = ~uf + 1;// 若原uf為負數,則對此處的正數uf取反加1得其相反數
return uf;
}
15、floatPower2
/* floatPower2 - Return bit-level equivalent of the expression 2.0^x
* (2.0 raised to the power x) for any 32-bit integer x.
*
* The unsigned value that is returned should have the identical bit
* representation as the single-precision floating-point number 2.0^x.
* If the result is too small to be represented as a denorm, return
* 0. If too large, return +INF.
*
* Legal ops: Any integer/unsigned operations incl. ||, &&. Also if, while
* Max ops: 30
* Rating: 4
*/
unsigned floatPower2(int x) {
unsigned INF = 0xff << 23; // 階碼全1
int e = 127 + x; // 得到階碼
if (x < 0) // 階數小於0直接返回0
return 0;
if (e >= 255) // 階碼>=255直接返回INF
return INF;
return e << 23;
// 直接將階碼左移23位,尾數全0,規格化時尾數隱藏有1個1作為底數
}