我知道数字表示之间的差异,但我希望有人解释一下。我们看到 float t 的值是原来的样子,我想知道为什么 f 不等于 2+t(在数学上应该是这样)但是有一点点,一点点错误[对我来说实际上是相当大的!]。
这个错误是由 int*float 乘法引入的吗?
我知道数字表示之间的差异,但我希望有人解释一下。我们看到 float t 的值是原来的样子,我想知道为什么 f 不等于 2+t(在数学上应该是这样)但是有一点点,一点点错误[对我来说实际上是相当大的!]。
这个错误是由 int*float 乘法引入的吗?
通常,整数类型的值与浮点类型的值的加法或乘法是先将整数转换为浮点数,然后再进行算术运算。如果整数值不能以浮点格式精确表示,那么甚至在执行操作之前就会引入错误。对于您示例中的小整数,这不是问题。
如果精确的数学结果不能以浮点类型表示,则算术运算将引入错误。有两种方法可能无法表示结果:
你的例子没有接近发生溢出或下溢的幅度,所以我不会在这里讨论它们。
假设您使用的是 C 实现中常用的 IEEE-754 32 位二进制浮点float
,有效位为 24 位。因此,每当您执行一个结果需要超过 24 位来表示的操作时,都会出现错误。这个 24 位跨度是从数字中的最高设置位到其最低设置位测量的。
例如 1111.11111111111111111111 2需要 24 位来表示。如果将 10000 2添加到它,则精确的数学结果是 11111.11111111111111111111 2。这需要 25 位,因此不适合,因此浮点实现必须将精确的数学结果四舍五入为可表示的结果。(在具有此特定值的常见舍入到最近模式中,它将低位向上舍入,导致所有位进位,产生 100000 2。)
现在您可以了解哪些操作会出错。如果将两个不同大小的数字相加,则较小数字的一些低位将被“推出”结果。如果这些位中的任何一个不为零,则信息丢失,发生错误。此外,结果可能会跨越二次幂边界,其最高位高于任一输入值的最高位。这将另一位从有效数字中推出。例如,如果我们将 1000 添加到 1111.11111111111111111111 2,则精确的数学结果是 10111.11111111111111111111 2。这需要 25 位,因此低位被四舍五入,产生 11000 2。
假设您有两个数字,它们的有效位需要a和b位。当您将它们相乘时,精确的数学结果需要a + b –1 或a + b位,具体取决于是否存在产生新高位的“进位”。例如,11 2 •111 2 = 10101 2,两位乘以三位产生五位。或 1.001 2 •1.01 2 = 1.01101 2,四位乘以三位产生六位。所以乘以整数会产生舍入误差。
以这种方式乘以 2 的幂绝不会产生舍入误差,尽管它可能会导致上溢或下溢。
这是因为浮点数中的浮点错误。由于浮点数只能包含一定数量的二进制数字,因此它们不能完全准确,因此在使用它们进行计算时会得到不太准确的数字。