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

何时使用float以及何时使用double?您是否总是使用double,仅当存在内存限制时才选择float?或者,除非精度要求要求您使用double,否则您始终使用float?在浮点数和双精度数方面,基本算术的计算复杂度是否存在实质性差异?使用float或double的利弊是什么?还有你用过长双吗?

评论

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

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

您所说的“小数”到底是什么意思。如果您需要精确地表示0.01之类的值(例如,为了钱),那么(二进制)浮点数并不是答案。如果您仅表示非整数,则浮点数可能没问题-但“十进制”不是描述所需内容的最佳词。
考虑到(从今天开始)大多数图形卡都接受双精度浮点数,因此图形编程通常使用单精度。

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

#1 楼

浮点类型的默认选择应为double。这也是使用不带后缀的浮点文字或在浮点数上运行的标准函数(在C中)(例如,expsin等)得到的类型。

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

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

总而言之,floatlong double应该保留给专家使用,带有double,可用于“每天”使用。

评论


除非存在与浮点缓存和数据传输有关的性能问题,否则我可能不会考虑使用数千个值的浮点数。为了表明浮点足够精确,通常需要花费大量的成本进行分析。

–Patricia Shanahan
13年2月28日在15:35

作为附录,如果需要与其他系统兼容,则使用相同的数据类型可能会很有利。

–zzzzBov
13年2月28日在16:30

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

–user949300
14年8月19日在16:57

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

– greggo
2014年9月9日19:03

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

–rwong
2014年11月17日22:00

#2 楼

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

我想到使用float的主要原因是: br />您正在存储大量数字,并且需要减少程序的内存消耗。
您所针对的系统本身不支持双精度浮点。直到最近,许多图形卡仅支持单精度浮点数。我确信有很多低功耗嵌入式处理器也都具有有限的浮点支持。
您所针对的硬件是单精度比双精度更快的
,并且您的应用程序大量使用了浮点算术。在现代的Intel CPU上,我相信所有的浮点计算都是以双精度进行的,因此您在这里一无所获。
您正在执行低级优化,例如使用特殊的CPU指令,这些指令一次可处理多个


因此,基本上,double是除非您有硬件限制,或者除非分析表明存储双精度数字会显着提高内存使用率,否则该方法必不可少。

评论


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

– John R. Strohm
2014年8月19日在17:03



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

–Basile Starynkevitch
2014年8月19日在20:41



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

–蒂姆·阿姆斯特朗(Tim Armstrong)
15年1月28日在21:43

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

–拉里·格里兹(Larry Gritz)
16 Sep 20 '18:19



而且,这甚至更糟,因为您可以在处理器缓存中容纳两倍于两倍的浮点数,并且内存延迟可能是许多程序的主要瓶颈。从字面上看,使整个浮动集保持温暖可能比使用双精度型并将其溢出到RAM快一个数量级。

–拉里·格里兹(Larry Gritz)
16-09-20在18:20

#3 楼

使用double进行所有计算和临时变量。需要维护数字数组时使用float-float[](如果足够的精度),并且您要处理数以万计的float数字。返回double,并且您不希望将其数字转换回float的任何中间步骤。

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

#4 楼

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

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

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

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

评论


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

–塞拉利·阿多伯(Selali Adob​​or)
2014-09-22 23:23

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

–塞拉利·阿多伯(Selali Adob​​or)
2014-09-22 23:36

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

–亚当·扎克曼(Adam Zuckerman)
2014年9月23日下午0:10

#5 楼

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

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

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

#6 楼

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

评论


该答案不会给问题添加任何新内容,也无法说出实际用途。

–马丁·彼得斯(Martijn Pieters)
2015年2月7日,11:26

#7 楼

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

当我需要更高的精度时,例如复杂的数学算法,我会使用double。 ,double和long double。
double类型的精度至少与float相同,而
long double类型的精度至少与double一样。 float类型的
值集是double类型的
值集的子集; double类型的值集合是long double类型的值集合的子集。


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

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

评论


使用浮点数进行认真的货币计算可能是一个错误。

–巴特·范·恩根·舍瑙(Bart van Ingen Schenau)
13年2月28日在10:53

浮动货币是完全错误的类型。您需要使用尽可能高的精度。

–ChrisF♦
13年2月28日在10:56



@BartvanIngenSchenau金钱的浮点数通常没问题,二进制的浮点数不是。例如,.net的Decimal是浮点类型,通常是货币计算的不错选择。

– CodesInChaos
13年2月28日在11:21



@ChrisF您不需要金钱的“高精度”,而是需要精确的值。

– Sean McSomething
13年2月28日在19:37

@SeanMcSomething-公平点。但是,浮点数仍然是错误的类型,考虑到大多数语言中可用的浮点类型,您需要“高精度”才能获得“精确值”。

–ChrisF♦
13年1月1日在8:38