你怎么解释浮点的不准确到新鲜的人员和外行人仍然认为计算机是无限的明智和准确的吗?
你有喜欢的例子或者故事,似乎得到的想法跨好比一个准确的,但干,解释吗?
这是怎么教计算机科学课吗?

有帮助吗?

解决方案

基本上有两个主要缺陷的人跌倒在与浮点数。

  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. 然后还有另一个问题,虽然大多数人不陷入,除非他们正在做的大量数值的东西。但是,那些已经知道的关于这个问题。由于许多浮点数只是估算的精确值,这意味着,对于给定的逼近 f 一个真正的号码 r 可以有无限多的更加真实的数字 r1, r2,...地图完全相同的近似值。这些数字在一定的时间间隔。让我们说 rmin 是最小的可能值 r 这结果 frmax 可能的最大值 r 为此持有,那么你有一个间隔时间[rmin, rmax]其任何数目在该时间间隔可能是你的实际数量 r.

    现在,如果你执行计算,数增加、减、乘法,等等。—你失去了精度。每个数字只是一个近似值,因此,你实际上是在进行的计算 时间间隔.结果是时间间隔太近似错误永远只能获得较大,从而扩大时间间隔。你可能会得到回一个单一的数目从该计算。但是,这仅仅是 一个 数从的时间间隔 可能的 结果,考虑到精密的你的原始操作数和精确度的损失的计算。

    这种事情被称为 间隔的算术 至少对我来说这是一部分,我们的数学课程的大学。

其他提示

显示它们从基部-10系统患有准确同样的问题。

尝试来表示1/3在基座10十进制表示你将无法精确地做到这一点。

所以,如果你写的“0.3333”,你将有很多使用情况合理精确表示。

但是,如果您移动回一小部分,你会得到“10000分之3333”,这是的的一样“1/3”。

其他馏分,如1/2可以很容易地通过在碱-10的有限十进制表示表示:“0.5”

现在碱-2和基座10从基本上相同的问题的困扰:两者都具有一些数字,它们不能代表准确

尽管基极 - 10具有表示为1/10“0.1”没问题的基底-2你需要一个无限表示开头“0.000110011 ...”。

这个怎么样一个移出的门外汉。电脑表示数字的一种方法是通过计算离散单元。这是数字计算机。为整数,那些没有小数部分,现代数字计算机计数的二的幂:2 1,...,4,8 ,,,位值,二进制数位,等等,等等,等等。对于级分,数字计算机计数两个逆权力:1/2,1/4,1/8,...的问题是,许多数字不能由有限数目的这些逆功率的总和来表示。使用更多的位值(更多位)将会增加那些“问题”的数字表示的精度,但从来没有得到它正是因为它只有位的数量有限。一些数字不能与位的无限数量来表示。

暂停...

OK,你要测量水的容器体积,你只有3个量杯:满杯,半杯,和四分之一杯。计数最后满杯后,假设有剩余的杯子的三分之一。然而,你无法衡量,因为它并不完全填充可用杯的任意组合。它不填充半杯,并从四分之一杯溢出太小,补什么。所以,你有一个错误 - 1/3和1/4之间的差异。当你与其他测量的误差结合起来此错误是雪上加霜。

在蟒:

>>> 1.0 / 10
0.10000000000000001

解释如何一些馏分不能精确地以二进制表示。就像一些级分(如1/3)不能在基体10精确地表示。

又如,在C

printf (" %.20f \n", 3.6);

难以置信给出

3.60000000000000008882

下面是我的简单的理解。

问题: 值0.45,不能准确地通过浮法表示,并且四舍五入为0.450000018。为什么呢?

答案: 45 int值是由二进制值101101表示。 为了使该值0.45这将是准确的,如果它你可以采取45×10 ^ -2(=10分之45^ 2)。 但是,这是不可能的,因为你必须使用基地2而不是10。

因此,最靠近10 ^ 2 = 100。将128 = 2 ^ 7。需要的位的总数为9:6为值45(101101)+ 3比特的值7(111)。 然后将值45×2 ^ -7 = 0.3515625。现在你有一个严重的不准确的问题。 0.3515625是几乎没有接近0.45。

我们如何改善这种不准确?那么我们可以改变值45和7到别的东西。

如何约460×2 ^ -10 = 0.44921875。您现在使用的9位为10 460个4位那么它是一个有点接近,但仍然不是关闭。但是,如果你需要的初始值是0.44921875,那么你会得到一个确切的匹配,没有近似。

因此,对于你值的公式将是X = A×2 ^ B。其中A和B是整数值的正或负。 显然,较高的数字可以但较高的会成为你的准确度,你知道的位来表示值A和B是有限的数量。浮法你有32张的总数有64个和十进制具有128。

一个可爱片数值古怪的,可以观察到如果一个转换9999999.4999999999到float和回double。将结果报告为千万,即使该值明显更接近9999999,即使9999999.499999999正确两轮〜9999999。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top