为什么在科学/工程中经常使用浮点数?


33

在研究浮点数的准确性时,我在一些地方看到了类似于

float和double是设计 / 经常用于工程和科学计算

根据我的理解,浮点数和双精度数的强度是它们用于(良好但不是完美的)精度所使用的内存量。

我觉得我几乎从这个答案中得到了理解

“浮点数使您可以为连续数量建模”

我仍然不相信我的理解。工程学和科学听起来都像是您希望从计算中获得精确结果的领域,据我所知,浮点数不会给出。我也不确定我到底遵循什么“连续数量”。

有人可以进一步解释一下,也许举个例子吗?



47
Engineering and Science both sound like fields where you would want precise results from your calculations, which, from my understanding, floating points do not give.在科学和工程学领域,您都只关心达到特定点的精度。为每个计算使用无限精度通常不必要地昂贵。使浮点数与定点数不同的是,您不必承诺一定数量的小数位-您可以拥有非常小的数量而带有许多小数位,或者拥有非常大的数量且精度有限。
2014年

24
为了补充上述观点,不仅您不关心超出某个特定点的精度,而且由于许多输入都是具有一定固有误差的测量值,因此您无法获得任意精确的结果。

2
指出四舍五入误差不会继续累积也不是一件容易的事。这取决于您在做什么以及如何做。有一个专门的领域
2014年

10
浮点数不是“随机精度”,各种操作的错误是可以预测的并且是众所周知的,并且可以计算出算法的错误。如果它们足够低(特别是如果您的向后误差小于输入变量中的不确定性),则可以确定结果是好的(或者至少它们的任何问题不是由浮动引起的,点错误)。
hobbs 2014年

Answers:


77

科学与工程计算需要在精度,范围和速度上进行权衡。定点算法可提供精度和适当的速度,但会牺牲范围。BigNum,任意精度的库在范围和精度上都占优势,但在速度上却有所损失。

问题的症结在于,大多数科学和工程计算都需要高速,大范围的计算,但对精度的要求相对适中。确定得最好的物理常数只有大约13位数字,而且许多值的确定性要差得多。计算机上的精度超过13位将无济于事。美中不足的是浮点运算的序列会逐渐失去精度。数值分析的基本原理是找出哪些问题特别容易受到影响,并找出重新安排操作顺序以减少问题的巧妙方法。

数学中的数论是一个例外,它需要对具有数百万个位数但绝对精度的数执行算术运算。数值理论家经常使用BigNum库,并且他们花费很长时间进行计算。


2
好答案。尽管基本功能可能是完全连续的,这需要精确的精确度才能精确建模,但现实情况是,科学和工程学中的一切都是近似的。我们宁愿有体面的,有用的近似值,而要完成比无限精度更高的工作,为此,我们将永远等待许多操作完成。
乔纳森·尤尼斯

4
@JonathanEunice您无法精确模拟现实。模型的输入来自测量,您可能永远无法如此精确地测量事物,以致现代计算机/软件(当时)中的本机实数会对其进行限制。换句话说,您可以拥有完美的模型,软件或数学模型,这无关紧要。例如,计算一个盒子的体积。a*b*c简单的东西,但是您需要绝对无法测量的尺寸,因此,您实际上并不需要无限的计算精度,只要足以承受测量误差即可。
2014年

2
@ luk32我们强烈同意其中的大多数观点。一个人可以精确地建模某些事物(例如,一个球体的体积),却永远无法精确地进行度量。现实永远无法完美地契合完美的模型。与等待完美的测量或计算相比,获得稍微不精确,有用的值/模型要好得多,而这始终是一步之遥。
乔纳森·尤尼斯

2
“问题的症结在于,大多数科学和工程计算都需要高速且范围广”。如果我给您长时间,您仍然无法精确计算,因为精确计算的算法广为人知。首先,我们甚至不能精确地表示数字。这只是我们不知道如何解决的问题,无论是快速还是缓慢。
Michael Le BarbierGrünewald2014年

@MichaelGrünewald,我们不能精确地表示实数,但是我们能够以足够接近的近似值解决问题,我们可以构建几千英尺高的结构,识别DNA中的基因,并在两年后与一颗彗星会合在太空。用兰迪·纽曼(Randy Newman)的话来解释,也许不准确,但这没关系。实际上,我们可以使用任意精度库来精确地表示有理数(受内存的限制)。
查尔斯E.格兰特

30

您提出什么选择

连续数量在数学中使用实数表示。没有可以对每个可能的实数进行编码的数据类型(因为实数不可数),因此这意味着我们只能选择我们最感兴趣的那些实数的子集。

  • 您可以选择所有可计算的实数,这与计算机代数系统(CAS)相似。问题在于,随着您的表达式树越来越大,它很快变得不可行。这也非常慢:尝试在Mathematica中象征性地求解庞大的微分方程组,然后与其他基于浮点的实现进行比较,您会发现速度上的巨大差异。此外,正如JörgW Mittag和kasperd所指出的:您甚至没有可判定的平等/比较操作。

  • 您可以使用精确的有理数,但是对于许多应用程序并不能真正起作用,因为您需要计算平方根或余弦或对数等。此外,还有一种趋势,即有理变得越来越复杂,因此需要更多的存储空间在您执行越来越多的计算时需要花费更多的时间。

  • 您还可以使用任意精度的小数,但是即使除法这样简单的操作也无法使用,因为您会无限次重复数字。您也可能遇到复杂性增加的问题,因为您执行的行为与有理数更相似,但程度较小。

因此,在某些情况下您将不得不使用近似值,在这种情况下,恰恰是浮点数最有效的地方。浮点数也是固定宽度的(不同于前面提到的所有其他3种数据类型),这可以防止随着对它们执行越来越多的计算而导致复杂性增加。


1
最好的答案之一,我在写我的文章之前就忽略了它。
Michael Le BarbierGrünewald2014年

8
另外,还有一点不方便的事实,就是您甚至无法确定两个可计算的实数是否相等。
约尔格W¯¯米塔格

1
使用所有可计算的实数会不会在比较中遇到问题?我敢肯定,如果不解决暂停问题,就无法比较任意可计算实数。
kasperd 2014年

@kasperd:我认为这在某种程度上取决于允许在计算中使用的操作,尽管我不确定一组计算类型可以有多少丰富,并且仍保证可以得到任意两个任意结果可以在有限时间内比较在有限数量的操作中产生的结果。代数类型几乎肯定会满足该条件,但是我不知道是否可以添加ln(x)和exp(x)函数,并且仍然满足它。
2014年

您可以使用连续分数来支持任意精度算术(加,乘,减,除),无理数(例如√2),众所周知的先验知识(例如Pi和e),trig函数等。请参阅HAKMEM中的Gosper算法。完成后,您可以执行惰性求值,以获得接近所需精度的浮点近似值。
Paul Chernoch

14

您对科学的主张是错误的,除了数学之外,工程与科学无法获得精确的结果。它们以精度系数工作,该精度系数内置于您显示的位数中。

您需要在这里理解的关键术语是: 重要数字。数字的有效数字是带有含义的数字,有助于其准确性。

这基本上意味着,如果我声明某物长12厘米,则实际上它的长度可以在11.5至12.5厘米之间。但是,如果我声明某物长12厘米,则长度可能在11995到12005厘米之间。

只是举例说明,如果您用卷尺测量客厅。即使您发现它的宽度为6米25厘米,您也知道卷尺测量的准确性不足以告诉您有关毫米精度或纳米精度的任何信息。


@leftaroundabout您的意思是数学(就像在数学中一样)不是科学吗?在我的书中是。
Pieter B

2
@PieterB:数学不是科学。这是哲学。科学是形成对我们的物理世界的理解的行为。哲学是理解思想在理想世界中如何运作的行为。
slebetman

我认为科学通常更喜欢在明确的置信度范围内工作,而不是在有意义的范围内工作。
塔米尔(Taemyr),2014年

@slebetman除此之外,这与我在博文中的观点无关,如果数学是否是一门科学,我不禁要引述一句话:自然是天生的数学,她用数学对我们说话。我们只需要听。因为自然是数学,所以任何旨在描述自然的科学都完全依赖数学。过分强调这一点是不可能的,这就是为什么卡尔·弗里德里希·高斯称数学为“科学女王”。
Pieter B

那句话是从这里来的。一个不错的阅读和大量的讨论,但是这里没有,因为确实与您的帖子或这个问题无关。
2014年

7

请注意,浮点数基本上与科学工程符号相同,这是人类在数学和科学中写数字的标准方式。在这些领域中,对极高精度的需求不大,但通常范围很大

为了从我的物理作业中随机挑选一个例子,最近我不得不处理一个电子质量,大约为9.11 * 10 ^ -31 kg。我不在乎精度。就我而言,这很容易达到9.12。但是我关心指数,不想写0.0000 ... 911千克,所以我使用科学计数法。

类似的推理适用于科学和工程计算:范围很广,但是我们不想存储和处理非常大的数字,因此我们存储归一化的值和指数,该指数和指数较小且处理速度更快。


6

浮点数还具有一些特性,非常适合计算某些类型的科学结果。最值得注意的是,就像科学计数法一样,精度与幅度成反比,因此您既可以表示接近零的小差异,也可以表示距离很远的较大差异。

戈德堡(Goldberg)的论文可能是对浮点数的性质最著名的分析(如果您关心这种事情,则需要阅读),但我认为卡汉(Kahan)的论文在解释许多细微之处背后的原理方面做得更好。设计问题。

特别是,卡汉(Kahan)关于Java的浮点实现虽然颇具煽动性,但却为IEEE-754语义为何有用提供了许多好处,无所事事的“迹象之多”(Ado About Nothing's Sign Bit)相当深入地探讨了零号的原理。


我还没有看过Kahan的整篇论文,但他似乎比我有礼貌。如果Java添加了一个real类型,该类型需要存储三个堆栈条目,并且可以代表机器的自然计算精度,那么它本来可以比实际使用的数字具有更大的实用性和性能。该值可以存储为80位浮点数+ 16位填充64位浮点数+ 32位填充,或64位尾数,16位指数和16位用于符号和标志(对于非FPU实现)。
2014年

指定floatdouble是存储格式,real是计算格式。在许多没有FPU的系统中,使用尾数,指数和位于字和半字边界上的标志的速度要快于每次操作都必须解压缩和重新打包双精度字的速度。
2014年

2

TL; DR我们不知道如何精确地计算大多数函数,因此,没有一点可以精确地代表数字。

到目前为止,所有答案都遗漏了最重要的一点:我们无法计算大多数数字的确切值。作为一个重要的特殊情况,我们不能计算指数函数的精确值-仅引用最重要的非理性函数。

天真的答案

您的问题似乎是“存在精确的算术库,为什么我们不使用它们来代替浮点算术?”答案是精确算术可用于有理数,并且:

  • 阿基米德的数字-π的学名-不合理。
  • 许多其他重要常数也不合理。
  • 许多其他重要常数甚至都不是有理数。
  • 对于任何非零有理数x,数字exp(x)是无理的。
  • 类似的陈述适用于部首,对数以及对科学家重要的许多功能(高斯分布,其CDF,贝塞尔函数,欧拉函数等)。

有理数是幸运的意外。大多数数字不是有理数(请参阅Baire定理),因此对数进行计算将始终使我们脱离理性世界。

什么是计算并代表数字?

我们可能会说“好吧,问题在于有理数不是表示实数的好选择”。然后,我们将Debian分叉起来,为实数设计新的表示系统。

如果要计算数字,则必须为实数选择一个表示系统并描述其上的重要运算,即定义计算的含义。由于我们对科学计算感兴趣,因此我们希望准确表示所有十进制数(我们的度量),它们的商(有理数),指数函数的值以及一些有趣的常数,例如阿基米德的数。

问题在于,在这样的系统中完美表示数字的唯一方法是使用符号形式,即完全不计算任何东西并使用代数表达式。这是实数的一种残缺表示,因为我们无法可靠地比较两个数字(哪个更大)?我们甚至不能轻易回答“给定的数字等于0吗?”的问题。

例如,如果您要寻找更精确的数学定义和问题,请寻找有理数,先验数,最佳逼近和贝儿定理。


我认为这是一个很好的答案,只是不回答这个问题,就我而言,我不确定提问者将理解您的观点。这样,您就可以用有限的数字表示形式(不考虑动态或静态位宽)对\ Real或\ Complex数字进行不精确的表示了。这完全是真的,但要紧。不用机械引用Goldberg的荣誉。:) Baire定理不属于Programmers或StackOverflow上常见的修辞学。
mctylr 2014年


0

浮点数提供了相对的准确性:它们可以代表的数字最多(相对于某个数字的准确百分比)只有很小的百分比(如果您要称一个百分比为0.0000000000001%)。他们使用计算尺具有相同的特征,尽管后者并没有比3位数的精度更好。尽管如此,在数字计算机普及之前,它足以算出大型结构的静态和动态力,这是因为材料常数也显示出一些变化,并且选择对材料和结构差异合理良性的结构将趋向于发展。使最大负载和薄弱点合理可辨。

现在,“准确性”对于许多表示物理性质的测量值和/或大小的数字来说是有用的功能。

并非科学/工程学中的所有事物都属于该类别。例如,如果您使用数论变换来乘以大数,或者使用Galois字段来处理纠错多项式,那么就不会出现小错误:处理过程中的任何一位错误都将导致与完全随机的结果难以区分噪声。

即使在那些区域中,只要人们跟踪误差的累积并确保浮点误差的累积量不大到甚至可能翻转浮点数,就可以使用浮点数(例如使用复杂的FFT进行卷积)。它们是近似的实际实体。对于这样的近似值,定点处理可能会更合适,但是现场中的浮点单元倾向于提供更快的操作和更多的可用位。

同样,像C或Fortran这样的编程语言也使得访问混合精度乘法和除法或加法/减法进位等基本操作出奇地困难,而这些是超越有限精度整数的基本构造块。

因此,如果您可以将操作映射到浮点数,那么这些天您将倾向于拥有相当强大的硬件,并且可以合理地用当今的通用编程语言之一指定算法。


0

我认为可以通过解决不适合的应用程序float/ double数据类型来解决。

当您需要确保可以精确地用特定数字位数表示数字时,则浮点数是不合适的,因为它们将数字表示为2的幂,而不是10的幂,就像我们用现实中。

因此,不应使用浮点数据类型的一个域是Finance *。对于例如银行的核心系统,如果本应为$ 100000.01的金额突然变为$ 100000.00或$ 100000.02,那将是完全不可接受的。

使用浮点数时很容易发生这种问题,特别是如果数字是一个或多个计算的结果,例如,计算一个帐户中所有交易的总和。

工程和科学计算是可以接受这些较小舍入误差的领域。用户通常会意识到所有数字的精度有限,并且通常使用许多有效数字。但最重要的是,它们具有明确定义的相对精度,即,无论是很大的数字还是很小的数字,它们都提供相同数量的有效数字。

*我曾经在一个金融应用程序上做过工作,其中使用floats来表示值,因此引入了舍入误差。幸运的是,这个特定的错误根本不是关键,用户确实抱怨程序中的计算错误。这就导致了不同的效果,甚至更糟:用户开始对系统失去信心。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.