intlogicalShift(intx,intn){/*
* Mask the highest n bits after doing right shifts,
* especially for negative numbers.
*/intmask=~(((0x1<<31)>>n)<<1);return(x>>n)&mask;}
intbitCount(intx){/* Add adjacent bits together each time. */intmask16=0x55|(0x55<<8);intmask8=0x33|(0x33<<8);intmask4=0x0f|(0x0f<<8);intmask2=0xff|(0xff<<16);intmask1=0xff|(0xff<<8);mask16=mask16|(mask16<<16);mask8=mask8|(mask8<<16);mask4=mask4|(mask4<<16);x=(x&mask16)+((x>>1)&mask16);x=(x&mask8)+((x>>2)&mask8);x=(x&mask4)+((x>>4)&mask4);x=(x&mask2)+((x>>8)&mask2);x=(x&mask1)+((x>>16)&mask1);returnx;}
intfitsBits(intx,intn){/*
* Convert x to a non-negative number in advance for convenience. If a
* non-negative number can be represented as an n-bit, two's complement
* integer, it should become 0 after doing right shift by (n - 1) times.
*/intsign=x>>31;x=(x&~sign)+(~x&sign);// x = x < 0 ? ~x : x;
return!(x>>(n+~0));}
intisLessOrEqual(intx,inty){/*
* If x and y have the same sign, judge the sign of (y - x);
* otherwise, the negative one is smaller than the positive one.
*/intsign_diff=x^y;intdiff=y+~x+1;return(((sign_diff&x)|(~sign_diff&~diff))>>31)&0x1;}
intilog2(intx){/* Find the highest 1 in x through binary search. */intresult=(!!(x>>16))<<4;result+=(!!(x>>(result+8)))<<3;result+=(!!(x>>(result+4)))<<2;result+=(!!(x>>(result+2)))<<1;result+=(!!(x>>(result+1)));returnresult;}
13 float_neg
题目
Return bit-level equivalent of expression $-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 representations of single-precision floating point values.
unsignedfloat_neg(unsigneduf){/*
* If uf is NaN, return uf;
* otherwise, convert the sign bit to the opposite.
*/unsignedsign_mask=0x1<<31;unsignedexp_mask=0xff<<23;unsignedfrac_mask=0x7fffff;unsignedexp=uf&exp_mask;unsignedfrac=uf&frac_mask;if(exp==exp_mask&&frac)returnuf;// uf is NaN
returnuf^sign_mask;}
14 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.
unsignedfloat_i2f(intx){unsignedint_min=0x80000000;unsignedexp=31;unsignedcarry=0;unsignednew_x=0;/* Deal with special cases. */if(x==0)return0;if(x==int_min)return0xcf000000;/* Convert x to positive for convenience. */if(x<0){x=-x;/* Set the sign bit. */new_x|=int_min;}/* Move the fraction bits to the top. */while(!(x&int_min)){x<<=1;--exp;}/* Set the exponent bits. */new_x|=(exp+127)<<23;/* Judge whether carry is 0 or 1. */if((x&0x1ff)==0x180||(x&0xff)>0x80)carry=1;// else carry = 0;
/* Set the fraction bits. */new_x|=(x>>8)&0x7fffff;new_x+=carry;returnnew_x;}
15 float_twice
题目
Return bit-level equivalent of expression $2f$ 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.
unsignedfloat_twice(unsigneduf){/* Deal with special cases. */unsignedsign_mask=0x1<<31;unsignedexp_mask=0xff<<23;unsignedsign=uf&sign_mask;unsignedexp=uf&exp_mask;if(uf==0||uf==sign_mask)returnuf;// uf is +0 / -0
if(exp==exp_mask)returnuf;// uf is NaN
if(exp==0)return(uf<<1)|sign;// uf is a subnormal number
returnuf+(0x1<<23);}