版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第二章习题答案1.给出以下概念的解释说明。真值机器数原码数值数据非数值数据变形补码移码无符号整数带符号整数浮点数定点数尾数补码阶码右规溢出阶阶码下溢机器零阶码上溢非数(NaN)规格化数BCD码大端方式左规非规格化数逻辑数小端方式ASCII码汉字输入码汉字内码机器字长最高有效位掩码最高有效字节(MSB)最低有效位最低有效字节(LSB)算术移位逻辑移位0扩展符号扩展零标志ZF溢出标志OF符号标志SF进位/借位标志CF2.简单回答下列问题。(1)为什么计算机内部采用二进制表示信息?既然计算机内部所有信息都用二进制表示,为什么还要用到十六进制或八进制数?(2)常用的定点数编码方式有哪几种?通常它们各自用来表示什么?(3)为什么现代计算机中大多用补码表示带符号整数?(4)在浮点数的基数和总位数一定的情况下,浮点数的表示范围和精度分别由什么决定?两者如何相互制约?(5)为什么要对浮点数进行规格化?有哪两种规格化操作?(6)为什么有些计算机中除了用二进制外还用BCD码来表示数值数据?(7)为什么计算机处理汉字时会涉及到不同的编码(如,输入码、内码、字模码)?说明这些编码中哪些用二进制编码,哪些不用二进制编码,为什么?3.实现下列各数的转换。(1)(25.8125)10=(?)2=(?)8=(?)16(2)(101101.011)2=(?)10=(?)8=(?)16=(?)8421(3)(010110010110.0011)8421=(?)10=(?)2=(?)16(4)(4E.C)16=(?)10=(?)2参考答案:(1)(25.8125)10=(11001.1101)2=(31.64)8=(19.D)16(2)(101101.011)2=(45.375)10=(55.3)8=(2D.6)16=(01000101.001101110101)8421(3)(010110010110.0011)8421=(596.3)10=(1001010100.01001100110011…)2=(254.4CCC…)16(4)(4E.C)16=(78.75)10=(01001110.11)24.假定机器数为8位(1位符号,7位数值),写出下列各二进制数的原码表示。+0.1001,–0.1001,+1.0,–1.0,+0.010100,–0.010100,+0,–0参考答案:(后面添0)+0.1001:–0.1001:+1.0:原码0.10010001.1001000溢出–1.0:溢出+0.010100:–0.010100:+0:0.01010001.01010000.00000001.0000000–0:
5.假定机器数为8位(1位符号,7位数值),写出下列各二进制数的补码和移码表示。+1001,–1001,+1,–1,+10100,–10100,+0,–0参考答案:(假定移码的偏置常数为128)(前面添0)+1001:移码补码100010010111011110000001011111111100101000110110010000000100000000000100111110111000000011111111100010100111011000000000000000000–1001:+1:–1:+10100:–10100:+0:–0:6.已知[x]补,求x(1)[x]补=11100111参考答案:(1)[x]补=11100111(2)[x]补=10000000(3)[x]补=01010010(4)[x]补=11010011(2)[x]补=10000000(3)[x]补=01010010(4)[x]补=11010011x=–0011001B=–25x=–10000000B=–128x=+1010010B=82x=–0101101B=–457.某32位字长的机器中带符号整数用补码表示,浮点数用IEEE754标准表示,寄存器R1和R2的内容分别为R1:0000108BH,R2:8080108BH。不同指令对寄存器进行不同的操作,因而不同指令执行时寄存器内容对应的真值不同。假定执行下列运算指令时,操作数为寄存器R1和R2的内容,则R1和R2中操作数的真值分别为多少?(1)无符号整数加法指令(2)带符号整数乘法指令(3)单精度浮点数减法指令参考答案:R1=0000108BH=00000000000000000001000010001011BR2=8080108BH=10000000100000000001000010001011B(1)对于无符号数加法指令,R1和R2中是操作数的无符号数表示,因此,其真值分别为R1:108BH,R2:8080108BH。(2)对于带符号整数乘法指令,R1和R2中是操作数的带符号整数,即补码表示,由最高位可知,R1为正数,R2为负数。R1的真值为+108BH,R2的真值为–(1111111011111111110111101110100b+1b)=–7F7FEF75H。(3)对于单精度浮点数减法指令,R1和R2中是操作数的IEEE754单精度浮点数表示。在IEEE754标准中,单精度浮点数的位数为32位,其中包含1位符号位,8位阶码,23位尾数。由R1中的内容可知,其符号位为0,说明为正数,阶码为00000000,尾数部分为00000000001000010001011,故其为非规格化浮点数,指数为–126,尾数中没有隐藏的1,用十六进制表示尾数为+0.002116H,故R1表示的真值为+0.002116H×2-126。由R2中的内容可知,其符号位为1,表示其为负数,阶码为00000001,尾数部分为00000000001000010001011,故其为规格化浮点数,指数为1–127=–126,尾数中有隐藏的1,用十六进制表示尾数为–1.002116H,故R2表示的真值为–1.002116H×2-1268.假定机器M的字长为32位,用补码表示带符号整数。表2.12中第一列给出了在机器M上执行的C
语言程序中的关系表达式,请参照已有的表栏内容完成表中后三栏内容的填写。表2.12题8用表关系表达式运算类型结果说明0==0U–1<0–1<0U无符号整数有符号整数0111…1B(232–1)>00…0B(0)2147483647>–2147483647–12147483647U>–2147483647–12147483647>(int)2147483648U–1>–2011…1B(231–1)>100…0B(–231)(unsigned)–1>–2参考答案:关系表达式运算类型结果说明0==0U无符号整数有符号整数无符号整数有符号整数无符号整数有符号整数有符号整数无符号整数1101011100…0B=00…0B–1<011…1B(–1)<00…0B(0)–1<0U11…1B(232–1)>00…0B(0)–1)>100…0B(–2–1)<100…0B(22147483647>–2147483647–12147483647U>–2147483647–12147483647>(int)2147483648U–1>–2011…1B(2011…1B(2011…1B(23131)313131)–1)>100…0B(–2)3111…1B(–1)>11…10B(–2)11…1B(2–1)>11…10B(2–2)32(unsigned)–1>–2329.在32位计算机中运行一个C语言程序,在该程序中出现了以下变量的初值,请写出它们对应的机器数(用十六进制表示)。(1)intx=-32768(4)charc=‟@‟参考答案:(2)shorty=522(5)floata=-1.1(3)unsignedz=65530(6)doubleb=10.5(1)-215=-1000000000000000B,故机器数为1„11000000000000000=FFFF8000H(2)522=1000001010B,故机器数为0000001000001010=020AH(3)65530=216-1-5=1111111111111010B,故机器数为0000FFFAH(4)‟@‟的ASCII码是40H(5)-1.1=-1.00011[0011]„B=-1.00011001100110011001100B,阶码为127+0=01111111,故机器数为10111111100011001100110011001100=BF8CCCCCH(6)10.5=1010.1B=1.0101B23,阶码为1023+3=10000000010,故机器数为0100000000100101[0000]=4025000000000000H10.在32位计算机中运行一个C语言程序,在该程序中出现了一些变量,已知这些变量在某一时刻的机器数(用十六进制表示)如下,请写出它们对应的真值。(1)intx:FFFF0006H(4)charc:2AH参考答案:(2)shorty:DFFCH5)floata:C4480000H(3)unsignedz:FFFFFFFAH(6)doubleb:C024800000000000H(1)FFFF0006H=1„10000000000000110B,故x=-1111111111111010B=-(65535-5)=-65530(2)DFFCH=1101111111111100B=-010000000000100B
故y=-(8192+4)=-8196(3)FFFFFFFAH=1„11010B,故z=232-6(4)2AH=00101010B,故c=42,若c表示字符,则c为字符‟*‟(5)C4480000H=11000100010010000„0B,阶码为10001000,阶为136-127=9,尾数为-1.1001B,故a=-1.1001B29=-1100100000B=-800(6)C024800000000000H=1100000000100100100000„0B,阶码为10000000010,阶为1026-1023=3,尾数为1.01001B,故b=-1.01001B23=-1010.01B=-10.2511.以下给出的是一些字符串变量在内存中存放的字符串机器码,请根据ASCII码定义写出对应的字符串。指出代码0AH和00H对应的字符的含义。(1)char*mystring1:68H65H6CH6CH6FH2CH77H6FH72H6CH64H0AH00H(2)char*mystring2:77H65H20H61H72H65H20H68H61H70H70H79H21H00H参考答案:字符串由字符组成,每个字符在内存中存放的是对应的ASCII码,因而可根据表2.5中的ASCII码和字符之间的对应关系写出字符串。(1)mystring1指向的字符串为:hello,world\n(2)mystring2指向的字符串为:wearehappy!其中,ASCII码00001010B=0AH对应的是“换行”字符‟\n‟(LF)。每个字符串在内存存放时最后都会有一个“空”字符‟\0‟(NUL),其ASCII码为00H。12.以下给出的是一些字符串变量的初值,请写出对应的机器码。(1)char*mystring1="./myfile"(2)char*mystring2="OK,good!"参考答案:(1)mysring1指向的存储区存放内容为:2EH2FH6DH79H66H69H6CH65H00H(2)mysring2指向的存储区存放内容为:4FH4BH2CH67H6FH6FH64H21H00H13.已知C语言中的按位异或运算(“XOR”)用符号“^”表示。对于任意一个位序列a,a^a=0,C语言程序可以利用这个特性来实现两个数值交换的功能。以下是一个实现该功能的C语言函数:123456voidxor_swap(int*x,int*y){*y=*x^*y;/*第一步*/*x=*x^*y;/*第二步*/*y=*x^*y;/*第三步*/}假定执行该函数时*x和*y的初始值分别为a和b,即*x=a且*y=b,请给出每一步执行结束后,x和y各自指向的内存单元中的内容分别是什么?参考答案:第一步结束后,x和y指向的内存单元内容各为a和a^b第二步结束后,x和y指向的内存单元内容各为b和a^b第三步结束后,x和y指向的内存单元内容各为b和a14.假定某个实现数组元素倒置的函数reverse_array调用了第13题中给出的xor_swap函数:1voidreverse_array(inta[],intlen)2{3456intleft,right=len-1;for(left=0;left<=right;left++,right--)xor_swap(&a[left],&a[right]);}
当len为偶数时,reverse_array函数的执行没有问题。但是,当len为奇数时,函数的执行结果不正确。请问,当len为奇数时会出现什么问题?最后一次循环中的left和right各取什么值?最后一次循环中调用xor_swap函数后的返回值是什么?对reverse_array函数作怎样的改动就可消除该问题?参考答案:当len为奇数时,最后一次循环执行的是将最中间的数与自己进行交换,即left和right都指向最中间数组元素,因而在调用xor_swap函数过程中的每一步执行*x^*y时结果都是0,并将0写入到了最中间的数组元素,从而改变了原来的数值。可以将for循环中的终止条件改为“left<right”,这样,在len为奇数时最中间的数组元素不动。15.假设以下表2.13中的x和y是某C语言程序中的char型变量,请根据C语言中的按位运算和逻辑运算的定义,填写表2.13,要求用十六进制形式填写。表2.13题15用表xyx^yx&yx|y~x|~yx&!yx&&yx||y!x||!yx&&~y0x5F0xC70x800x070xA00xF00x7F0x55参考答案:表2.13题15用表xyx^y0xFF0x370xFF0x07x&y0x000xC00x000x07x|y~x|~y0xFF0x3F0xFF0xF8x&!y0x000x000x000x00x&&y0x010x010x010x01x||y0x010x010x010x01!x||!y0x000x000x000x00x&&~y0x010x5F0xC70x800x070xA00xF00x7F0xFF0xFF0xF70xFF0xFF0x010x010x0016.对于一个n(n≥8)位的变量x,请根据C语言中按位运算的定义,写出满足下列要求的C语言表达式。(1)x的最高有效字节不变,其余各位全变为0。(2)x的最低有效字节不变,其余各位全变为0。(3)x的最低有效字节全变为0,其余各位取反。(4)x的最低有效字节全变1,其余各位不变。参考答案:(1)(x>>(n-8))<<(n-8)(2)x&0xFF(3)((x^~0xFF)>>8)<<8(3)x|0xFF17.以下是一个由反汇编器生成的一段针对某个小端方式处理器的机器级代码表示文本,其中,最左边是指令所在的存储单元地址,冒号后面是指令的机器码,最右边是指令的汇编语言表示,即汇编指令。已知反汇编输出中的机器数都采用补码表示,请给出指令代码中划线部分表示的机器数对应的真值。80483d2:81ecb801000080483d8:8b5508sub&0x1b8,%espmov0x8(%ebp),%edx80483db:83c214addmovadd$0x14,%edx0xfffffe58(%ebp),%eax(%edx),%eax80483de:8b8558feffff80483e4:030280483e6:898574feffffmov%eax,0xfffffe74(%ebp)
80483ec:8b550880483ef:83c24480483f2:8b85c8feffff80483f8:8902mov0x8(%ebp),%edxadd$0x44,%edxmovmov0xfffffec8(%ebp),%eax%eax,(%edx)80483fa:8b451080483fd:03450c8048400:8985ecfeffff8048406:8b45088048409:83c020参考答案:mov0x10(%ebp),%eaxaddmov0xc(%ebp),%eax%eax,0xfffffeec(%ebp)mov0x8(%ebp),%eaxadd$0x20,%eaxb8010000:机器数为000001B8H,真值为+110111000B=44014:机器数为14H,真值为+10100B=2058feffff:机器数为FFFFFE58H,真值为-110101000B=-42474feffff:机器数为FFFFFE74H,真值为-110001100B=-39644:机器数为44H,真值为+1000100B=68c8feffff:机器数为FFFFFEC8H,真值为-110001100B=-31210:机器数为10H,真值为+10000B=160c:机器数为0CH,真值为+1100B=12ecfeffff:机器数为FFFFFEECH,真值为-100010100B=-27620:机器数为20H,真值为+00100000B=3218.假设以下C语言函数compare_str_len用来判断两个字符串的长度,当字符串str1的长度大于str2的长度时函数返回值为1,否则为0。123intcompare_str_len(char*str1,char*str2){returnstrlen(str1)-strlen(str2)>0;4}已知C语言标准库函数strlen原型声明为“size_tstrlen(constchar*s);”,其中,size_t被定义为unsignedint类型。请问:函数compare_str_len在什么情况下返回的结果不正确?为什么?为使函数正确返回结果应如何修改代码?参考答案:因为size_t被定义为unsignedint类型,因此,库函数strlen的返回值为无符号整数。函数compare_str_len中的返回值是strlen(str1)-strlen(str2)>0,这个关系表达式中>号左边是两个无符号数相减,其差还是无符号整数,因而总是大于等于0,也即在str1的长度小于str2的长度时结果也为1。显然,这是错误的。只要将第3行语句改为以下形式即可:3returnstrlen(str1)>strlen(str2);19.考虑以下C语言程序代码:12345678intfunc1(unsignedword){return(int)((word<<24)>>24);}intfunc2(unsignedword){return((int)word<<24)>>24;}假设在一个32位机器上执行这些函数,该机器使用二进制补码表示带符号整数。无符号数采用逻辑移位,带符号整数采用算术移位。请填写表2.14,并说明函数func1和func2的功能。表2.14题19用表wfunc1(w)func2(w)
机器数值机器数值机器数值127128255256参考答案:函数func1的功能是把无符号数高24位清零(左移24位再逻辑右移24位),当成带符号整数返回时,结果一定是正数;函数func2的功能是把无符号数的高24位都变成和第25位一样,因为左移24位后进行算术右移,高24位补符号位(即第25位),当成带符号整数返回时,结果可能是正数也可能是负数。Wfunc1(w)func2(w)机器数值机器数值+127+128+2550机器数值+127–128–10000007FH00000080H000000FFH00000100H1271282552560000007FH00000080H000000FFH00000000H0000007FHFFFFFF80HFFFFFFFFH00000000H020.填写表2.15,注意对比无符号整数和带符号整数的乘法结果,以及截断操作前、后的结果。表2.15题20用表xyx×y(截断前)x×y(截断后)模式机器数值机器数值机器数值机器数值无符号带符号无符号带符号无符号带符号110110001001111111010010111111111111参考答案:xyx×y(截断前)x×y(截断后)模式机器数110值6机器数010值2机器数值12–47机器数100值4无符号数二进制补码无符号数001100111100000111111111110001000001110–21010+27100–47001111111二进制补码无符号数001+17111–17–149+1111–11111111001二进制补码111–1111–1001+121.以下是两段C语言代码,函数arith()是直接用C语言写的,而optarith()是对arith()函数以某个确定的M和N编译生成的机器代码反编译生成的。根据optarith(),可以推断函数arith()中M和N的值各是多少?#defineM
#defineNint{arith(intx,inty)intresult=0;result=x*M+y/N;returnresult;}intoptarith(intx,inty){intt=x;x<<=4;x–=t;if(y<0)y+=3;y=>>2;returnx+y;}参考答案:可以看出x*M和“intt=x;x<<=4;x-=t;”三句对应,这些语句实现了x乘15的功能(左移4位相当于乘以16,然后再减1),因此,M等于15;y/N与“if(y<0)y+=3;y>>2;”两句对应,第二句“y右移2位”实现了y除以4的功能,因此N是4。而第一句“if(y<0)y+=3;”主要用于对y=–1时进行调整,若不调整,则–1>>2=–1而–1/4=0,两者不等;调整后–1+3=2,2>>2=0,两者相等。22.下列几种情况所能表示的数的范围是什么?(1)16位无符号整数(2)16位补码表示的带符号整数(3)下述格式的浮点数(基数为2,移码的偏置常数为128)数符1位阶码尾数8位移码7位原码数值部分参考答案:(1)16位无符号整数:0~65535(2)16位补码表示的整数:–32768~+32767(3)浮点数:负数:–(1–2–7)×2+127~–2–7×2–128正数:+2–7×2–128~(1–2–7)×2+12723.以IEEE754单精度浮点数格式表示下列十进制数。+1.75,+19,–1/8,258参考答案:+1.75=+1.11B=1.11B×20,故阶码为0+127=01111111B,数符为0,尾数为1.110…0,小数点前为隐藏位,所以+1.7表示为00111111111000000000000000000000,用十六进制表示为3FE00000H。+19=+10011B=+1.0011B×24,故阶码为4+127=10000011B,数符为0,尾数为1.00110…0,所以+19表示为01000001100110000000000000000000,用十六进制表示为41980000H。–1/8=–0.125=–0.001B=–1.0×2–3,阶码为–3+127=01111100B,数符为1,尾数为1.0…0,所以–1/8表示为10111110000000000000000000000000,用十六进制表示为BE000000H。258=100000010B=1.0000001B×28,故阶码为8+127=10000111B,数符为0,尾数为1.0000001,所以
258表示为01000011100000010000000000000000,用十六进制表示为43810000H。24.设一个变量的值为4098,要求分别用32位补码整数和IEEE754单精度浮点格式表示该变量(结果用十六进制形式表示),并说明哪段二进制位序列在两种表示中完全相同,为什么会相同?参考答案:4098=+1000000000010B=+1.00000000001×21232位2-补码形式为:00000000000000000001000000000010(00001002H)IEEE754单精度格式为:01000101100000000001000000000000(45801000H)粗体部分为除隐藏位外的有效数字,因此,在两种表示中是相同的位序列。25.设一个变量的值为–2147483647(提示:2147483647=231-1),要求分别用32位补码整数和IEEE754单精度浮点格式表示该变量(结果用十六进制形式表示),并说明哪种表示其值完全精确,哪种表示的是近似值。参考答案:–2147483647=–1111111111111111111111111111111B=–1.111111111111111111111111111111×23032位补码形式为:10000000000000000000000000000001(80000001H)IEEE754单精度格式为:11001110111111111111111111111111(CEFFFFFFH)32位补码形式能表示精确的值,而浮点数表示的是近似值,因为低7位被截断了。26.下表给出了有关IEEE754浮点格式表示中一些重要的非负数的取值,表中已经有最大规格化数的相应内容,要求填入其他浮点数格式的相应内容。表2.16题26用表单精度双精度项目阶码尾数以2的幂次表示的值以10的幂次表示的值以2的幂次表示的值以10的幂次表示的值01最大规格化数111111101…11(2–2-23)×21273.4×1038(2–2-52)×210231.8×10308最小规格化数最大非规格化数最小非规格化数+∞NaN参考答案:表2.16题26用表单精度双精度项目阶码尾数以2的幂次表示的值以10的幂次表示的值以2的幂次表示的值以10的幂次表示的值0000000000111111111111110000000010000000000000000111111110„000„001„110„001„110„010„00010101011最大规格化数(2–2-23)×21273.4×1038(2–2-52)×210231.8×10308最小规格化数最大非规格化数最小非规格化数+∞1.0×2–126(1–2–23)×2–1261.2×10–381.2×10–381.4×10–451.0×2–10222.2×10–3082.2×10–3084.9×10–324(1–2–52)×2–10222–23×2–126=2–1492–52×2–1022––––
NaN11111111非全0––––27.已知下列字符编码:A为1000001,a为1100001,0为0110000,求E、e、f、7、G、Z、5的7位ACSII码和在第一位前加入奇校验位后的8位编码。参考答案:E的ASCII码为„A‟+(„E‟–„A‟)=1000001+100=1000101,奇校验位P=0,第一位前加入奇校验位后的8位编码是01000101。e的ASCII码为„a‟+(„e‟–„a‟)=1100001+100=1100101,奇校验位P=1,第一位前加入奇校验位后的8位编码是11100101。f的ASCII码为„a‟+(„f‟–„a‟)=1100001+101=1100110,奇校验位P=1,第一位前加入奇校验位后的8位编码是11100110。7的ASCII码为„0‟+(7-0)=0110000+111=0110111,奇校验位P=0,第一位前加入奇校验位后的8位编码是00110111。G的ASCII码为„A‟+(„G‟–„A‟)=1000001+0110=1000111,奇校验位P=1,第一位前加入奇校验位后的8位编码是11000111。Z的ASCII码为„A’+(„Z‟–„A‟)=1000001+11001=1011010,奇校验位P=1,第一位前加入奇校验位后的8位编码是11011010。5的ASCII码为„0‟+(5–0)=0110000+101=0110101,奇校验位P=1,第一位前加入奇校验位后的8位编码是10110101。28.假定在一个程序中定义了变量x、y和i,其中,x和y是float型变量(用IEEE754单精度浮点数表示),i是16位short型变量(用补码表示)。程序执行到某一时刻,x=–0.125、y=7.5、i=100,它们都被写到了主存(按字节编址),其地址分别是100,108和112。请分别画出在大端机器和小端机器上变量x、y和i中每个字节在主存的存放位置。参考答案:–0.125=–0.001B=–1.0×2-3x在机器内部的机器数为:17.5=+111.1B=+1.111×22y在机器内部的机器数为:0100=64+32+4=1100100B011111001000000100…0(BE000000H)11100…0(40F00000H)i在机器内部表示的机器数为:0000000001100100(0064H)大端机内容BEH00H00H00H40HF0H00H00H00H64H小端机地址100101102103108109110111内容00H00H00HBEH00H00HF0H40H64H00H11211329.对于图2.6,假设n=8,机器数X和Y的真值分别是x和y。请按照图2.6的功能填写表2.17,并给出对每个结果的解释。要求机器数用十六进制形式填写,真值用十进制形式填写。表2.17题29用表
表示XxYyX+Yx+yOFSFCFX-Yx-yOFSFCF无符号带符号无符号带符号0xB00x8C0xB00x7E0x7E0x8C0x5D0x5D参考答案:表2.17题29用表表示XxYyX+Yx+yOF1SF0CF1X-Y0x240x24x-y36OF0SF0CF0无符号带符号0xB00xB01760x8C1400x3C60-800x8C-1160x3C6010136000无符号带符号0x7E0x7E1261260x5D0x5D93930xDB0xDB219-371111000x210x213333000000(1)无符号整数176+140=316,无法用8位表示,即结果应有进位,CF应为1。验证正确。(2)无符号整数176-140=36,可用8位表示,即结果没有进位,CF应为0。验证正确。(3)带符号整数-80+(-116)=-316,无法用8位表示,即结果溢出,OF应为1。验证正确。(4)带符号整数-80-(-116)=36,可用8位表示,即结果不溢出,OF应为0。验证正确。(5)无符号整数126+93=219,可用8位表示,即结果没有进位,CF应为0。验证正确。(6)无符号整数126-93=33,可用8位表示,即结果没有进位,CF应为0。验证正确。(7)带符号整数126+93=219,无法用8位表示,即结果溢出,OF应为1。验证正确。(8)带符号整数126-93=33,可用8位表示,即结果不溢出,OF应为0。验证正确。无符号整数的加减运算的结果是否溢出,通过进位/借位标志CF来判断,而带符号整数的加减运算结果是否溢出,通过溢出标志OF来判断。30.在字长为32位的计算机上,有一个函数其原型声明为“intch_mul_overflow(intx,inty);”,该函数用于对两个int型变量x和y的乘积判断是否溢出,若溢出则返回1,否则返回0。请使用64位精度的整数类型longlong来编写该函数。参考答案:使用64位精度的乘法实现两个32位带符号整数相乘(专门的补码乘法运算),可以通过乘积的高32位和低32位的关系来进行溢出判断。判断规则是:若高32位中每一位都与低32位的最高位相同,则不溢出;否则溢出。1234intch_mul_overflow(intx,inty){longlongprod_64=(longlong)x*y;returnprod_64!=(int)prod_64;5}第3行赋值语句的右边采用强制类型转换,使得x和y相乘的结果强制以64位乘积的形式保留在64位longlong型变量prod_64中。在第4行关系运算符!=右边的强制类型转换,将一个64位乘积的高32位丢弃,然后,在进行关系运算时,因为关系运算符!=的左边是一个64位整数,所以,右边的32位数必须再进行符号扩展以转换为64位整数,然后再与左边的整数进行比较。若乘积没有溢出,则丢弃的高32位和后面符号扩展的32位相同,因而比较结果一定是相等,返回为0;若乘积有溢出,则比较结果一定不相等,返回为1。若第3行赋值语句改成如下形式,则prod_64得到的是低32位乘积进行符号扩展后的64位值,因此,当结果溢出时,prod_64中得到的并不是正确的64位乘积。
3longlongprod_64=x*y;31.对于第2.7.5节中例2.31存在的整数溢出漏洞,如果将其中的第5行改为以下两个语句:unsignedlonglongarraysize=count*(unsignedlonglong)sizeof(int);int*myarray=(int*)malloc(arraysize);已知C语言标准库函数malloc的原型声明为“void*malloc(size_tsize);”,其中,size_t定义为unsignedint类型,则上述改动能否消除整数溢出漏洞?若能则说明理由;若不能则给出修改方案。参考答案:上述改动无法消除整数溢出漏洞,这种改动方式虽然使得arraysize的表示范围扩大了,避免了arraysize的溢出,不过,当调用malloc函数时,若arraysize的值大于32位的unsignedint的最大可表示值,则malloc函数还是只能按32位数给出的值去申请空间,同样会发生整数溢出漏洞。程序应该在调用malloc函数之前检测所申请的空间大小是否大于32位无符号整数的可表示范围,若是,则返回-1,表示不成功;否则再申请空间并继续进行数组复制。修改后的程序如下:1/*复制数组到堆中,count为数组元素个数*/2intcopy_array(int*array,intcount){3inti;4/*在堆区申请一块内存*/5unsignedlonglongarraysize=count*(unsignedlonglong)sizeof(int);size_tmyarraysize=(size_t)arraysize;if(myarraysize!=arraysize)return-1;6789int*myarray=(int*)malloc(myarraysize);if(myarray==NULL)101112131415}return-1;for(i=0;i<count;i++)myarray[i]=array[i];returncount;32.已知一次整数加法、一次整数减法和一次移位操作都只需一个时钟周期,一次整数乘法操作需要10个时钟周期。若x为一个整型变量,现要计算55*x,请给出一种计算表达式,使得所用时钟周期数最少。参考答案:55*x=(64-8-1)*x=64*x-8*x-x根据上述表达式,只要两次移位操作和两次减法操作,共4个时钟周期。若将55分解为32+16+4+2+1,则需要4次移位操作和4次加法操作,共8个时钟周期。上述两种方式都比直接执行一次乘法操作所用的时钟周期数少。33.假设x为一个int型变量,请给出一个用来计算x/32的值的函数div32。要求不能使用除法、乘法、模运算、比较运算、循环语句和条件语句,可以使用右移、加法以及任何按位运算。参考答案:根据第2.7.6节内容可知,带符号整数x除以2k的值可以用移位方式实现。若x为正数,则将x右移k位得到商;若x为负数,则x需要加一个偏移量(2k-1)后再右移k位得到商。因此,在执行右移操作前必须先计算偏移量,计算公式如下:
0x>=0x<0b=31x的符号位在最左边,因此,表达式x>>31的计算结果得到32个符号位,x小于0时为32个1,否则为32个0。偏移量b可以通过用掩码的方式得到。函数div32的C语言源代码如下:intdiv32(intx){/*根据x的符号得到偏移量b*/intb=(x>>31)&0x1F;return(x+b)>>5;}34.无符号整数变量ux和uy的声明和初始化如下:unsignedux=x;unsigneduy=y;若sizeof(int)=4,则对于任意int型变量x和y,判断以下关系表达式是否永真。若永真则给出证明;若不永真则给出结果为假时x和y的取值。(1)(x*x)>=0(2)(x-1<0)||x>0(3)x<0||-x<=0(4)x>0||-x>=0(5)x&0xf!=15||(x<<28)<0(7)~x+~y==~(x+y)(9)((x>>2)<<2)<=x(11)x/4+y/8==(x>>2)+(y>>3)(13)x+y==ux+uy参考答案:(6)x>y==(-x<-y)(8)(int)(ux-uy)==-(y-x)(10)x*4+y*8==(x<<2)+(y<<3)(12)x*y==ux*uy(14)x*~y+ux*uy==-x(1)(x*x)>=0非永真。例如,x=65534时,则x*x=(216-2)*(216-2)=232-2*2*216+4(mod232)=-(218-4)=-262140。x的机器数为0000FFFEH,x*x的机器数为FFFC0004H。(2)(x-1<0)||x>0非永真。当x=-2147483648时,显然,x<0,机器数为80000000H,x-1的机器数为7FFFFFFFH,符号位为0,因而x-1>0。此时,(x-1<0)和x>0两者都不成立。(3)x<0||-x<=0永真。若x>0,x符号位为0且数值部分为非0(至少有一位是1),从而使-x的符号位一定是1,即则-x<0;若x=0,则-x=0。综上,只要x<0为假,则-x<=0一定为真,因而是永真。(4)x>0||-x>=0非永真。当x=-2147483648时,x<0,且x和-x的机器数都为80000000H,即-x<0。此时,x>0和-x>=0两者都不成立。(5)x&0xf!=15||(x<<28)<0非永真。这里!=的优先级比&(按位与)的优先级高。因此,若x=0,则x&0xf!=15为0,(x<<28)<0也为0,所以结果为假。(6)x>y==(-x<-y)非永真。当x=-2147483648、y任意(除-2147483648外),或者y=-2147483648、x任意(除-2147483648外)时不等。因为int型负数-2147483648是最小负数,该数取负后结果仍为-2147483648,而不是2147483648。(7)~x+~y==~(x+y)永假。[-x]补=~[x]补+1,[-y]补=~[y]补+1,故~[x]补+~[y]补=[-x]补+[-y]补-2。
[-(x+y)]补=~[x+y]补+1,故~[x+y]补=[-(x+y)]补-1=[-x]补+[-y]补-1。由此可见,左边比右边少1。(8)(int)(ux-uy)==-(y-x)永真。(int)ux-uy=[x-y]补=[x]补+[-y]补=[-y+x]补=[-(y-x)]补(9)((x>>2)<<2)<=x永真。因为右移总是向负无穷大方向取整。(10)x*4+y*8==(x<<2)+(y<<3)永真。因为带符号整数x乘以2k完全等于x左移k位,无论结果是否溢出。(11)x/4+y/8==(x>>2)+(y>>3)非永真。当x=-1或y=-1时,x/4或y/8等于0,但是,因为-1的机器数为全1,所以,x>>2或y>>3还是等于-1。此外,当x或y为负数且x不能被4整除或y不能被8整除,则x/4不等于x>>2,y/8不等于y>>3。(12)x*y==ux*uy永真。根据第2.7.5节内容可知,x*y的低32位和ux*uy的低32位是完全一样的位序列。(13)x+y==ux+uy永真。根据第2.7.4节内容可知,带符号整数和无符号整数都是在同一个整数加减运算部件中进行运算的,x和ux具有相同的机器数,y和uy具有相同的机器数,因而x+y和ux+uy具有完全一样的位序列。(14)x*~y+ux*uy==-x永真。-y=~y+1,即~y=-y-1。而ux*uy=x*y,因此,等式左边为x*(-y-1)+x*y=-x。变量dx、dy和dz的声明和初始化如下:35.doubledx=(double)x;doubledy=(double)y;doubledz=(double)z;若float和double分别采用IEEE754单精度和双精度浮点数格式,sizeof(int)=4,则对于任意int型变量x、y和z,判断以下关系表达式是否永真。若永真则给出证明;若不永真则给出结果为假时x和y的取值。(1)dx*dx>=0(2)(double)(float)x==dx(4)(dx+dy)+dz==dx+(dy+dz)(6)dx/dx==dy/dy(3)dx+dy==(double)(x+y)(5)dx*dy*dz==dz*dy*dx参考答案:(1)dx*dx>=0永真。double型数据用IEEE754标准表示,尾数用原码小数表示,符号和数值部分分开运算。不管结果是否溢出都不会影响乘积的符号。(2)(double)(float)x==dx非永真。当int型数据x的有效位数比float型可表示的最大有效位数24更多时,x强制转换为float型数据时有效位数丢失,而将x转换为double型数据时没有有效位数丢失。也即等式左边可能是近似值,而右边是精确值。(3)dx+dy==(double)(x+y)非永真。因为x+y可能会溢出,而dx+dy不会溢出。(4)(dx+dy)+dz==dx+(dy+dz)永真。因为dx、dy和dz是由32位int型数据转换得到的,而double类型可以精确表示int类型数据,并且对阶时尾数移位位数不会超过52位,因此尾数不会舍入,因而不会发生大数吃小数的情况。
但是,如果dx、dy和dz是任意double类型数据,则非永真。(5)dx*dy*dz==dz*dy*dx非永真。相乘的结果可能产生舍入。(6)dx/dx==dy/dy非永真。dx和dy中只要有一个为0、另一个不为0就不相等。36.在IEEE754浮点数运算中,当结果的尾数出现什么形式时需要进行左规,什么形式时需要进行右规?如何进行左规,如何进行右规?参考答案:(1)对于结果为±1x.xx„x的情况,需要进行右规。右规时,尾数右移一位,阶码加1。右规操作可以表示为:MbMb×2-1,EbEb+1。右规时注意以下两点:①尾数右移时,最高位“1”被移到小数点前一位作为隐藏位,最后一位移出时,要考虑舍入。②阶码加1时,直接在末位加1。(2)对于结果为±0.00„01x„x的情况,需要进行左规。左规时,数值位逐次左移,阶码逐次减1,直到将第一位“1”移到小数点左边。假定k为结果中“±”和最左边第一个1之间连续0的个数,则左规操作可以表示为:MbMb×2k,EbEb–k。左规时注意以下两点:①尾数左移时数值部分最左边k个0被移出,因此,相对来说,小数点右移了k位。因为进行尾数相加时,默认小数点位置在第一个数值位(即:隐藏位)之后,所以小数点右移k位后被移到了第一位1后面,这个1就是隐藏位。②执行EbEb–k时,每次都在末位减1,一共减k次。37.在IEEE754浮点数运算中,如何判断浮点运算的结果是否溢出?参考答案:浮点运算结果是否溢出,并不以尾数的溢出情况来判断,而主要看阶码是否溢出。尾数溢出时,可通过右规操作进行纠正。阶码上溢时,说明结果的数值太大,无法表示;阶码下溢时,说明结果数值太小,可以把结果近似为0。在进行对阶、规格化、舍入和浮点数的乘/除运算等过程中,都需要对阶码进行加、减运算,因而可能会发生阶码上溢或阶码下溢的情况,因此,必须对阶码进行溢出判断。(有关对阶码进行溢出判断的方法可参见教材中相关章节。)38.分别给出不能精确用IEEE754单精度和双精度格式表示的最小正整数。参考答案:一个整数如果有效位数大于浮点表示格式中可表示的有效位数时就不能用浮点格式精确表示。因此,当一个整数的有效位数大于24,则不能用IEEE754单精度格式精确表示,有效位数大于24的最小正整数是10„01=224+1=16777217;当一个整数的有效位数大于53,则不能IEEE754双精度格式精确表示。有效位数大于53的最小正整数是10„01=253+1。39.采用IEEE754单精度浮点数格式计算下列表达式的值。(1)0.75+(–65.25)(2)0.75–(–65.25)参考答案:x=0.75=0.110...0B=(1.10...0)2×2-1,y=–65.25=–1000001.01000...0B=(–1.00000101...0)2×26用IEEE754标准单精度格式表示为:[x]浮=00111111010...0[y]浮=110000101000001010...0所以,Ex=01111110,Mx=0(1).1...0,Ey=10000101,My=1(1).000001010...0尾数Mx和My中小数点前面有两位,第一位为数符,第二位加了括号,是隐藏位“1”。以下是计算机中进行浮点数加减运算的过程(假定保留2位附加位:保护位和舍入位)(1)0.75+(–65.25)①对阶:[ΔE]补=Ex+[–Ey]补(mod2n)=01111110+01111011=11111001,即ΔE=–7。
根据对阶规则可知需对x进行对阶,结果为:Ex=Ey=10000101,Mx=00.000000110...000Mx右移7位,符号不变,数值高位补0,隐藏位右移到小数点后面,最后移出的2位保留②尾数相加:Mb=Mx+My=00.000000110...000+11.000001010...000(注意小数点在隐藏位后)根据原码加/减法运算规则,得:00.000000110...000+11.000001010...000=11.000000100…000上式尾数中最左边第一位是符号位,其余都是数值部分,尾数后面两位是附加位(加粗)。③规格化:尾数数值部分最高位为1,因此不需要进行规格化。④舍入:把结果的尾数Mb中最后两位附加位舍入掉,从本例来看,不管采用什么舍入法,结果都一样,都是把最后两个0去掉,得:Mb=11.000000100…0⑤溢出判断:在上述阶码计算和调整过程中,没有发生“阶码上溢”和“阶码下溢”的问题。因此,阶码Eb=10000101。最后结果为Eb=10000101,Mb=1(1).00000010…0,即:–64.5。(2)0.75–(–65.25)①对阶:[ΔE]补=Ex+[–Ey]补(mod2n)=01111110+01111011=11111001,ΔE=-7。根据对阶规则可知需要对x进行对阶,结果为:Ex=Ey=10000110,Mx=00.000000110...000Mx右移一位,符号不变,数值高位补0,隐藏位右移到小数点后面,最后移出的位保留②尾数相加:Mb=Mx–My=00.000000110...000–11.000001010...000(注意小数点在隐藏位后)根据原码加/减法运算规则,得:00.000000110...000–11.000001010...000=01.00001000…000上式尾数中最左边第一位是符号位,其余都是数值部分,尾数后面两位是附加位(加粗)。③规格化:尾数数值部分最高位为1,不需要进行规格化。④舍入:把结果的尾数Mb中最后两位附加位舍入掉,从本例来看,不管采用什么舍入法,结果都一样,都是把最后两个0去掉,得:Mb=01.00001000…0⑤溢出判断:在上述阶码计算和调整过程中,没有发生“阶码上溢”和“阶码下溢”的问题。因此,阶码Eb=10000101。最后结果为Eb=10000101,Mb=0(1).00001000…0,即:+66。40.以下是函数fpower2的C语言源程序,它用于计算2x的浮点数表示,其中调用了函数u2f,u2f用于将一个无符号整数表示的0/1序列作为float类型返回。请填写fpower2函数中的空白部分,以使其能正确计算结果。1{floatfpower2(intx)23unsignedexp,frac,u;45if(x<exp=){/*值太小,返回0.0*/6;;7frac=}elseif(x<exp=8){/*返回非规格化结果*/9;;1011121314151617frac=}elseif(x<exp=){/*返回规格化结果*/;;frac=}else{exp=/*值太大,返回+∞*/;;frac=}
181920u=exp<<23|frac;returnu2f(u);}参考答案:12345floatfpower2(intx){unsignedexp,frac,u;if(x<-149){/*值太小,返回0.0*/6exp=frac=00;7;8}elseif(x<exp=-1260){/*返回非规格化结果*/9;1011121314151617181920frac=0x400000>>(-x-127);}elseif(x<exp=128){;/*返回规格化结果*/x+127frac=0;}else{exp=/*值太大,返回+∞*/2550;frac=;}u=exp<<23|frac;returnu2f(u);}41.以下是一组关于浮点数按位级进行运算的编程题目,其中用到一个数据类型float_bits,它被定义为unsignedint类型。以下程序代码必须采用IEEE754标准规定的运算规则,例如,舍入应采用就近舍入到偶数的方式。此外,代码中不能使用任何浮点数类型、浮点数运算和浮点常数,只能使用float_bits类型;不能使用任何复合数据类型,如数组、结构和联合等;可以使用无符号整数或带符号整数的数据类型、常数和运算。要求编程实现以下功能并进行正确性测试,需要针对参数f的所有32位组合情况进行处理。(1)计算浮点数f的绝对值|f|。若f为NaN,则返回f,否则返回|f|。函数原型为:float_bitsfloat_abs(float_bitsf);(2)计算浮点数f的负数-f。若f为NaN,则返回f,否则返回-f。函数原型为:float_bitsfloat_neg(float_bitsf);(3)计算0.5*f。若f为NaN,则返回f,否则返回0.5*f。函数原型为:float_bitsfloat_half(float_bitsf);(4)计算2.0*f。若f为NaN,则返回f,否则返回2.0*f。函数原型为:float_bitsfloat_twice(float_bitsf);(5)将int型整数i的位序列转换为float型位序列。函数原型为:float_bitsfloat_i2f(inti);(6)将浮点数f的位序列转换为int型位序列。若f为非规格化数,则返回值为0;若f是NaN或±∞或超出int型数可表示范围,则返回值为0x80000000;若f带小数部分,则考虑舍入。函数原型为:intfloat_f2i(float_bitsf);
参考答案:(1)计算浮点数f的绝对值|f|。若f为NaN,则返回f,否则返回|f|。float_bitsfloat_abs(float_bitsf){unsignedsign=f>>31;unsignedexp=f>>23
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 热奄包治疗知识测试题目与答案
- 树元教育考试试题及答案展示
- 2026年供用电营业人员测试卷及答案
- 焊接缺陷练习题及精准答案
- 2026年低压电工实操业务考试试卷试题及答案
- 2026年超限超载风险管控考试试卷试题及答案
- 2026年不合格品处置流程考核考试试卷试题及答案
- 2026年危险化学品从业人员安全培训考试题库及答案
- 2026年特种设备安全员考试题(附答案)
- 2026年数据库运维考核试题(附答案)
- 2025广东食品药品职业学院教师招聘考试题目及答案
- 2026年中国急性缺血性脑卒中指南
- (2025年)传染病上报培训考试题附答案
- 全国工业产品生产许可证目录(2026年版)
- 企业品牌形象策划方案书
- 建设质量安全培训制度
- 25消防设施操作员考试承诺书电子版
- 塔式起重机安拆手册(2024版)
- 2025年湖南安全技术职业学院单招(计算机)考试备考题库附答案
- 舞美搭建合同范本
- 血小板抗体检测及临床意义
评论
0/150
提交评论