什么时候使用浮点数,什么时候使用双精度点


194

在我的编程经验中,我经常需要决定是否对实数使用float或double。有时我会选择浮动,有时我会选择双重,但这确实让我感觉更加主观。如果我要捍卫自己的决定,我可能不会给出合理的理由。

什么时候使用float和什么时候使用double?仅当存在内存限制时,您才总是使用double吗?或者,除非精度要求要求您使用double,否则您始终使用float?浮点数和双精度数之间关于基本算术的计算复杂度是否存在实质性差异?使用float或double的利弊是什么?你甚至用过长双吗?


28
在许多情况下,您既不想使用,也不想使用十进制浮点或定点类型。二进制浮点类型不能完全代表大多数小数。
CodesInChaos

3
什么引起浮点舍入错误相关?。@CodesInChaos 我的回答是建议资源来帮助您做出确定,没有一种万能的解决方案。
Mark Booth,

在以下位置找到了很好的答案:堆栈溢出
Haris

5
您所说的“小数”到底是什么意思。如果您需要精确地表示0.01之类的值(例如,为了钱),那么(二进制)浮点数并不是答案。如果仅表示非整数,则浮点数可能没问题-但是“十进制”不是描述所需内容的最佳词。
基思·汤普森

1
您并非总是有选择。例如,在Arduino平台上,double和float都等于float。您需要找到一个加载库来处理实际的双打。
kiwiron '16

Answers:


187

浮点类型的默认选择应为double。这也是您使用浮点直接获得一个不带后缀或(C语言),关于浮点数(如操作标准功能类型expsin等等)。

float 仅在需要对大量浮点数进行操作(应考虑成千上万或更多)时才应使用此方法,并且对该算法的分析表明,减小的范围和精度不会带来问题。

long double如果您需要比更大的范围或精度double,并且可以在目标平台上提供此功能,则可以使用。

总之,floatlong double应该由专家来保留使用,以double用于“每一天”使用。


10
除非存在与浮点缓存和数据传输有关的性能问题,否则我可能不会考虑使用数千个值的浮点数。通常,进行分析以表明浮点足够精确会付出巨大的代价。
Patricia Shanahan

4
作为补充,如果您需要与其他系统兼容,则使用相同的数据类型可能会比较有利。
zzzzBov

15
我会使用浮点数百万个数字,而不是1000个数字。另外,某些GPU在使用浮点数时效果更好,在特殊情况下,使用浮点数即可。如您所说,否则使用双打。
2014年

4
@PatriciaShanahan-“与...有关的性能问题。”一个很好的例子是,如果您打算使用SSE2或类似的矢量指令,则可以在float中执行4个ops / vector(vs为每双2),这可以显着提高速度(一半的操作和一半的数据进行读写)。这可以大大降低使用浮点数的门槛,值得理清数字问题。
greggo 2014年

12
我为这个答案提供了另一条建议:当使用RGB值进行显示时,可以使用float(有时是半精度),因为人眼,显示器或色彩系统都没有那么多精度。此建议适用于OpenGL等。此附加建议不适用于对精度要求更高的医学图像。
rwong 2014年

42

在针对现代计算机的代码中,很少有理由使用float而不是double。额外的精度减少(但不能消除)舍入误差或其他不精确性引起问题的机会。

我可以想到使用float的主要原因是:

  1. 您正在存储大量数字,并且需要减少程序的内存消耗。
  2. 您要针对的系统本身不支持双精度浮点。直到最近,许多图形卡仅支持单精度浮点。我敢肯定,有很多低功耗和嵌入式处理器也都具有有限的浮点支持。
  3. 您所针对的硬件是单精度比双精度快,并且您的应用程序大量使用浮点算法。在现代的Intel CPU上,我相信所有浮点计算都是以双精度完成的,因此您在此一无所获。
  4. 您正在执行低级优化,例如使用特殊的CPU指令,这些指令一次处理多个数字。

因此,基本上,除非您有硬件限制,或者除非分析表明存储双精度数字对内存使用有重大贡献,否则双精度是必经之路。


2
“现代计算机”是指Intel x86处理器。古代人使用的某些机器在基本浮球类型上提供了完全足够的精度。(CDC 6600使用了60位字,48位归一化浮点尾数,12位指数。这几乎就是x86为双精度提供的功能。)
John R. Strohm,2014年

@ John.R.Strohm:同意,但是CDC6600上不存在C编译器。是Fortran IV ...
Basile Starynkevitch 2014年

我所说的“现代计算机”是指自从过去的一到二十年,或者实际上是因为IEEE浮点标准得到广泛实施而构建的任何处理器。我完全意识到存在非x86架构,并在回答时牢记了这一点-我提到了GPU和嵌入式处理器,它们通常不是x86。
user611910

但是,那根本不是真的。SSE2可以在一次操作中操纵4个浮点或2个双打,AVX可以操纵8个浮点或4个双打,AVX-512可以操纵16个浮点或8个双打。对于任何类型的高性能计算,浮点数的数学运算应被认为是x86上双精度运算的两倍。
拉里·格里茨

1
而且,这甚至更糟,因为您可以在处理器缓存中容纳两倍于两倍的浮点数,并且内存延迟可能是许多程序的主要瓶颈。实际上,将整个浮动集保持在高速缓存中可能比使用双精度并将其溢出到RAM快一个数量级。
拉里·格里茨

10

使用double您所有的计算和临时变量。float需要维护数字数组时使用float[](如果精度足够),并且您要处理数以万计的float数字。

许多/大多数数学函数或运算符都将转换/返回double,并且您不希望将float任何中间步骤的数字都转换回去。

例如,如果您从文件或流中输入了100,000个数字,并且需要对其进行排序,则将这些数字放在中float[]


5

某些平台(ARM Cortex-M2,Cortex-M4等)不支持double(始终可以在处理器的参考手册中对其进行检查。如果没有编译警告或错误,并不表示代码是最佳的。可以模拟double。)。这就是为什么您可能需要坚持intfloat的原因

如果不是这种情况,我将使用double

您可以查看D. Goldberg着名的文章(“每位计算机科学家应了解的浮点运算法则”)。在使用浮点运算之前,您应该三思。在您的特定情况下,根本不需要它们的可能性很大。

http://perso.ens-lyon.fr/jean-michel.muller/goldberg.pdf


3
一年前,这个问题已经得到了很好的回答……但是无论如何,我想说的是,无论何时在具有双精度FPU加速的平台上使用double,您都应该在其他任何平台上使用它,即使这意味着让编译器模拟它,而不是仅使用带有浮点的FPU(请注意,并非所有平台上都需要FPU,实际上,Cortex-M4架构将它们定义为可选功能[M2是错字吗?] )。
Selali Adob​​or 2014年

该逻辑的关键是,尽管确实应该对浮点运算感到厌倦,而且它有很多“怪癖”,但绝对不会以FPU支持double来表示仅使用double而不是float。通常,浮点数比双精度点更快,并且占用的内存更少(FPU功能有所不同)。大量的使用使这一点无法过早优化。事实上,对于许多(甚至大多数)应用程序,事实加倍显然是过大的。此页面上的元素是否真的需要将其相对位置和大小计算为13个小数位?
Selali Adob​​or 2014年

2
当包含指向非现场页面或文档的链接时,请将文档中的相关信息或摘要复制到您的答案中。站外链接有随时间消失的趋势。
亚当·祖克曼

3

对于现实世界中的问题,回答此问题时,数据采样阈值很重要。同样,本底噪声也很重要。如果您的数据类型选择超出了两者之一,那么提高精度将不会带来任何好处。

大多数现实世界的采样器仅限于24位DAC。建议在有效位数为24位精度的情况下,实际计算中的32位精度应足够。

双精度会以2倍的内存成本为代价。因此,限制在浮点数上使用double会大大减少正在运行的应用程序的内存占用/带宽。


-3

在float和double之间使用哪个变量的选择取决于所需数据的准确性。如果要求答案与实际答案的差异可以忽略不计,则所需的小数位数将很多,因此将决定使用双精度数。浮点数会切掉某些小数位部分,从而降低准确性。


3
这个答案不会给问题添加任何新内容,也不会说出任何实际用途。
马丁·皮特斯

-5

通常,float当我不需要太多精度时(例如为了赚钱),我会使用该类型,这是错误的,但是我习惯于这样做。

另一方面,double当我需要更高的精度时,例如复杂的数学算法,我会使用它。

C99标准说:

共有三种浮点类型:float,double和long double。double类型提供的精度至少与float相同,而long double类型提供的精度至少与double一样。float类型的值集是double类型的值集的子集;double类型的值集合是long double类型的值集合的子集。

我从没真正使用过long double,但是我没有那么多地使用C / C ++。通常,我使用动态类型化的语言(例如Python),而不必在乎这些类型。

有关Double vs Float的更多信息,请参见SO的问题


25
使用浮点数进行认真的货币计算可能是一个错误。
Bart van Ingen Schenau 2013年

17
浮动货币是完全错误的类型。您需要使用最高精度。
克里斯·弗雷德

8
@BartvanIngenSchenau金钱的浮点数通常可以,二进制的浮点数则不行。例如,.net Decimal是浮点类型,通常是货币计算的不错选择。
CodesInChaos

13
@ChrisF您不需要金钱的“高精度”,而是需要精确的值。
肖恩·麦克索明

2
@SeanMcSomething-公平点。但是,浮点数仍然是错误的类型,考虑到大多数语言中可用的浮点类型,您需要“高精度”才能获得“精确值”。
克里斯·
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.