深入理解计算机系统第二章家庭作业

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
typedef unsigned char* byte_pointer;
//输入为一个字节序列的地址(起始位置),用一个字节指针和一个字节数来表示,输出为字节表示,每个地址中的值
void show_bytes(byte_pointer start, size_t len)
{
	size_t i;//size_t是unsigned int的别名,在头文件中已经定义
	for (i = 0; i < len; i++)
		printf("%.2x", start[i]);//十六进制格式输出
	printf("\n");
}
int main()
{
	int a = 1;
	byte_pointer b = (byte_pointer)&a;
	show_bytes(b,sizeof(byte_pointer));//01000000cccccccc
	show_bytes(b, sizeof(short));//0100
	show_bytes(b, sizeof(long long ));//01000000cccccccc
	


}

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
typedef unsigned char* byte_pointer;
//输入为一个字节序列的地址(起始位置),用一个字节指针和一个字节数来表示,输出为字节表示,每个地址中的值
void show_bytes(byte_pointer start, size_t len)
{
	size_t i;//size_t是unsigned int的别名,在头文件中已经定义
	for (i = 0; i < len; i++)
		printf("%.2x", start[i]);//十六进制格式输出
	printf("\n");
}
void show_short(short x)
{
	show_bytes((byte_pointer)&x, sizeof(short));
}

void show_double(double x)
{
	show_bytes((byte_pointer)&x, sizeof(double));
}
void show_long(long x)
{
	show_bytes((byte_pointer)&x, sizeof(long));
}


int main()
{
	show_short(11);//0b00
	show_double(11);//0000000000002640
	show_long(11);//0b000000
}

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int is_little_endian()
{
    
        int i = 1;
        char c = (*(char*)&i);

        if (c)
        {
            printf("小端\n");
            return 0;
        }
        else
        {
            return 1;
            printf("大端\n");
        }
    
}
int main()
{
	int a = is_little_endian();

	return 0;
}
//定义变量int i=1;将 i 的地址拿到,强转成char*型,这时候就取到了 i 的低地址,
//这时候如果是1就是小端存储,如果是0就是大端存储。
//大端,是指数据的低位保存在内存的高地址中,而数据的高位保存在内存的低地址中
//小端,是指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int combine(int a, int b)
{
	a = 0xff & a;
	b = (~0xff) & b;
	return a + b;
}
int main()
{
	int a = 0x12345678;
	int b = 0x11111111;
	int c = combine(a, b);
	printf("%x", c);//11111178
	return 0;

}

在这里插入图片描述
在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
unsigned replace_byte(unsigned x, int i, unsigned char b)
{
	int temp = 0xff;
	temp = temp & b;
	temp = temp << i*8;
	printf("%x \n", temp);
	int tempx = 0xff << i * 8;//一个字节有8位,unsigned char的大小位一个字节
	x = x & (~tempx);
	printf("%x\n", x);

	return temp | x;

}
int main()
{
	unsigned a = 0x12345678;
	unsigned char b = 0xAB;
	unsigned c = replace_byte(a, 2, b);
	printf("%x", c);
	
	return 0;

}

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
int judge(int x)
{
	return (!~x) || (!x) || (!~(x | 0xffffff00)) || (!~(x | 0x00ffffff));
}
int main()
{
	return judge(0x00000010);
}

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int int_shifts_are_arithmetic()
{
	int x = ~0x01;
	x = x >> 4;//0xffffffff(算数右移)0x0fffffff(逻辑右移)
	printf("%x\n", x);
	return !(~x);

}
int main()
{
	return int_shifts_are_arithmetic();
}

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
unsigned srl(unsigned x,int k)
{
	unsigned xsra = (int)x >> k;//算术右移
	int w = sizeof(int)<<3;//位数(<<3相当于乘以8)
	unsigned mask = ~(((1 << k) - 1) << (w - k));//((1 << k) - 1) 能获得低位连续为1,高位为0,有k个1,(w-k)使得前k个高位为1,取反则可使前k为0
	return xsra & mask;

}
int sra(int x, int k)
{
	int xsrl = (unsigned)x >> k;//逻辑右移
	int w = sizeof(int) << 3;
	int test = 1 << (w - k - 1);
	int mask = test & xsrl;
	mask = ~(mask - 1);
	return mask | xsrl;


}

在这里插入图片描述

int any_odd_one(unsigned x) {
	unsigned int t = 0x55555555;//0x01010101010101010101010101010101
	return (x & t) != 0;
}

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int odd_ones(unsigned x)
{
	x ^= x >> 1;
	x ^= x >> 2;
	x ^= x >> 4;
	x ^= x >> 8;
	x ^= x >> 16;/最后一位将所有位数的1进行计数
	return x & 1;
}
int main()
{
	int a = odd_ones(0xffff1010);//0
	printf("%x", a);
	int b = odd_ones(0x1110ffff);//1
	printf("%x", b);
	return 0;
}

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
int leftmost_one(unsigned x)
{
	x |= x >> 1;
	x |= x >> 2;
	x |= x >> 4;
	x |= x >> 8;
	x |= x >> 16;//结果是x(32)x(3231)x(323130)...x(32...1)
	return x ^ (x >> 1);
}

在这里插入图片描述

添加链接描述
在这里插入图片描述

int bad_int_size_is_32()
{
	int set_msb = 1 << 31;
	//int beyond_msb = 1 << 32;
	//当移位数过大时,有的编译器会进行取模操作,有的则不会,故代码不是通用的

	int beyond_msb = set_msb;
	beyond_msb <<= 1;
	return set_msb && !beyond_msb;//非零的数都是逻辑真,!是逻辑运算不是取反
}
int int_size_is_32()
{
	int set_msb = 1 << 15;
	set_msb <<= 15;
	set_msb <<= 1;
	int beyond_msb = set_msb;
	beyond_msb <<= 1;
	return set_msb && !beyond_msb;
}

在这里插入图片描述

int lower_one_mask(int n)
{

	int sizeof_int = sizeof(int);
	unsigned x = ~0;//0xffffffff
	x >>= ((sizeof_int << 3) - n);
	return x;
}

在这里插入图片描述
在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
unsigned rotate_left(unsigned x, int n)
{
	int w = sizeof(unsigned) << 3;
	unsigned lower = x >> (w - n);
	unsigned higher = x << n;
	return lower | higher;
}
int main()
{
	unsigned a = rotate_left(0x12345678, 4);
	printf("%x\n", a);
	unsigned b = rotate_left(0x12345678, 20);
	printf("%x\n", b);
	return 0;
}

在这里插入图片描述

//x用n位表示
int fits_bits(int x,int n)
{
	
	unsigned sizeof_int = sizeof(int);
	unsigned w = sizeof_int << 3;
	int y = x << (w-n) >> (w-n);
	return y == x;
}

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
typedef unsigned packed_t;
int xbyte(packed_t word, int bytenum)
{
	//return (word >> (bytenum << 3)) & 0xff;
	//原来代码的问题是在所抽出的字节是负数的情况下得到是无符号数而不是有符号数
	// 当取出的字节为负数时,由于原操作“粗暴”的将高位置零,会返回一个错误的正值。
   //程序比要求的多了一个强制类型转换因为要求的是在算术右移的机器上运行而一般机器是对于无符号逻辑右移
	unsigned left_move = (3 - bytenum) << 3;
	unsigned right_move = (3) << 3;
	return (int)word << left_move >> right_move;

}

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
void copy_int(int val,void *buf,int maxtybes)
{
	//if (maxtybes-sizeof(val) >= 0)
	// size_t is an unsigned integer type
	//maxbytes-sizeof(val)将一直转化为无符号数并永远大于等于零
	if (maxtybes < 0)
		return;
	if(maxtybes>=sizeof(val))
	memcpy(buf, (void*)&val, sizeof(val));
}

在这里插入图片描述
在这里插入图片描述

int saturating_add(int x, int y)
{
	unsigned sizeof_int = sizeof(int);
	int bias = (sizeof(int) << 3) - 1;/
	int i = (x  ^ y )>> bias;//比较符合位是否相同
	int j = ((x+y) ^ x) >> bias;//是否相加后变符号,是否溢出
	int k = x >> bias;//判断正溢出还是负溢出
	return (i & (x + y)) + (~i & (j & ( (~k & INT_MAX) + (k & INT_MIN) )));
}

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
int tsub_ok(int x,int y)
{
	y = -y;
	unsigned sizeof_int = sizeof(int);
	int bias = sizeof_int << 3 - 1;
	int i = (x ^ y) >> bias;
	int j= ((x + y) ^ x) >> bias;
	return i || ~j;
}

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include <stdint.h>
#include <stdbool.h>
unsigned unsigned_high_prod(unsigned x, unsigned y)
{
	unsigned w = sizeof(int32_t) << 3;
	int64_t signed_total_prod = signed_high_prod(x, y);
	signed_total_prod <<= w;
	signed_total_prod += x * y;
	bool x_w = x < 0 ? true : false;
	bool y_w = y < 0 ? true : false;
	int64_t unsigned_total_prod = signed_total_prod + ((x_w * (int)y + y_w * (int)x) << w) + x_w * y_w << (w * 2);
	return (unsigned)(unsigned_total_prod >> w);
}

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include<stddef.h>
typedef unsigned size_t;
void* Calloc(size_t nmemb, size_t size) {
	if (nmemb == 0 || size == 0) return NULL;

	int s = nmemb * size;
	if (s / size == nmemb) {        //检测溢出
		void* p = malloc(s);
		memset(p, 0, s);
		return p;
	}
	return NULL;
}

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
int K_multiply(int x,int K)
{
	if (K == 17)
		x = x << 4 + x;
	else if (K == -7)
		x = -(x << 3 - x);
	else if (K == 60)
		x = x << 6 - x << 2;
	else if (K == -112)
		x = -x << 7 + x << 4;
	return x;


}

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
int divide_power2(int x, int k)
{

	return (x > 0 ? x + (1 << k) - 1 : x) >> k;
}

在这里插入图片描述

int mul3div4(int x)
{
	int k = 2;
	int bias = (1 << k) - 1;//3
	unsigned sizeof_int = sizeof(int);
	unsigned w = sizeof_int << 3;
	x = (x << 1) + x;//没有考虑溢出
	int judge = x >> (w - 1); //判断正负
	return (judge & ((x + bias) >> k)) + (~judge & (x >> k));
}

在这里插入图片描述

#include<stdio.h>
int threefourthd(int x)
{
	int k = 2;
	int bias = (1 << k) - 1;
	unsigned sizeof_int = sizeof(int);
	unsigned w = sizeof_int << 3;
	int judge = x >> (w - 1); //-:FFFFFFFF +:00000000
	x = (x << 1) + x;
	//如果先除容易变成0,但是先乘容易溢出
	return (judge & ((x + bias) >> k)) + (~judge & (x >> k));
}
int main()
{
	int a = threefourthd(3);
	printf("%d\n", a);
	int b = threefourthd(-1);
	printf("%d\n", b);
	return 0;
}

在这里插入图片描述

在这里插入图片描述

unsigned only_k(unsigned k)
{
	unsigned w = sizeof(unsigned) << 3;
	unsigned a = ~0;
	return a << k;
}
unsigned k_j(unsigned k, unsigned j)
{
	unsigned w = sizeof(unsigned) << 3;
	unsigned a = ~0;
	a = a << (w-k);
	return a >> (w-j-k);
}

在这里插入图片描述
A:当x是最小值时,其负数还是最小值
B:1,LEFT = ((((((x+y)mod)16)mod)+y)mod)-x)mod = (17y + 15x)mod. RIGHT = (17y)mod + (15x)mod = (17y + 15x)mod.
C:1, LEFT = (~x + 1) + (~y + 1) - 1 = -x + -y - 1. RIGHT = ~(x+y) + 1 - 1 = -(x+y) - 1 = -x + -y - 1.
D:1
E:1
在这里插入图片描述
Y = x
2k - x 即 x = Y/(2k- 1)
(a) Y = 101 = 5, k = 3, x = 5/7 (b) Y = 0110 = 6, k = 4, x = 2/5 © Y = 010011 = 19, k = 6, x = 19/63

在这里插入图片描述
return (sx ^ sy) ? (sx ? 1 : 0): (sx ? (ux>=uy) : (ux<=uy));
在这里插入图片描述
V=(-1)s×M×2E
Bias=2k-1-1
E=e-Bias
M=1+f
A:7.0=111=1.11210(二进制)
M=1.11,E=10,f=0.1100…
e=10+Bias
(-1)s1011000…
B:E = n+bias, M = 0b1.11
, f = 0b11*, V = 2^(n+1)-1
0, n+bias, 11*
C: E = 0b001, M = 0b1.00, f = 0b00*, V = 1.0

在这里插入图片描述
在这里插入图片描述
0 00…00 00…01 2-63*2^ (-214-1)
0 00…01 00…00 2 ^ (-214-1)
0 11…10 11…11 (2-2(-63)) * (2(14)-1)

在这里插入图片描述
| 8000 | 0 | -14 | 0 | 0 |
| 4001 | 1025/1024 | 1 | 10252^-8 | 2.001953 |
| 512 | 6000 | 1 | 9 | 12^9 | 512.000000 |
| 1023/1024 | -14 | 10232^-24 | 0.000061 |
| - | - | - | -inf |
| 3BB0 | 124/64 | -1 | 312^-5 | 0.968750 |
在这里插入图片描述
| Format A | Format A | Format B | Format B |
| Bits | Value | Bits | Value |
| 1 01111 001 | -9/8 | 1 0111 0010 | -9/8 |
| 0 10110 011 | 1124 | 0 1110 0110 | 1124 |
| 1 00111 010 | -52-10 | 1 0000 0101 | -52-10 |
| 0 00000 111 | 72-17| 0 0000 0001 | 2-10 |
| 1 11100 000 | -213 | 1 1110 1111 | -3123 |
| 0 10111 100 | 327 | 0 1110 1111 | 3123 |
在这里插入图片描述
A:1
B:不总是返回1.如x=INT_MIN,Y=1
C:1
D:不总是返回1.例如dx与dy互为倒数且dy*dz=+infinite
E:不总是返回1.例如dx=1.0, dz=0.0 
在这里插入图片描述
在这里插入图片描述

float fpwr2(int x)
{
	/* Result exponent and fraction */
	unsigned exp, frac;
	unsigned u;
	if (x < -149)// 小于最小的非规格化数
	{
		/* Too small. Return 0.0 */
		exp = 0;
		frac = 0;
	} 
	else if (x < -126)   // 非规格化数
	{
		/* Denormalized result */
		exp = 0;
		frac = 1 << (149 + x);
	}
	else if (x < 128) // 规格化数
	{
		/* Normalized result. */
		exp = x + 127;
		frac = 0;
	}
	else// 大于最大规格化数
	{
		/* Too big. Return +oo */
		exp = 0xFF;
		frac = 0; 
	}
	
	/*Pack exp and frac into,32 bits */
	u = exp << 23 | frac;
	/* Return as float */
	return u2f(u);
}

在这里插入图片描述
0x 40490FDB = 0b 0100 0000 0100 1001 0000 1111 1101 1011 = 0,10000000,10010010000111111011011

A: 10010010000111111011011

B: y=1, k=3, 即 0b11.(001)*

C: 0x4049039b 0x40492492 从高位向低位第19个。
在这里插入图片描述
在这里插入图片描述

#include <stdio.h>

typedef unsigned float_bits;

float_bits float_negate(float_bits f) {
  unsigned sign = f >> 31;
  unsigned exp = f >> 23 & 0xFF;
  unsigned frac = f & 0x7FFFFF;

  int is_NAN = (exp == 0xFF) && (frac != 0);
  if (is_NAN) {
    return f;
  }
  return ~sign << 31 | exp << 23 | frac;
}

在这里插入图片描述

typedef unsigned float_bits;
float_bits float_absval(float_bits s)
{
	unsigned sign = s >> 31;
	unsigned exp = s >> 23 & 0xFF;
	unsigned frac = s & 0x7FFFFF;
	int is_NAN = (exp == 0xFF) && (frac != 0);
	if (is_NAN) {
		return s;
	}
	return 0 << 31 | exp << 23 | frac;
	
}

在这里插入图片描述

typedef unsigned float_bits;
float_bits float_twice(float_bits f)
{
	unsigned sign = f >> 31;
	unsigned exp = f >> 23 & 0xFF;
	unsigned frac = f & 0x7FFFFF;
	int is_NAN = (exp == 0xFF) && (frac != 0);
	if (is_NAN) {
		return f;
	}
	if (exp == 0)		//非规格化数
		frac <<= 1;
	else if (exp == 0xFF - 1) {	//*2后为无穷	
		exp = 0xFF;
		frac = 0;
	}
	else	//规格化数
		exp += 1;

	return sign << 31 | exp << 23 | frac;

	
}

在这里插入图片描述

#include <stdio.h>

typedef unsigned float_bits;

float_bits float_half(float_bits f) {
    unsigned sign = f >> 31;
    unsigned exp = f >> 23 & 0xFF;
    unsigned frac = f & 0x7FFFFF;
    unsigned rest = f & 0x7FFFFFFF;

    if (exp == 0xFF) {	//如果f为NAN或无穷,直接返回
        return f;
    }

    int addition = (frac & 0x3) == 0x3;	//向偶数舍入偏置

    if (exp == 0) {	//非规格化数,<<1后加偏置
        frac >>= 1;
        frac += addition;
    }
    else if (exp == 1) {	//规格化数变为非规格化数
        rest >>= 1;
        rest += addition;
        exp = rest >> 23 & 0xFF;
        frac = rest & 0x7FFFFF;
    }
    else {		//规格化数
        exp -= 1;
    }

    return sign << 31 | exp << 23 | frac;
}

在这里插入图片描述

#include <stdio.h>

typedef unsigned float_bits;

int float_f2i(float_bits f) {
  unsigned sign = f >> 31;
  unsigned exp = f >> 23 & 0xFF;
  unsigned frac = f & 0x7FFFFF;
  unsigned bias = 0x7F;

  int num;
  unsigned E;
  unsigned M;

  if (exp >= 0 && exp < 0 + bias) {		//小于1,向0舍入
    num = 0;
  } else if (exp >= 31 + bias) {		//溢出或(int)f == INT_MIN 
    num = 0x80000000;
  } else {		//向0舍入
    E = exp - bias;
    M = frac | 0x800000;
    if (E > 23) {
      num = M << (E - 23);
    } else {				
      num = M >> (23 - E);
    }
  }

  return sign ? -num : num;
}


在这里插入图片描述

#include <stdio.h>

typedef unsigned float_bits;

/*假设i> 0,计算i的位数,例如0x3 => 2、0xFF => 8、0x80 => 8*/
int bits_length(int i) {
  if ((i & INT_MIN) != 0) {
    return 32;
  }

  unsigned u = (unsigned)i;
  int length = 0;
  while (u >= (1<<length)) {
    length++;
  }
  return length;
}

/*计算l的掩码位数,例如3  => 0x00000007、16 => 0x0000FFFF*/
unsigned bits_mask(int l) {
  return (unsigned) -1 >> (32-l);
}

/*计算float*/
float_bits float_i2f(int i) {
  unsigned sign, exp, frac, rest, exp_sign , round_part;
  unsigned bits, fbits;
  unsigned bias = 0x7F;

  if (i == 0) {
    sign = 0;
    exp = 0;
    frac = 0;
    return sign << 31 | exp << 23 | frac;
  }
  if (i == INT_MIN) {
    sign = 1;
    exp = bias + 31;
    frac = 0;
    return sign << 31 | exp << 23 | frac;
  }

  sign = 0;		//确定符号
  if (i < 0) {
    sign = 1;
    i = -i;
  }

  bits = bits_length(i);	//计算i的位数
  fbits = bits - 1;		//尾数位数		
  exp = bias + fbits;
  
  rest = i & bits_mask(fbits);
  if (fbits <= 23) {
    frac = rest << (23 - fbits);
    exp_sign = exp << 23 | frac;
  } else {		//fbits > 23
    int offset = fbits - 23;
    int round_mid = 1 << (offset - 1);		//用于比较,是否舍入位是10

    round_part = rest & bits_mask(offset);
    frac = rest >> offset;
    exp_sign = exp << 23 | frac;

    if (round_part < round_mid) { 	//向偶数舍入,是否舍入位是00
    	/*无操作*/
    } else if (round_part > round_mid) {	//是否舍入位是11
      exp_sign += 1;		//11…->100…
    } else {		//round_part == round_mid,是否舍入位是10
      if ((frac & 0x1) == 1) {
        exp_sign += 1;		//10…1->10…0
      }
    }
  }

  return sign << 31 | exp_sign;
}


  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值