1.用~和&运算实现异或(^)操作
//*
* 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);
- }
2.求二进制补码最小值
/*
* tmin - return minimum two's complement integer
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 4
* Rating: 1
*/
- int tmin(void) {
-
- return 1<<31;
-
- }
3.判断一个数是否为补码表示的最大值
/*
* isTmax - returns 1 if x is the maximum, two's complement number,
* and 0 otherwise
* Legal ops: ! ~ & ^ | +
* Max ops: 10
* Rating: 1
*/
方法一:
补码表示的最大值为:0x 7fff ffff,其用二进制表示就是0111 1111 .... 1111
我们发现,当0x 7fff ffff加1就变成了tmin,也就是1000 0000 .... 0000
那么,把tmin减1就可以得到这个补码表示的最大值了,由于不能用减号,我们可以加-1,而-1可以写成~0x1+1
- int isTmax(int x) {
- int ans=0x1<<31;
- int max=ans+(~0x1+1);
- return !(max-x);
- }
方法二:
以四位为例,则最大值为x=0111,我们将x+1后再取反,又得到了x。
不信你看,x+1=1000,~(x+1)=0111,因此我们用异或操作来判断它是不是最大值->~(x+1)^x。
不过,这种方法有个特例。当x=-1时,也就是x=1111,x+1=0000(发生了溢出),~(x+1)=1111,
~(x+1)^x =1111,所以要加一个判断条件,判断它是不是-1
- int isTmax(int x) {
- return !(~(x+1)&x) && !!(x+1);
- }
4.判断是否所有的奇数位的数字都为1
/*
* 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
*/
构造所有奇数位为1的数——0x AAAA AAAA(也就是1010 1010 1010 .... 1010),注意,最右边的一位是第0位哦~
然后我们将x与0x AAAA AAAA做&运算,这可以只保留x的奇数位,再判断其与0x AAAA AAAA是否相等即可,若相等则得0,!0=1;若不相等则得1,!1=0
- int allOddBits(int x) {
- int a=0xAA<<8;
- int b=0xAA<<16;
- int c=0xAA<<24;
- int d=a|b|c;
- return !((x&d)^d);
- }
5.不用"-",求-x
/*
* negate - return -x
* Example: negate(1) = -1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 5
* Rating: 2
*/
x+(-x)=0,而x+(~x)=-1,可得(-x)= (~x)+1
- int negate(int x) {
- return ~x+1;
- }
6.计算输入值是否为0-9的ASCII值
/*
* 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
*/
其实我觉得吧,不会做题主要是没有耐心看题目,现在重新回头看看这些题,倒也没有想象中的那么难了。
这道题其实就是让我们判断输入值是否在[0x30,0x39]之间
0x30的位级表示为0011 0000,0x39的位级表示为0011 1001
对于输入值x,我们要先满足x<<4==3,也就是得到x的前四位,前四位要等于3,然后后四位在0-9之间就好了。
首先,我们可以用x & 0xF来保留x的后四位(&运算——与1相与是本身,与0相与是0)
7.使用位级运算实现C语言中的
x?y:z
三目运算符/*
* conditional - same as x ? y : z
* Example: conditional(2,4,5) = 4
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 16
* Rating: 3
*/
好的,什么是三目运算符呢?我来简单说一下。
就是可以把它看成一个if-else语句,如果满足条件x,则执行y,否则执行z
这道题就可以看成if(x!=0) return y; else return z;
- int conditional(int x, int y, int z) {
- x = !!x;
- x = ~x+1;
- return (x&y)|(~x&z);
- }
我们需要寻找一种方法,当x!=0的时候让x变成0x FFFF FFFF
1取反后加1就是0x FFFF FFFF了,那么怎样得到1呢?就用两个非运算就可以了。当x!=0时,第一次非运算得到0,再进行一次非运算就可以得到1了。
若x!=0,则x经过一系列运算变成了0x FFFF FFFF,再和y进行与运算就可以保留y的值了;把x取反,变成了0x 0000 0000,与z进行与运算还是0
若x==0,则x经过一系列运算变成了0x 0000 0000,与y进行与运算变成0;取反后成为0x FFFF FFFF,和z进行与运算得z的值
完蛋,这道题把我也绕晕了
希望有朋友可以教教我TUT
8.使用位级运算实现<=;如果x<=y,则返回1;否则返回0
/*
* isLessOrEqual - if x <= y then return 1, else return 0
* Example: isLessOrEqual(4,5) = 1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 24
* Rating: 3
*/
判断x<=y有两种方法,一个是x和y的符号相同,且y-x>=0;一个是x和y的符号不同,但x<0
- int isLessOrEqual(int x, int y) {
- int negX=~x+1;//-x
- int addX=negX+y;//y-x
- int checkSign = addX>>31&1; //y-x的符号
- int leftBit = 1<<31;//最大位为1的32位有符号数
- int xLeft = x&leftBit;//x的符号
- int yLeft = y&leftBit;//y的符号
- int bitXor = xLeft ^ yLeft;//x和y符号相同标志位,相同为0不同为1
- bitXor = (bitXor>>31)&1;//符号相同标志位格式化为0或1
- return ((!bitXor)&(!checkSign))|(bitXor&(xLeft>>31));
- //返回1有两种情况:符号相同标志位为0(相同)位与y-x 的符号为0(y-x>=0)结果为1;符号相同标志位为1(不同)位与x的符号位为1(x<0)
- }
9. 使用位级运算求逻辑非
!
/*
* 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
*/
我们知道-x=(~x)+1,当x>0时,((~x)+1)>>31得1;当x<=0时,((~x)+1)>>31得0。所以我们还要处理x=0和x<0的情况。
我们可以将x和((~x)+1)进行或运算再右移31位,如果(x | (~x)+1)>>31为0,则说明x等于0;如果(x | (~x)+1)>>31为1,则说明x!=0。
- int logicalNeg(int x) {
- return ((x|(~x)+1)>>31)+1;
- }
10. “一个数用补码表示最少需要几位?”
/* 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 y=~x;
- int tmp1=!((1<<31)&x);
- int tmp2=!((1<<31)&y);
- tmp1=~tmp1+1;
- tmp2=~tmp2+1;
-
- int tmp=(tmp1&x)+(tmp2&y);
-
- tmp=tmp|tmp>>1;
- tmp=tmp|tmp>>2;
- tmp=tmp|tmp>>4;
- tmp=tmp|tmp>>8;
- tmp=tmp|tmp>>16;
- int mask=1;
- mask=(mask<<8)|1;
- mask=(mask<<8)|1;
- mask=(mask<<8)|1;
- int sum=0;
- sum+=tmp&mask;
- sum+=(tmp>>1)&mask;
- sum+=(tmp>>2)&mask;
- sum+=(tmp>>3)&mask;
- sum+=(tmp>>4)&mask;
- sum+=(tmp>>5)&mask;
- sum+=(tmp>>6)&mask;
- sum+=(tmp>>7)&mask;
- return ((sum&0xff)+((sum>>8)&0xff)+((sum>>16)&0xff)+((sum>>24)&0xff))+1;
- }
11.求2*一个浮点数
/*
* 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 sign = uf & 0x80000000;
- unsigned frac = uf & 0x7fffff;
- if(exp ^ 0x7f800000){//exp!=255
- if(!exp){//exp==0
- frac <<= 1;//此时为非规格化数,尾数无隐含常数1,直接左移1位即可
- }
- else{//0
- exp += 0x800000;//乘2
- if((exp ^ 0x7f800000)==0){//判断乘2以后是否溢出
- frac=0;//输出INF
- }
- }
- }
- return sign | exp | frac;
- }
12.将浮点数转化为整数
/*
* 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 = 0x80000000;
- //提取符号位
- int s = (uf >>31) & 0x1;
- //提取阶码
- int E = uf >> 23 & 0xff;
- //提取阶数
- int e = E -127;
- if (uf == 0) return 0;
- //因为输入是规格化浮点数,转化为整数时第23位需要为1
- uf &= 0x00ffffff;
- uf |= 0x00800000;
- //浮点数中0~22位的数字逻辑上位小数,当看作整数时相当于乘以了2^23
- //阶码为255或阶数大于等于32时,视为溢出,输出INF.因为int为32bit,超出即溢出,且考虑1bit符号位
- if ((uf & 0x7f80000) == 0x7f80000 || e>= 32) return INF;
- if (e<0) return 0;//若为小数,返回零
- //无符号数的移位运算都是逻辑移位
- if (e <= 23) uf >>= 23 - e;//因为浮点数尾数宽度为23bit,位数小于等于23,尾数位右移.这是一种舍入方式
- else uf <<= e-23;//位数大于23,尾数左移
-
- //当符号位为负数,uf要取值为它的相反数
- if(s) uf = ~uf + 1;
- return uf;
- }
13.求2.0^x
/*
* 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) {
- //int INF = 0xff << 23;
- int INF = 0x7f800000;
- int exp = x + 127 ;
- //溢出
- if(exp >= 255) return INF;
- //为小数时
- if(exp <= 0) return 0;
-
- return exp<<23;
- }
太痛苦了!真的!后面的三个题等我缓过来再写吧……
然后,这个答案吧不完全对,有很多小细节我还没来得及一个一个改,还是等我缓过来再写吧……