1、第 二 章 习 题 答 案1 给出以下概念的解释说明。真值 机器数 数值数据 非数值数据 无符号整数 带符号整数定点数 原码 补码 变形补码 溢出 浮点数尾数 阶 阶码 移码 阶码下溢 阶码上溢规格化数 左规 右规 非规格化数 机器零 非数(NaN)BCD 码 逻辑数 ASCII 码 汉字输入码 汉字内码 机器字长大端方式 小端方式 最高有效位 最高有效字节(MSB) 最低有效位最低有效字节(LSB) 掩码 算术移位 逻辑移位 0 扩展符号扩展 零标志 ZF 溢出标志 OF 符号标志 SF进位/借位标志 CF2 简单回答下列问题。(1)为什么计算机内部采用二进制表示信息?既然计算机内部所有信息
2、都用二进制表示,为什么还要用到十六进制或八进制数?(2)常用的定点数编码方式有哪几种? 通常它们各自用来表示什么?(3)为什么现代计算机中大多用补码表示带符号整数?(4)在浮点数的基数和总位数一定的情况下,浮点数的表示范围和精度分别由什么决定?两者如何相互制约?(5)为什么要对浮点数进行规格化?有哪两种规格化操作?(6)为什么有些计算机中除了用二进制外还用 BCD 码来表示数值数据?(7)为什么计算机处理汉字时会涉及到不同的编码(如,输入码、内码、字模码)?说明这些编码中哪些用二进制编码,哪些不用二进制编码,为什么?3实现下列各数的转换。(1) (25.8125)10= (?)2= (?) 8
3、= (?) 16(2) (101101.011)2 = (?)10= (?) 8= (?) 16= (?) 8421(3) (0101 1001 0110.0011)8421 = (?)10= (?) 2= (?) 16(4) (4E.C)16 = (?)10= (?) 24 假定机器数为 8 位(1 位符号,7 位数值) ,写出下列各二进制数的原码表示。+0.1001,0.1001,+1.0 ,1.0,+0.010100 ,0.010100,+0,05 假定机器数为 8 位(1 位符号,7 位数值) ,写出下列各二进制数的补码和移码表示。+1001,1001,+1 ,1,+10100,101
4、00,+0,06 已知 x补 ,求 x(1)x 补 =11100111 (2) x补 =10000000 (3) x补 =01010010 (4)x 补 =110100117 某 32 位字长的机器中带符号整数用补码表示,浮点数用 IEEE 754 标准表示,寄存器 R1 和 R2 的内容分别为 R1:0000108BH, R2:8080108BH。不同指令对寄存器进行不同的操作,因而不同指令执行时寄存器内容对应的真值不同。假定执行下列运算指令时,操作数为寄存器 R1 和 R2 的内容,则R1 和 R2 中操作数的真值分别为多少?(1) 无符号整数加法指令(2) 带符号整数乘法指令(3) 单精
5、度浮点数减法指令8 假定机器 M 的字长为 32 位,用补码表示带符号整数。表 2.12 中第一列给出了在机器 M 上执行的C 语言程序中的关系表达式,请参照已有的表栏内容完成表中后三栏内容的填写。表 2.12 题 8 用表关系表达式 运算类型 结果 说明0 = 0U1 2147483647 12147483647U 2147483647 12147483647 (int) 2147483648U1 2(unsigned) 1 2无符号整数有符号整数01111B (2321) 000B(0)0111B (2311) 1000B (231)9 在 32 位计算机中运行一个 C 语言程序,在该程序
6、中出现了以下变量的初值,请写出它们对应的机器数(用十六进制表示) 。(1)int x=-32768 (2)short y=522 ( 3)unsigned z=65530(4)char c= (5)float a=-1.1 ( 6)double b=10.510. 在 32 位计算机中运行一个 C 语言程序,在该程序中出现了一些变量,已知这些变量在某一时刻的机器数(用十六进制表示)如下,请写出它们对应的真值。(1)int x:FFFF0006H (2)short y:DFFCH ( 3)unsigned z:FFFFFFFAH(4)char c:2AH 5)float a:C4480000H
7、( 6)double b:C024800000000000H11. 以下给出的是一些字符串变量在内存中存放的字符串机器码,请根据 ASCII 码定义写出对应的字符串。指出代码 0AH 和 00H 对应的字符的含义。(1)char *mystring1:68H 65H 6CH 6CH 6FH 2CH 77H 6FH 72H 6CH 64H 0AH 00H (2)char *mystring2:77H 65H 20H 61H 72H 65H 20H 68H 61H 70H 70H 79H 21H 00H12. 以下给出的是一些字符串变量的初值,请写出对应的机器码。(1)char *mystring
8、1=“./myfile“ (2)char *mystring2=“OK, good!“13. 已知 C 语言中的按位异或运算(“XOR”)用符号“”表示。对于任意一个位序列 a,aa=0,C 语言程序可以利用这个特性来实现两个数值交换的功能。以下是一个实现该功能的 C 语言函数:1 void xor_swap(int *x, int *y)2 3 *y=*x *y; /* 第一步 */4 *x=*x *y; /* 第二步 */5 *y=*x *y; /* 第三步 */6 假定执行该函数时*x 和*y 的初始值分别为 a 和 b,即*x=a 且*y=b,请给出每一步执行结束后,x 和y 各自指向
9、的内存单元中的内容分别是什么?14. 假定某个实现数组元素倒置的函数 reverse_array 调用了第 13 题中给出的 xor_swap 函数:1 void reverse_array(int a, int len)2 3 int left, right=len-1;4 for (left=0; left 0;4 已知 C 语言标准库函数 strlen 原型声明为“size_t strlen(const char *s);”,其中,size_t 被定义为unsigned int 类型 。请问:函数 compare_str_len 在什么情况下返回的结果不正确?为什么?为使函数正确返回结果
10、应如何修改代码?19考虑以下 C 语言程序代码:1 int func1(unsigned word)2 3 return (int) ( word 24);4 5 int func2(unsigned word)6 7 return ( (int) word 24;8 假设在一个 32 位机器上执行这些函数,该机器使用二进制补码表示带符号整数。无符号数采用逻辑移位,带符号整数采用算术移位。请填写表 2.14,并说明函数 func1 和 func2 的功能。表 2.14 题 19 用表w func1(w) func2(w)机器数 值 机器数 值 机器数 值12712825525620填写表 2.
11、15,注意对比无符号整数和带符号整数的乘法结果,以及截断操作前、后的结果。表 2.15 题 20 用表x y xy(截断前) xy(截断后)模式机器数 值 机器数 值 机器数 值 机器数 值无符号 110 010带符号 110 010无符号 001 111带符号 001 111无符号 111 111带符号 111 11121以下是两段 C 语言代码,函数 arith( )是直接用 C 语言写的,而 optarith( )是对 arith( )函数以某个确定的 M 和 N 编译生成的机器代码反编译生成的。根据 optarith( ),可以推断函数 arith( ) 中 M 和 N 的值各是多少?
12、#define M #define N int arith (int x, int y)int result = 0 ;result = x*M + y/N; return result;int optarith ( int x, int y)int t = x;x 2;return x+y;22. 下列几种情况所能表示的数的范围是什么?(1) 16 位无符号整数(2) 16 位补码表示的带符号整数(3) 下述格式的浮点数(基数为 2,移码的偏置常数为 128)23. 以 IEEE 754 单精度浮点数格式表示下列十进制数。+1.75,+19,1/8,25824设一个变量的值为 4098,要求
13、分别用 32 位补码整数和 IEEE 754 单精度浮点格式表示该变量(结果用十六进制形式表示) ,并说明哪段二进制位序列在两种表示中完全相同,为什么会相同?25设一个变量的值为2 147 483 647(提示:2 147 483 647=231-1) ,要求分别用 32 位补码整数和IEEE754 单精度浮点格式表示该变量(结果用十六进制形式表示) ,并说明哪种表示其值完全精确,哪种表示的是近似值。26下表给出了有关 IEEE 754 浮点格式表示中一些重要的非负数的取值,表中已经有最大规格化数的相应内容,要求填入其他浮点数格式的相应内容。表 2.16 题 26 用表单精度 双精度项目 阶码
14、 尾数 以 2 的幂次表示的值以 10 的幂次表示的值以 2 的幂次表示的值以 10 的幂次表示的值01最大规格化数最小规格化数最大非规格化数最小非规格化数+NaN11111110 111 (22-23)2127 3.41038 (22-52)21023 1.81030827已知下列字符编码:A 为 100 0001,a 为 110 0001,0 为 011 0000,求 E、e、f、7、G 、Z、5 的 7位 ACSII 码和在第一位前加入奇校验位后的 8 位编码。28假定在一个程序中定义了变量 x、y 和 i,其中,x 和 y 是 float 型变量(用 IEEE754 单精度浮点数表示)
15、 ,i 是 16 位 short 型变量(用补码表示) 。程序执行到某一时刻,x= 0.125、y=7.5、i=100,它们都被写到了主存(按字节编址) ,其地址分别是 100,108 和 112。请分别画出在大端机器和小端机器上变量 x、y 和 i 中每个字节在主存的存放位置。29. 对于图 2.6,假设 n=8,机器数 X 和 Y 的真值分别是 x 和 y。请按照图 2.6 的功能填写表 2.17,并给出对每个结果的解释。要求机器数用十六进制形式填写,真值用十进制形式填写。表 2.17 题 29 用表表示 X x Y y X+Y x+y OF SF CF X-Y x-y OF SF CF无
16、符号 0xB0 0x8C带符号 0xB0 0x8C无符号 0x7E 0x5D带符号 0x7E 0x5D30. 在字长为 32 位的计算机上,有一个函数其原型声明为“int ch_mul_overflow(int x, int y);”,该函数用于对两个 int 型变量 x 和 y 的乘积判断是否溢出,若溢出则返回 1,否则返回 0。请使用 64 位精度的整数类型 long long 来编写该函数。31对于第 2.7.5 节中例 2.31 存在的整数溢出漏洞,如果将其中的第 5 行改为以下两个语句:数符S1阶码S1尾数S11 位S18 位移码S17 位原码数值部分S1unsigned long
17、long arraysize=count*(unsigned long long)sizeof(int); int *myarray = (int *) malloc(arraysize); 已知 C 语言标准库函数 malloc 的原型声明为“void *malloc(size_t size);”,其中,size_t 定义为unsigned int 类型,则上述改动能否消除整数溢出漏洞?若能则说明理由;若不能则给出修改方案。32. 已知一次整数加法、一次整数减法和一次移位操作都只需一个时钟周期,一次整数乘法操作需要 10个时钟周期。若 x 为一个整型变量,现要计算 55*x,请给出一种计算表
18、达式,使得所用时钟周期数最少。33假设 x 为一个 int 型变量,请给出一个用来计算 x/32 的值的函数 div32。要求不能使用除法、乘法、模运算、比较运算、循环语句和条件语句,可以使用右移、加法以及任何按位运算。34. 无符号整数变量 ux 和 uy 的声明和初始化如下:unsigned ux=x;unsigned uy=y;若 sizeof(int)=4,则对于任意 int 型变量 x 和 y,判断以下关系表达式是否永真。若永真则给出证明;若不永真则给出结果为假时 x 和 y 的取值。(1)(x*x) = 0 (2)(x-10(3)x0 | -x=0(5)xdouble dy = (
19、double) y;double dz = (double) z;若 float 和 double 分别采用 IEEE 754 单精度和双精度浮点数格式,sizeof(int)=4 ,则对于任意 int 型变量 x、y 和 z,判断以下关系表达式是否永真。若永真则给出证明;若不永真则给出结果为假时 x和 y 的取值。(1)dx*dx = 0 (2)(double)(float) x = dx(3)dx+dy = (double) (x+y) (4)(dx+dy)+dz = dx+(dy+dz)(5)dx*dy*dz = dz*dy*dx (6)dx/dx = dy/dy36. 在 IEEE 7
20、54 浮点数运算中,当结果的尾数出现什么形式时需要进行左规,什么形式时需要进行右规?如何进行左规,如何进行右规?37在 IEEE 754 浮点数运算中,如何判断浮点运算的结果是否溢出?38. 分别给出不能精确用 IEEE 754 单精度和双精度格式表示的最小正整数。39采用 IEEE 754 单精度浮点数格式计算下列表达式的值。(1)0.75+( 65.25) (2)0.75( 65.25)40. 以下是函数 fpower2 的 C 语言源程序,它用于计算 2x的浮点数表示,其中调用了函数 u2f,u2f 用于将一个无符号整数表示的 0/1 序列作为 float 类型返回。请填写 fpower
21、2 函数中的空白部分,以使其能正确计算结果。1 float fpower2(int x)2 3 unsigned exp, frac, u;45 if (x ) /* 值太小,返回 0.0 */6 exp = ;7 frac = ;8 else if (x ) /* 返回非规格化结果 */9 exp = ;10 frac = ;11 else if (x ) /* 返回规格化结果 */12 exp = ;13 frac = ;14 else /* 值太大,返回+ */15 exp = ;16 frac = ;17 18 u = exp 23 | frac;19 return u2f(u);20
22、 41. 以下是一组关于浮点数按位级进行运算的编程题目,其中用到一个数据类型 float_bits,它被定义为unsigned int 类型。以下程序代码必须采用 IEEE 754 标准规定的运算规则,例如,舍入应采用就近舍入到偶数的方式。此外,代码中不能使用任何浮点数类型、浮点数运算和浮点常数,只能使用float_bits 类型;不能使用任何复合数据类型,如数组、结构和联合等;可以使用无符号整数或带符号整数的数据类型、常数和运算。要求编程实现以下功能并进行正确性测试,需要针对参数 f 的所有 32 位组合情况进行处理。(1)计算浮点数 f 的绝对值|f |。若 f 为 NaN,则返回 f,否
23、则返回|f| 。函数原型为:float_bits float_abs(float_bits f);(2)计算浮点数 f 的负数-f。若 f 为 NaN,则返回 f,否则返回 -f。函数原型为:float_bits float_neg(float_bits f);(3)计算 0.5*f。若 f 为 NaN,则返回 f,否则返回 0.5*f。函数原型为:float_bits float_half(float_bits f);(4)计算 2.0*f。若 f 为 NaN,则返回 f,否则返回 2.0*f。函数原型为:float_bits float_twice(float_bits f);(5)将 int 型整数 i 的位序列转换为 float 型位序列。函数原型为:float_bits float_i2f(int i);(6)将浮点数 f 的位序列转换为 int 型位序列。若 f 为非规格化数,则返回值为 0;若 f 是 NaN 或或超出 int 型数可表示范围,则返回值为 0x80000000;若 f 带小数部分,则考虑舍入。函数原型为:int float_f2i(float_bits f);