《计算机科学导论》课后习题 第4章 数据运算

发布时间 2023-11-22 14:59:08作者: Acolyte_9527

一、复习题

Q4-1 算术运算和逻辑运算有什么区别?

A:算数运算时运用于整数和浮点数的加、减、乘、除运算。逻辑运算应用于位模式中的一个二进制位,或者在两个模式中相应的两个二进制位的相同基本运算。

Q4-2 在二进制补码格式的整数相加中,最左边一列是怎样进位的?

A:最左边一列的进位会被舍弃,因为分配给特定数据类型的内存空间是有限的。由于二进制补码格式中最左边一位代表正负号,所以如果出现进位,实际上是溢出了。

Q4-3 n的位分配单元可以等于1吗?为什么?

A:翻译令人迷惑,这里“分配单元”其实就是内存中分配的内存单元大小。比如在java编程语言中,定义一个int类型的数据,就是将4字节(即32比特)内存分配给了这个数据,用来表示一个32位的二进制补码整数;又,当我们定义一个boolean类型时,我们就将1比特分配给了这个数据,因为boolean的值只有true和false,即1和0。所以,我的答案是:可以。

Q4-4 解释"溢出"这个词。

A:在计算机科学中,“溢出”可以指代“算术溢出”、“缓冲区溢出”、“堆栈溢出”等情况,本问题中应该特指“算术溢出”,即执行单项数值计算时,计算结果大于寄存器或记忆体所能储存或表示的能力限制。详见:求闻百科·算数溢出

Q4-5 在浮点数的加法运算中,怎样调整指数不同的数的表示方法?

A:在一次浮点数的加法运算中,通常是调整指数较小的数,使其去规范化。通过在尾数中增加隐含的1,以及增加指数,尾数位移相应的位数,使得两数的指数统一。完成加法运算后,再将计算结果标准化。详见本书“附录J 实数的加减法”。

Q4-6 一元运算和二元运算有何不同?

A:一元运算只有一个输入,也就是只有一个数据参与运算。二元运算需要两个输入,也就是两个数据参与运算。

Q4-7 二元逻辑运算有哪些?

A:AND、OR、XOR。

Q4-8 什么是真值表?

A:真值表定义了对于每一种输入的输出值。详见:求闻百科·真值表

Q4-9 NOT运算符的作用是什么?

A:NOT运算符输出的是输入的反转

Q4-10 AND运算符的结果何时为真?

A:输入皆为真。

Q4-11 OR运算符的结果何时为真?

A:输入皆不为假。

Q4-12 XOR运算符的结果何时为真?

A:输入不同。

Q4-13 说出AND运算符本章讨论的一个重要特性。

A:如果一个输入中有一位是0,则不需要检查其他输入中的相应的位,便可迅速得到结果为0。这一特性在java编程中会被称为“短路运算”,具体可见我的这篇笔记:秦疆的Java课程笔记:29 基础 逻辑运算符 位运算符

Q4-14 说出OR运算符本章讨论的一个重要特性。

A:如果一个输入中有一位是1,则不需要检查其他输入中的相应的位,便可迅速得到结果为1。

Q4-15 说出XOR运算符本章讨论的一个重要特性。

A:如果输入中的一位是1,那结果就是与其他输入中相应位相反。

Q4-16 何种二元运算可以用来置位?掩码应该用什么位模式?

A:OR运算。掩码中的1位对第一个输入中相应的位进行置位,掩码中的0位使第一个输入中相应的位保持不变。

Q4-17 何种二元运算可以用来复位?掩码应该用什么位模式?

A:AND运算。掩码中的0位对第一个输入中相应的位进行复位,掩码中的1位使得第一个输入中相应的位保持不变。

Q4-18 何种二元运算可以用来反转?掩码应该用什么位模式?

A:XOR运算。掩码中的1位对第一个输入中相应的位进行反转,掩码中的0位使第一个输入中相应的位保持不变。

Q4-19 逻辑和算术移位间的区别是什么?

A:逻辑移位运算应用于不带符号位的数的模式,原因是这些移位运算可能会改变数的符号,此符号是由模式中最左位定义的。算术移位运算假定位模式是用二进制补码格式表示的带符号位的整数。算术右移被用来对整数除以2;而算术左移被用来对整数乘以2。这些运算不应该改变符号位(最左)。

二、练习题

P4-1 求下列运算的结果:

NOT 99=66
NOT FF=00
NOT 00=FF
NOT 01=FE
在模式层次的逻辑运算中,NOT其实就是求反码,还记得上一章练习题怎么给十六进制求反码吗?对,每位减去15。
我猜出题人是想让我们先转二进制。但这里姑且让我偷偷懒。

P4-2求下列运算的结果:

99 AND 99=10011001 AND 10011001=10011001=99
99 AND 00=10011001 AND 0000000=0000000=00
99 AND FF=10011001 AND 11111111=10011001=99
FF AND FF=11111111 AND 11111111=11111111=FF

P4-3求下列运算的结果:

99 OR 99=10011001 OR 10011001=10011001=99
99 OR 00=10011001 OR 0000000=10011001=99
99 OR FF=10011001 OR 11111111=11111111=FF
FF OR FF=11111111 OR 11111111=11111111=FF

P4-4求下列运算的结果:

某些运算结果上面都有,直接用。
NOT (99 OR 99)=NOT 99=01100110=66
99 OR (NOT 00)=99 OR FF=11111111=FF
(99 AND 33) OR (00 AND FF)=(10011001 AND 00110011) OR (00000000 AND 11111111)=00010001 OR 00000000=00010001=11
99 OR 33 AND (00 OR FF)=10011001 OR 00110011 AND (00000000 OR 11111111)=10111011 AND 11111111=10111011=BB

P4-5 要将一个位模式的最左4位复位(置0),求掩码和运算。

P4-5到P4-8都默认为8位二进制码。
A:AND 00001111

P4-6 要将一个位模式的最右4位置位(置1),求掩码和运算。

A:OR 00001111

P4-7 要将一个位模式的最右3位和最左2位反转,求掩码和运算。

A:XOR 11000111

P4-8 要将一个位模式的最左3位和最右2位复位,求掩码和运算。

A:AND 00011100

P4-9 用移位运算将一个无符号数除以4。

A:算术右移 2位

P4-10 用移位运算将一个无符号数乘以8。

A:算数左移 3位

P4-11 综合使用逻辑和移位运算求取一个无符号数的第4和5位。

A:原数为α。逻辑右移3位,AND 00000001,得到原数第四位。
原数α,逻辑右移4位,AND 00000001,得到原数第五位。
但是是否存在一个方法,不需要两次用到原数α呢?

P4-12 用8位分配单元,先把下列数转换成二进制补码,然后运算,再把结果转成十进制。

19+23=00010011+00010111=00101010=42
19-23=00010011-00010111=00010011+11101001=11111100=-4
-19+23=11101101+00010111=00000100=4
-19-23=11101101+11101001=11010110=-42

P4-13 用16位分配单元,先把下列数转换成二进制补码,然后运算,再把结果转成十进制。

A:略
太简单,也不存在溢出,位数太多纯折磨人。

P4-14 如果数字和结果都用8位二进制补码表示,下列哪个运算会溢出?

A:都不会溢出。

P4-15 如果数字和结果都用8位二进制补码表示,不通过实际的计算,我们能说出下列哪个运算会溢出吗?

A:第1,4项会溢出。

P4-16 假设数字皆以16位二进制补码表示法来存储,求结果。假设以十六进制表示法,结果又如何?

A:略。
看到16位二进制就不太想写。其中第2,3,4项都是溢出的。

P4-17 使用一个8位的分配单元,首先把下列每个数字转化为符号加绝对值表示法,进行运算,然后把结果转化为十进制。

A:
19+23先写成二进制符号加绝对值表示法,00010011+00010111
第一步,判断加减法:加法,不需要对减去的数字取反码。
第二步,判断两数符号异同,XOR运算:00010011 XOR 00010111=00000100,首位为0,符号相同。
第三步,绝对值相加:10011+10111=101010
第四步,检查是否溢出:否。
结果为00101010=42
因为太麻烦了,这里只写一个作为演示。符号加绝对值表示法的加减运算见附录I。

P4-18 计算下列使用 IEEE 127(参见第3章)的浮点数运算结果。

A:34.75+23.125,先分别写成IEEE 127码。
34.75=100010.11=0 10000100 00010110000000000000000
23.125=10111.001=0 10000011 01110010000000000000000
将两数去规范化,使得指数与统一为较高的指数,尾数增加隐含的1变成24位,写为:
0 10000100 100010110000000000000000
0 10000100 0101110010000000000000000
暂时忽略指数,将每个数的符号和尾数按照符号加绝对值的加减法运算(过程略)结果为:
0 10000101 111001111000000000000000
没有发生上溢,那就不需要调整尾数和指数。
再规范化(去掉尾数添加的1,尾数变回23位),结果为
0 10000101 11001111000000000000000=111001.111符合期望的结果。
因为太麻烦了,这里只写一个作为演示。详见附录J 实数的加减法。

P4-19 下列哪种情况永不会发生溢出?证明你的观点。

A:正整数加负整数,两个负整数相减。
证明正整数加负整数不会溢出:
在规定的取值范围(-c,c),对于任意c>a>0,0>b>-c,c>a+b>-c恒成立,不会发生溢出。
对于二进制补码表示法中出现的特殊情况,即当b=-c时,有a+b=a-c,则0>a-c>-c,即0>a+b>-c恒成立,不会发生溢出。
证明两个负整数相减不会溢出:
在规定的取值范围(-c,c),对于任意0>a>-c,0>b>-c,有c>-b>0,则c>a-b>-c恒成立,不会发生溢出。
对于二进制补码表示法中出现的特殊情况。
情况一:当b=-c,a≠-c时,a-b=a+c,则c>a+c>0,即c>a-b>0恒成立。
情况二:当a=-c,b≠-c时,a-b=-c-b,则0>-c-b>-c,即0>a-b>0恒成立。
情况三:当a=b=-c时,a-b=0。
以上情况均不会发生溢出。

P4-20 把一个整数加到它的反码上的结果是什么?

A:结果是所有位变成1。

P4-21 把一个整数加到它的补码上的结果是什么?

A:根据整数加减法运算法则,加补码相当于减去原数,结果应该是0。