我应该使用double还是float?


89

在C ++中使用一种代替另一种的优缺点是什么?


有没有人尝试制作一个浮点数数组和一个双精度数数组,看看是否确实在浮点数成员之间有4个字节,在双精度数成员之间有8个字节?即使64位编译器/计算机不需要那么多成员,也可能仍为每个成员保留8个字节用于浮点数。
user3015682

Answers:


104

如果您想知道真正的答案,则应该阅读 每位计算机科学家应该了解的有关浮点算法的内容

简而言之,尽管double允许其表示更高的精度,但是对于某些计算,它将产生更大的误差。“正确”的选择是:根据需要使用尽可能多的精度,而不是更多,然后选择正确的算法

无论如何,许多编译器都在“非严格”模式下进行了扩展浮点数学运算(即,使用硬件中可用的更宽泛的浮点类型,例如80位和128位浮点),这也应予以考虑。实际上,您几乎看不到任何速度差异-无论如何它们都是硬件的本机。


10
是。随着现代CPU预取越来越大的内存块,并行数值处理单元和流水线体系结构,速度问题实际上不再是问题。如果您要处理大量数字,那么4字节浮点数和8字节双精度数之间的大小差异可能会影响内存占用。
lavinio

5
SSE(或任何vertor浮点单元)与双精度相比,单精度可处理两倍的触发器数量。如果仅执行x87(或任何标量)浮点运算,则可能无关紧要。
格雷格·罗杰斯

1
@Greg Rogers:目前,编译器还不那么聪明。除非您正在编写原始程序集,否则没有太大的不同。是的,随着编译器的发展,这可能会改变。
J-16 SDiZ 2009年

补充说明:如果您完全不知道数据的样子(或者对链接中的所有数学知识一无所知),请使用double-在大多数情况下,它是更安全的。
J-16 SDiZ 2009年

2
本文不短。
jokoon 2010年

44

除非您有其他特殊原因,否则请使用double。

也许令人惊讶的是,它是double(而不是float),它是C(和C ++)中的“常规”浮点类型。标准数学函数(例如sinlog)将double用作参数,并返回double。普通的浮点文字,例如在程序中编写3.14时,其类型为double。不浮动。

在典型的现代计算机上,双精度可以与浮点数一样快,甚至更快,因此,即使对于大型计算,性能通常也不是要考虑的因素。(而且这些操作可能需要很大的计算,否则性能甚至都不会进入您的视线。我的新i7台式计算机可以在一秒钟内完成60亿倍的倍增。)


26

这个问题没有上下文,因此无法回答。以下是一些可能影响选择的事项:

  1. 浮点数,双打和长双打的编译器实现。C ++标准规定:

    共有三种浮点类型:float,double和long double。double类型至少提供与float相同的精度,long long类型提供至少与double一样高的精度。

    因此,这三个内存的大小可以相同。

  2. FPU的存在。并非所有的CPU都有FPU,有时会仿真浮点类型,有时不支持浮点类型。

  3. FPU体系结构。IA32的FPU内部为80位-32位和64位浮点数在负载时扩展到80位,并在存储时减少。还有SIMD,它可以并行执行四个32位浮点或两个64位浮点。SIMD的使用未在标准中定义,因此需要编译器进行更复杂的分析才能确定是否可以使用SIMD,或者需要使用特殊功能(库或内部函数)。80位内部格式的结果是,您可以根据将数据保存到RAM的频率来获得略有不同的结果(因此,精度会下降)。因此,编译器不能特别好地优化浮点代码。

  4. 内存带宽。如果双精度型需要比浮点型更多的存储空间,则读取数据将花费更长的时间。那是天真的答案。在现代的IA32上,这完全取决于数据来自何处。如果它在L1高速缓存中,则只要数据来自单个高速缓存行,负载就可以忽略不计。如果它跨越多个缓存行,则开销很小。如果来自L2,则需要花费更长的时间,如果位于RAM中,则需要更长的时间,最后,如果位于磁盘上,则需要花费很多时间。因此,选择float或double的重要性不及使用数据的方式重要。如果要对大量顺序数据进行小的计算,则最好使用小的数据类型。在较小的数据集上进行大量计算将使您可以使用较大的数据类型,而不会产生重大影响。如果你' 重新随机访问数据,则数据大小的选择并不重要-数据加载在页面/缓存行中。因此,即使您只希望从RAM中获取一个字节,也可以传输32个字节(这在很大程度上取决于系统的体系结构)。最重要的是,CPU / FPU可能是超标量的(又名流水线)。因此,即使负载可能要花费几个周期,CPU / FPU可能仍在忙于做其他事情(例如乘法),从而将负载时间隐藏到一定程度。

  5. 该标准不对浮点值强制采用任何特定格式。

如果您有规格,那将指导您进行最佳选择。否则,将无法使用什么东西。


16

Double更为精确,但编码为8个字节。浮点数只有4个字节,因此空间较小且精度较低。

如果应用程序中有double和float,则应格外小心。由于过去,我有一个错误。代码的一部分使用浮点数,其余的代码使用double。将double复制为float,然后将float复制为double会导致精度误差,这可能会产生很大的影响。就我而言,这是一家化工厂...希望它不会产生重大后果:)

我认为正是由于这种错误,几年前Ariane 6火箭才爆炸了!!!

仔细考虑要用于变量的类型


3
注意,甚至不能保证4/8字节的float / double,这取决于平台。甚至可能是同一类型...
sleske 2010年

2
阿丽亚娜5代码试图将64位浮点,其值是大于32,767,转换成一个16位带符号整数。这产生了溢出异常,导致火箭启动了自毁序列。有问题的代码是从旧的,较小的火箭中重复使用的代码。
cmwt

5

我一直不高兴地翻倍,直到遇到瓶颈。然后,我考虑开始浮动或优化其他部分


4

这取决于编译器如何实现double。将double和float设置为相同类型是合法的(并且在某些系统上)。

话虽如此,如果它们确实不同,则主要问题是精度。由于尺寸不同,双精度具有更高的精度。如果您使用的数字通常会超过浮点数的值,请使用双精度数。

其他几个人提到了性能问题。那将是我考虑的清单上的最后一个。正确性应该是您的第一考虑因素。



2

我认为不管有什么区别(每个人都指出,浮点数占用的空间更少,并且通常更快)...有人使用双精度函数会遇到性能问题吗?我说使用double ...,如果稍后您决定“哇,这真的很慢” ...找到您的性能瓶颈(这可能不是您使用double的事实)。然后,如果它仍然太慢,请查看可以牺牲一些精度并使用float的地方。



1

这在很大程度上取决于CPU,最明显的折衷是精度和内存之间的权衡。对于GB GB的RAM,内存并不是什么大问题,因此通常最好使用doubles。

至于性能,它在很大程度上取决于CPU。floatdouble32位计算机上的相比,s通常会获得更好的性能。在64位上,doubles有时会更快,因为它(通常)是本机大小。但是,与您选择数据类型相比,更重要的是是否可以利用处理器上的SIMD指令。


0

double具有更高的精度,而float则占用更少的内存并且速度更快。通常,除非情况不够准确,否则应使用float。


5
在典型的现代计算机上,双精度与浮点运算一样快。
Thomas Padron-McCarthy
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.