数据表示基础:舍入误差
来自规范 : 数据表示基础 - 舍入误差 了解并能够解释为什么定点和浮点表示的小数可能不精确。 |
为了使一个实数能够被二进制数系统精确表示,它必须能够用给定位数的二进制小数表示。某些值永远无法精确表示,例如 0.110。
处理器中的数学运算通常使用固定数量的位执行。例如,将 8 位加到 8 位。这通常不会造成任何问题。
00110011 (51) +00001010 (10) -------- 00111101 (61)
但如果我们将以下数字加在一起会发生什么
01110011 (115) +01001010 (74) -------- 10111101 (189)
这似乎运行良好,但我们遇到了问题。如果我们处理的是二进制补码数,将两个正数加在一起的结果为负数!
01110011 (115) +01001010 (74) -------- 10111101 (-67!)
让我们看一下另一个问题示例,溢出的问题。
1010 (-6) +1010 (-6) -------- (1)0100 (+4!)
如您在上面的总和中看到的,我们将两个负数加在一起,结果是正数。
为了处理上述情况,我们使用状态寄存器。
标志 | 名称 | 描述 |
---|---|---|
Z | 零标志 | 指示算术或逻辑运算(或有时是加载)的结果为零。 |
C | 进位标志 | 使大于单个字(在上面的示例中为 4 或 8 位)的数字能够通过根据需要将二进制数字从较小的字进位到较大字的最低有效位来进行加/减运算。 |
S / N | 符号标志 / 负数标志 | 一个指示结果是否为负数,而另一个指示是否发生了减法或加法。 |
O | 溢出标志 | 指示操作的带符号结果太大而无法使用二进制补码表示方式放入寄存器宽度中。 |
P | 奇偶校验标志 | 指示最后一个结果的设置位数是奇数还是偶数。 |
状态寄存器工作 对于我们之前遇到的总和,我们将看一下如何使用状态寄存器来阻止出现不正确的结果。 01110011 (115) +01001010 (74) -------- 10111101 (-67) 状态寄存器:Z = False | C = False | N = True | O = True | P = Even 使用这些标志,您可以看到结果为负数,如果原始总和只使用正值,那么我们知道我们有一个错误。 看一下另一个方程 1010 (-6) +1010 (-6) ---- (1)0100 状态寄存器:Z = False | C = True | N = False | O = True | P = Odd 使用这些标志,您可以看到结果为正数,而原始结果使用的是两个负数。我们还可以看到发生了溢出。 |
练习:状态寄存器 以下 4 位总和的结果有什么问题? 1011 (-5) +1011 (-5) ---- 答案 结果会导致溢出,从而给出不正确的结果。 1011 (-5) +1011 (-5) ---- (1)0110 (+6) 在计算的背景下,溢出是什么? 答案 当计算结果太大而无法放入固定数量的位中时。 我们需要状态寄存器做什么? 答案 状态寄存器保存标志,跟踪总和的结果,这有助于我们了解结果中何时出现错误并相应地进行更正。 说出状态寄存器中的三个标志。 答案 溢出、进位、负数、零。 显示以下总和的状态寄存器。 1001 (-7) +1001 (-7) ---- (1)0010 (+2) 答案 状态寄存器:Z = False | C = True | N = False | O = True | P = Odd |