2.57:
void show_short(short s);
void show_long(long long l);
void show_double(double d);
void show_bytes(char *p, int size);
void show_short(short s) {
printf("the value of short %d is:", s);
show_bytes((char *)&s, sizeof(short));
}
void show_long(long long l) {
printf("the value of short %lld is:", l);
show_bytes((char *)&l, sizeof(long long));
}
void show_double(double d) {
printf("the value of short %lf is:", d);
show_bytes((char *)&d, sizeof(double));
}
2.58:
/*
* 1 in little_endian
* *((char *)&i) means :
* 01 00 00 00 ----> 01
*/
int is_little_endian() {
int i = 1;
return *((char *)&i);
}
2.59:
int graft(int x, int y) {
return (x & 0xff) | (y & ~0xff); //或也可以改成+
}
2.60:
unsigned int graft2(unsigned int x,unsigned char y, int offset) {
return (x & ~(0xff << (offset << 3))) | (((unsigned int)y) << (offset << 3));
}
2.61:
//A
return !~x;
//B
return !x;
//C
return !~((x >> ((sizeof(int) - 1) << 3));
//D
return !(x & 0xff);
2.62:
return ~((~0)>>1); //~0 = -1
2.63:
int sra(int x, int k) {
//arithmetically
int xsrl = (unsigned) x >> k;
unsigned first_bit = x & (0x1 << (sizeof(int) * 8 - 1));
return xsrl + (((!first_bit) + ~0) << (sizeof(int) * 8 - k));
}
unsigned srl(unsigned x, int k) {
//logically
unsigned xsra = (int) x >> k;
unsigned first_bit = x & (0x1 << (sizeof(int) * 8 - 1));
return xsra & ~(~0 << (sizeof(int) * 8 - k));
}
2.64:
int any_even_one(unsigned x) {
return !!(x & 0xaaaaaaaa);
}
2.65:
int even_ones(unsigned x) {
x ^= (x >> 16);
x ^= (x >> 8);
x ^= (x >> 4);
x ^= (x >> 2);
x ^= (x >> 1);
return !(x & 0x1);
}
2.66:
int leftmost_one(unsigned x) {
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
return (x>>1) + 1;
}
2.67:
int int_size_is_32(){
int set_msb = 1 << 31;
int beyond_msb = (1 << 16) << 16;
return set_msb && !beyond_msb;
}
int better_int_size_is_32() {
int seb_msb = ((1 << 8) << 8) << 15;
int beyond_msb = (((1 << 8) << 8) << 8) << 8;
return seb_msb && !beyond_msb;
}
2.68:
//原题有点歧义,参数x没起到作用,于是把题目改成把x最低n位变成1
int lower_byte(int x, int n) {
return x | ((unsigned)(~0) >> (sizeof(int) * 8 - n));
}
2.69:
unsigned rotate_right(unsigned x, int n) {
return (x >> n) + ((x << (sizeof(int) * 8 - n - 1)) << 1);
}
2.70:
int fits_bits(int x, int n) {
x >>= (n - 1);
return !x || !(x + 1);
}
2.71:
return ((int)word << (3 - bytenum << 3)) >> (3 << 3);
2.72:
A:size_t是无符号类型,在和int类型计算的时候,int类型会被转换,得出的结果也是无符号的,所以始终都大于0
B:maxbytes > 0 && maxbytes >= sizeof(val)
2.73:
int saturating_add(int x, int y) {
int r = x + y;
int tmp = r;
int w = (sizeof(x) << 3) - 1;
//x,y,r,取各自的符号位
x >>= w;
y >>= w;
r >>= w;
//正溢出时x,y为0,算数位移计算出的r为0xffffffff => 计算出pos_of = 0xffffffff
int pos_of = (~x)&(~y)&r;
//负溢出时x,y为0xffffffff,r为0
int neg_of = x & y & (~r);
//统统使用位运算
return (pos_of & TMAX) | (neg_of & TMIN) | tmp;
}
2.74
int tsub_ovf(int x, int y) {
int r = x - y;
x >>= (sizeof(int) << 3) - 1;
y >>= (sizeof(int) << 3) - 1;
r >>= (sizeof(int) << 3) - 1;
return (x != y)&&(r == y);
}
2.75:
unsigned unsigned_high_prod(unsigned x, unsigned y) {
//divide x(or y) into two parts the highest bit(xt or yt) and others(xr or yr) like this:
//x => 0 000000000000000000000000000000
//unsigned x * y = (xt * 2^31 + xr) * (yt * 2^31 + yr) = xr * yr + xt * 2^31 * yr + yt * 2^31 * xr + xt * yt * 2^62
//and (unsigned) xr = (int)xr.So we can use the signed_high_prod() to calculate xr * yr
unsigned xt = x >> sizeof(unsigned) - 1;
unsigned yt = y >> sizeof(unsigned) - 1;
unsigned xr = x & ~(1 << sizeof(unsigned) - 1);
unsigned yr = y & ~(1 << sizeof(unsigned) - 1);
return signed_high_prod(xr, yr) +
(xt & yt) << 30 +
(unsigned)(((int)xt << 31 >> 31) & yr) >> 1 +
(unsigned)(((int)yt << 31 >> 31) & xr) >> 1 +
add_of(xr * yr, (unsigned)(((int)xt << 31 >> 31) & yr) << 31,(unsigned)(((int)yt << 31 >> 31) & xr) << 31);
}
2.76:
1. x << 2 + x
2. x << 3 + x
3. x << 5 - x << 1
4. x << 3 - x << 6
2.77:
//c语言除法规则是向零舍去
int divide_power2(int i, int k) {
return (i + ((1 << k) - 1) * (i < 0)) >> k;
}
2.78:
//参考了网上思路
//设x 为 b[w - 1], b[w - 2] ... b1, b0
//x * 5 => (x << 2) + x
//x * 5 / 8 = >
//(b[w - 3] ... b1, b0, 0, 0 + b[w - 1] ... b1, b0) >> 3 等价于
//b[w - 3] ... b1 + b[w - 1] ... b3 + (b1 & b2)
//并且 当x < 0时 需要进行舍入 也就是 x<0 && (x&0x7)时 结果需要加1
int mul5div8(int x) {
int b0 = x & 1;
int b2 = x & 0x4;
int result = (x >> 1) + (x >> 3) + (b0 && b2);
result += (x >> ((sizeof(int) << 3) - 1)) && (x&0x7);
return result;
}
int main() {
int i = 0x80000000;
while(i < 0x7fffffff) {
int ans_me = mul5div8(i);
int ans_std = (long)5 * i / 8;
if(ans_me != ans_std)
printf("%d %d %d\n", i, ans_me, ans_std);
i++;
}
}
2.80:
1. (~0) << n
2. ((~0) << m) + (0x1 <<(m + n))
2.81:
1. false y = TMIN
2. true
3. false x = 0, y = 0
4. true
5. true
2.82
∑nn=1Y2kn
2.83~2.90忘保存了..
2.91 ~ 2.96
工具函数
float u2f(unsigned u) {
return *((float*)&u);
}
unsigned f2u(float f) {
return *((unsigned*)&f);
}
int NaN(float_bits f) {
int exp = (f>>23) & 0xff;
int frac = f & 0x7fffff;
return exp == 0xff && frac != 0;
}
int is_INF(float_bits f){
int exp = (f>>23) & 0xff;
int frac = f & 0x7fffff;
return exp == 0xff && frac == 0;
}
int float_equal(float_bits f1, float f2) {
return f1 == f2u(f2);
}
//测试函数,对于不同的题目需要进行相应的修改
int test(int (*fun1)(float_bits), int (*fun2)(float)) {
unsigned u = 0;
do{
int me = fun1(u);
int std = fun2(u2f(u));
if(me != std)
printf("error!!!\nu= %d, %x \nme is %x \nstd is %x \n", u, u, me, std);
u++;
}while(u!=0);
printf("all finished");
return 0;
}
2.91:
//isnan 和 fabs 都是math.h中的方法
float_bits float_absval(float_bits f) {
return NaN(f) ? f : f&~(1<<(sizeof(float_bits)<<3) - 1);
}
float myfabs(float f) {
if(isnan(f)) return f;
else return fabs(f);
}
2.92:
float_bits float_negate(float_bits f) {
if(NaN(f)) return f;
else return f + (1 << (sizeof(float_bits)<<3) - 1);
}
float myfneg(float f) {
if(isnan(f)) return f;
return -f;
}
2.93:
float_bits float_half(float_bits f) {
if(NaN(f) || is_INF(f)) return f;
unsigned sign = f & 0x80000000;
unsigned exp = f & 0x7f800000;
if(exp > 0x00800000) return f - 0x00800000;
f &= ~(1<<31); //需要位移 先舍去符号位
//向偶数舍入
unsigned b1 = f & 0x2;
unsigned b0 = f & 0x1;
b1 >>= 1;
f >>= 1;
f += (b1 & b0);
return sign + f;
}
float myhalf(float f) {
if(isnan(f)) return f;
return f / 2;
}
2.94:
float_bits float_twice(float_bits f) {
if(NaN(f) || is_INF(f)) return f;
unsigned sign = f & 0x80000000;
unsigned exp = f & 0x7f800000;
if(exp == 0) return (f << 1) + sign; //非规格化时
else if(exp == 0x7f000000) return sign + 0x7f800000; //计算以后会产生溢出时
return f + 0x00800000;
}
float mytwice(float f) {
if(isnan(f)) return f;
else return f*2;
}
2.95:
//乱的一比 等有时间再改改
float_bits float_i2f(int i) {
if(i == 0) return 0; //0
if(i == 0x80000000) return 0xcf000000; //TMin
unsigned sign = i & 0x80000000;
if(i < 0) i = -i; //统一正负数
unsigned x = i & 0x7fffffff;
unsigned exp = 0x3f800000; //设置阶码为Bias(数值0)
unsigned frac = 0;
int pos = 0;
while((x>>=1)!=0) //最高位所在的位置,0<=pos&&pos<=31
pos++;
x = i & 0x7fffffff;
if(pos <= 23) //pos <= 23不需要考虑舍入的情况
frac = (x<<23 - pos) & 0x007fffff;
else{ //需要考虑舍入,
unsigned b0 = x & ~((~0) << pos - 23);
unsigned b1 = (x >> pos - 23) & 1;
if(b0 > (1 << pos - 24) || (b0 == (1 << pos - 24) && b1 == 1))
x += (1 << pos - 23);
frac = (x >> pos - 23) & 0x007fffff;
//最容易被忽略的 在舍入中产生了进位
if((x >> pos + 1) == 1) pos++;
}
exp += pos << 23;
return sign + exp + frac;
}
float myi2f(int i) {
return (float)i;
}
2.96:
//做完上一题以后这道题就清爽了好多
#define BIAS 0x3f800000
int main() {
test(float_f2i, myf2i);
return 0;
}
int float_f2i(float_bits f) {
int ans = 0;
unsigned sign = f & 0x80000000;
unsigned exp = f & 0x7f800000;
unsigned frac = f & 0x007fffff;
frac += 0x00800000;
if(exp < BIAS) return 0; //f < 1
if(exp > BIAS + (30 << 23)) return 0x80000000; //f > TMax
int pos = (exp - BIAS) >> 23;
if(pos <= 23) ans = frac >> 23 - pos;
else ans = frac << pos - 23;
return sign == 0 ? ans : -ans;
}
int myf2i(float f) {
return f;
}