Dav*_*ten 29 floating-point floating-accuracy
你如何向仍然认为计算机是无限智能和准确的新鲜程序员和外行人解释浮点不准确?
你有一个最喜欢的例子或轶事似乎比一个精确但干燥的解释更好地理解这个想法吗?
这是如何在计算机科学课程中教授的?
Joe*_*oey 26
人们在浮点数上遇到了两个主要的陷阱.
规模问题.每个FP编号都有一个指数,用于确定数字的整体"比例",因此您可以表示非常小的值或非常大的值,尽管您可以为此投入的数字位数有限.添加两个不同比例的数字有时会导致较小的一个被"吃掉",因为无法将其放入更大的比例.
PS> $a = 1; $b = 0.0000000000000000000000001
PS> Write-Host a=$a b=$b
a=1 b=1E-25
PS> $a + $b
1
Run Code Online (Sandbox Code Playgroud)
作为这种情况的类比,你可以想象一个大型游泳池和一茶匙水.两者的大小差异很大,但你可以轻松掌握它们的大小.然而,将茶匙倒入游泳池将使您仍然可以使用大约一个充满水的游泳池.
(如果人们学习这种与指数符号的麻烦,还可以使用这些值1和100000000000000000000左右.)
然后是二进制与十进制表示的问题.类似的数字0.1不能用有限数量的二进制数字来精确表示.但是有些语言掩盖了这一点:
PS> "{0:N50}" -f 0.1
0.10000000000000000000000000000000000000000000000000
Run Code Online (Sandbox Code Playgroud)
但是你可以通过重复添加数字来"放大"表示错误:
PS> $sum = 0; for ($i = 0; $i -lt 100; $i++) { $sum += 0.1 }; $sum
9,99999999999998
Run Code Online (Sandbox Code Playgroud)
不过,我想不出一个很好的类比来正确解释这一点.它基本上是同样的问题,为什么你可以代表1/3的小数只有大约因为拿到你需要不断地反复,3日在小数的末尾精确值.
类似地,二进制分数有利于表示一半,四分之一,八分之一等,但是像十分之一的东西将产生无限重复的二进制数字流.
然后还有另一个问题,尽管大多数人都不会绊倒,除非他们做了大量的数字化工作.但那时,那些已经知道这个问题的人.由于许多浮点数仅仅是精确值的近似值,这意味着对于实数r的给定近似值f,可以存在无限多个更多的实数r 1,r 2,......其映射到完全相同的近似值.这些数字在一定的间隔内.比方说,[R 分是最低可能值[R导致˚F和[R 最大的最大可能值对于这个r,你得到一个间隔[ r min,r max ],其中该间隔中的任何数字都可以是你的实际数字r.
现在,如果你对这个数字进行计算 - 加法,减法,乘法等 - 就会失去精确度.每个数字只是一个近似值,因此您实际上是在执行间隔计算.结果也是间隔,并且近似误差仅变得更大,从而加宽了间隔.您可以从该计算中找回一个数字.但这只是可能结果间隔中的一个数字,考虑到原始操作数的精度和计算引起的精度损失.
这种事情被称为Interval算术,至少在我看来它是我们大学数学课程的一部分.
告诉他们基础10系统遇到完全相同的问题.
尝试在基数10中将1/3表示为十进制表示.您将无法完全执行此操作.
因此,如果您编写"0.3333",您将获得许多用例的合理精确表示.
但是,如果您移动回一小部分,你会得到"一万分之三千三百三十三",这是不一样的"1/3".
其他分数,例如1/2可以很容易地用基数为10的有限十进制表示来表示:"0.5"
现在base-2和base-10基本上也遇到了同样的问题:两者都有一些它们无法准确表示的数字.
虽然base-10没有问题,在base-2中将1/10表示为"0.1",但您需要以"0.000110011 .."开头的无限表示.
这对于外行人的解释是怎么回事?计算机代表数字的一种方法是计算离散单位.这些是数字计算机.对于整数,没有分数部分的那些,现代数字计算机计算两个幂:1,2,4,8 ,,,地方值,二进制数字,等等,等等,等等.对于分数,数字计算机计算两个的反幂:1/2,1/4,1/8,......问题是许多数不能用有限数量的这些反幂的和来表示.使用更多的位置值(更多位)将增加那些"问题"数字的表示的精度,但是从来没有完全得到它,因为它只有有限的位数.有些数字不能用无限数量的位表示.
打盹...
好的,你想测量容器中的水量,你只有3个量杯:满杯,半杯和四分之一杯.在计算完最后一个完整的杯子之后,让我们说剩余三分之一的杯子.然而,你无法衡量,因为它并没有完全填充可用杯子的任何组合.它没有填满半杯,四分之一杯的溢出量太小,无法填充任何东西.所以你有一个错误 - 1/3和1/4之间的差异.当您将其与其他测量的错误结合使用时,此错误会更加复杂.