P70
#include <stdio.h>
int fits_bits(int x,int n){
int w=sizeof(int)<<3;
return x == x<<(w-n)>>(w-n);
}
int main(){
printf("%d\n",fits_bits(114514,19));
}
P71
- A
这个函数不能从word中提取一个负值的byte。 - B
#include <stdio.h>
typedef unsigned packed_t;
int xbyte(packed_t word,int bytenum){
int w = sizeof(unsigned);
int left = (w-bytenum-1)<<3;
int right = (w-1)<<3;
return (int)(word<<left>>right);
}
int main(){
printf("%d\n",xbyte(-114514,0));
}
P72
- A
sizeof返回的值类型是unsigned,所以maxbytes-sizeof(val)的值也是unsigned类型,大于等于0恒成立。 - B
#include <stdio.h>
void copy_int(int val,void* buf,int maxbytes){
if(maxbytes-(int)sizeof(val)>=0)
memcpy(buf,(void*)&val,sizeof(val));
}
int main(){
int max = 114;
void* buff = malloc(max);
copy_int(514,&buff,114);
}
P73
#include <stdio.h>
#include <limits.h>
int saturating_add(int x,int y){
int sum = x+y;
int mask = INT_MIN;
int pos_over = !(x&mask)&&!(y&mask)&&(sum&mask);
int neg_over = (x&mask)&&(y&mask)&&!(sum&mask);
(pos_over&&(sum=INT_MAX))||(neg_over&&(sum=INT_MIN));//这段是求教大佬得到的,实在精妙
return sum;
}
int main(){
printf("%x\n",saturating_add(0x10000000,-1));
}
P74
#include <stdio.h>
#include <limits.h>
int tsub_ok(int x,int y){
int sub = x-y;
return !((x>0&&y<0&&sub<0)||(x<0&&y>0&&sub>0));
}
int main(){
printf("%d\n",tsub_ok(114514,INT_MIN));
}
P75
#include <stdio.h>
#include <inttypes.h>
int signed_high_prod(int x, int y) {
int64_t mul = (int64_t) x * y;
return mul >> 32;
}
unsigned unsigned_high_prod(unsigned x, unsigned y) {
int sig_x = x >> 31;
int sig_y = y >> 31;
int signed_prod = signed_high_prod(x, y);
return signed_prod + x * sig_y + y * sig_x;
}
unsigned test(unsigned x, unsigned y) {
uint64_t mul = (uint64_t) x * y;
return mul >> 32;
}
int main(){
printf("%d\n",test(114514,1919810)==unsigned_high_prod(114514,1919810));
}
P76
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
void* mcalloc(size_t nmemb,size_t size){
if(nmemb==0||size==0)
return NULL;
int tmp = nmemb*size;
if(nmemb==tmp/size){//注意不能与上一行合并写成nmemb==(nmemb*size)/size
void* p = malloc(size);
if(p)
memset(p,0,nmemb);
return p;
}
return NULL;
}
int main(){
printf("%d\n",mcalloc(INT_MAX,INT_MAX));
}
P77
#include <stdio.h>
int mul17(int x){
return (x<<4)+x;
}
int mulm7(int x){
return x-(x<<3);
}
int mul60(int x){
return (x<<6)-(x<<2);
}
int mulm112(int x){
return (x<<4)-(x<<7);
}
int main(){
printf("%d\n",mul17(114514)==17*114514);
printf("%d\n",mulm7(114514)==(-7)*114514);
printf("%d\n",mul60(114514)==60*114514);
printf("%d\n",mulm112(114514)==(-112)*114514);
}
P78
#include <stdio.h>
#include <limits.h>
int divide_power2(int x,int k){
int sig = x&INT_MIN;
(sig&&(x=x+(1<<k)-1));
return x>>k;
}
int main(){
printf("%d\n",divide_power2(-114514,3)==(-114514)/8);
}
P79
#include <stdio.h>
#include <limits.h>
int divide_power2(int x,int k){
int sig = x&INT_MIN;
(sig&&(x=x+(1<<k)-1));
return x>>k;
}
int mul3div4(int x){
x = (x<<1)+x;
return divide_power2(x,2);
}
int main(){
printf("%d\n",mul3div4(114514)==114514*3/4);
}
P80
#include <stdio.h>
#include <limits.h>
int threeforths(int x) {
int sig = x & INT_MIN;
int head = x & ~0x3;
int tail = x & 0x3;
int hdd4 = head >> 2;
int hdd4m3 = (hdd4 << 1) + hdd4;
int tlm3 = (tail << 1) + tail;
int bias = (1 << 2) - 1;
(sig && (tlm3 += bias));
int tlm3d4 = tlm3 >> 2;
return hdd4m3 + tlm3d4;
}
int main(int argc, char* argv[]) {
printf("%d\n",threeforths(-3)==-2);
}
P81
- A
#include <stdio.h>
int patternGenerator(int k){
return (-1<<k);
}
int main(){
printf("%x\n",patternGenerator(8));
}
- B
#include <stdio.h>
int patternGenerator(int k,int j){
return (~((-1)<<k))<<j;//运算符优先级真的坑
}
int main(){
printf("%x\n",patternGenerator(16,8));
}
P82
- A
不是。x=INT_MIN - B
是(即答 - C
是 - D
是 - E
是
P83
- A
- B
a.
b.
c.
P84
#include <stdio.h>
unsigned f2u(float x){
return *(unsigned*)&x;
}
int float_le(float x,float y){
unsigned ux = f2u(x);
unsigned uy = f2u(y);
unsigned sx = ux>>31;
unsigned sy = uy>>31;
return (ux<<1==0&&uy<<1==0)||
(sx&&!sy)||
(!sx&&!sy&&ux<=uy)||
(sx&&sy&&ux>=uy);
}
int main(){
printf("%d\n",float_le(-0,+0));
printf("%d\n",float_le(+0,-0));
}
此段代码非原创,参见https://github.com/DreamAndDead/CSAPP-3e-Solutions/issues/1。