HNU计算机系统作业第二章

题2.58

解答:

代码:

int is_little_endian(){

      int a=1;

      char *p = (char *) &a;

      return (int)(*p);

}

实现思路:

大端法和小端法高低位存储的方向相反,小端法地址低位存低位,大端法地址高位存低位,因此可以定义一个int型数据的1,它的最低位为1,最高位为0,如果是小端法则最低地址存的数据是1,如果是大端法则最低地址存的数据是0,通过将指向该数据首地址的指针强制转换成char型,因为char型数据只占一个字节,这样在返回时只会读取最低位地址的数据,如果是1则机器为小端法,如果是0则机器为大端法。

 

题2.71

解答:

  1.  

代码为何出错:首先源代码中word是unsigned型无符号数右移是逻辑右移,因此不能保证前面填充的位数是按符号位填充,得到的数不一定是拓展成的32位的int类型,而且右移后有和0xFF相与,无论指定的字节表示的是正数还是负数,前24位全部成为0,不满足按符号位拓展的规则,因此是错误的。

B

函数的正确实现:

int xbyte(packet_t word, int bytenum) {

      return (((int) word<<((3-bytenum)<<3))>>24);

}

实现思路:

先将word数据转化成int型数据,这样的话在右移时就会进行符号拓展,不会改变指定的字节的值,然后先把这个字节移到最高位的那个字节,去掉前面多余的字节,然后右移去掉后面多余的字节,此时已经是int型,右移时进行算术右移,按符号位拓展,不会改变指定字节的值,就能实现此功能。

 

题2.84

解答:

A. 数 5.0

5.0=0b 101.0 (十进制转化为二进制) M = 1.01   f = 0.01  E = 2  

e = bias + E= 2k-1-1+2   V = 5.0

位表示:

  1. 10....01   0100....

B. 能够被准确描述的最大奇整数

若要表示最大的奇整数,则所表示的数由二进制表示应该是111111…

要求能准确标示,所以小数点后的位数一共有确定的能够准确存储的n位

所以这个数表示为1.1111…x2n

所以M 为 1.111111…   f = 0.11111111…(小数点后共有n个1)  E = n

e = bias + n   V =0b 1111111… (一共由n+1个1组成) = 2n+1 - 1

位表示:

0  bias+n  11111…

C. 最小的正规格化数的倒数

最小的规格化正数:1.0000…x21-bias

M = 1.00....   f = 0.000....   E = 1 - bias   e = 1   V = 21-bias

最小的规格化正数的倒数:1.0000…x2bias-1

M = 1.00...   f = 0.000....   E = bias – 1   e = bias + E   V = 2bias-1

位表示:

  1. 11…101  00000…

 

题2.88

解答:

  1. (double) (float) x == dx

不总是为1,因为float类型尾数只有23位,因此只能准确表示二进制形式小于24位的整数,如果超过24位在转换成float时会使精度丢失,但是double尾数有52位可以准确表示53位二进制的整数,因此在当整数较大二进制形式大于24位时,此表达式就不成立。

例如:整数x = +2147483647的二进制形式为11111111111111111111111111111111但是在转化成float时只能保留24位1,而在转化成double时能保存32位1,此时两个数大小就已经不一样了,即使是float再转化成double之前丢失的位也只能用0填充,已经和原来的数字不一样了。

  1. dx + dy == (double) (x+y)

不总是为1,等式左边两个数都为double类型,当x+y的值超过32位时,左边的计算值依然正确,而右边会发生越界,只能保留32位。

例如:x = +2147483647,y = +2147483647时,int类型就会发生越界超过范围溢出成为一个负数,但是如果提前转换成double类型就不会发生越界问题,可以正常计算x + y的值。

  1. dx + dy +dz == dz + dy +dx

总是为1,double的精确表示范围在正负2的53次方之内,而x y z相加的二进制位数,一定在53位之内,因此无论相加的顺序如何,都可以精确表示。

  1. dx * dy * dz == dz * dy *dx

不总是为1,一个32位二进制数乘一个32位二进制数得到的结果可能大于53位二进制,此时double类型也不能精确地表示这个结果值,有可能会发生舍入,而此时运算顺序不同则发生舍入的值可能就不同,可能会导致最终的计算结果也就不一样,因此等式左右两边有可能不相等。

  1. dx / dx == dy /dy

不总是为1,当dx或者dy中有一个为0而另一个不为0时,此时0/0得到的是NaN,等式就不相等了。

 

题2.92

解答:

函数实现:

float_bits float_negate(float_bits f){

      unsigned exp=(f>>23)&0xff;

      unsigned frac=f&0x7fffff;

      if(frac!=0 && exp==0xff){

            return f;

      }

      else return f^0x80000000;

};

实现思路:

通过移位操作和按位与操作,先把f在机器内的float型二进制表示的8位exp和23位尾数取出来,然后根据此判断f是否是NAN,如果是那就返回原值,如果不是通过异或操作,将最高位的符号位取反,就能实现浮点数符号的变化得到-f。

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值