floating-point - 浮点不准确示例

标签 floating-point floating-accuracy

<分区>

您如何向仍然认为计算机无限智能和准确的新程序员和外行解释浮点不准确?
你有没有最喜欢的例子或轶事,似乎比精确但枯燥的解释更能理解这个想法?
这在计算机科学类(class)中是如何教授的?

最佳答案

基本上人们在使用 float 时会遇到两个主要的陷阱。

  1. 规模问题。每个 FP 数字都有一个指数,它决定了数字的整体“比例”,因此您可以表示非常小的值或非常大的值,尽管您可以为此投入的位数是有限的。添加两个不同比例的数字有时会导致较小的数字被“吃掉”,因为没有办法将它放入较大的比例中。

    PS> $a = 1; $b = 0.0000000000000000000000001
    PS> Write-Host a=$a b=$b
    a=1 b=1E-25
    PS> $a + $b
    1
    

    作为这种情况的类比,您可以想象一个大游泳池和一茶匙水。两者的尺寸都非常不同,但您可以轻松掌握它们的大致尺寸。然而,将茶匙倒入游泳池中,您仍然会看到一个装满水的游泳池。

    (如果学习这个的人对指数表示法有困难,也可以使用值 1100000000000000000000 左右。)

  2. 然后是二进制与十进制表示的问题。像 0.1 这样的数字不能用有限数量的二进制数字精确表示。不过,有些语言掩盖了这一点:

    PS> "{0:N50}" -f 0.1
    0.10000000000000000000000000000000000000000000000000
    

    但是您可以通过将数字重复加在一起来“放大”表示错误:

    PS> $sum = 0; for ($i = 0; $i -lt 100; $i++) { $sum += 0.1 }; $sum
    9,99999999999998
    

    不过,我想不出一个很好的类比来恰本地解释这一点。这基本上是同一个问题,为什么你只能用十进制表示 1/3 因为要获得准确的值,你需要在小数末尾无限期地重复 3 .

    同样,二进制分数适用于表示二分之一、四分之一、八分之一等。但是像十分之一这样的东西会产生无限重复的二进制数字流。

  3. 然后还有另一个问题,尽管大多数人不会遇到这个问题,除非他们正在处理大量的数字内容。但是,那些人已经知道了这个问题。由于许多 float 只是精确值的近似值,这意味着对于实数 r 的给定近似值 f 可以有无限多的实数 r1, r2, ... 映射到完全相同的近似值。这些数字位于某个区间内。假设 rmin 是导致 fr< 的 r 的最小可能值/em>max 这适用于 r 的最大可能值,然后你得到一个区间 [rmin, rmax] 其中该区间内的任何数字都可以是您的实际数字 r

    现在,如果您对该数字执行计算(加、减、乘等),您就会失去精度。每个数字都只是一个近似值,因此您实际上是在使用间隔 执行计算。结果也是一个区间,近似误差只会越来越大,从而扩大区间。您可能会从该计算中得到一个数字。但这只是可能结果间隔中的一个数字,同时考虑到您的原始操作数的精度和计算造成的精度损失。

    那种东西叫Interval arithmetic至少对我来说,这是我们大学数学类(class)的一部分。

关于floating-point - 浮点不准确示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33775861/

相关文章:

javascript - 将 float 缩放 10 总是精确的

floating-point - 两个具有相同指数的精确表示的 float 之间的减法可以不精确吗?

javascript - JavaScript 中 float 的除法

c - 避免 float 的不准确性

c++ - float 是否可以返回 0.0 减去两个不同的值?

linux - 是否可以在 ifort 中启用舍入为零或舍入为负无穷大?

java - 修复没有 BigDecimal 的浮点精度问题

python - 机器 epsilon 的倍数是什么意思?

math - float 学有问题吗?

javascript - 在javascript中 chop (不四舍五入)小数