2009-07-02 164 views

回答

88

如果你想知道真正的答案,你应该阅读What Every Computer Scientist Should Know About Floating-Point Arithmetic

总之,虽然double允许在其表示更高的精度,对于某些计算它会产生较大误差。 “正确”的选择是:使用尽可能多的精度,但不是更多选择正确的算法

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

+8

是的。随着现代CPU预取越来越大的内存块,并行数值处理单元和流水线架构,速度问题实际上不成问题。 如果你处理的是大量的数字,那么4字节浮点数和8字节双精度*之间的*大小*差别可能会影响内存占用量。 – lavinio 2009-07-02 14:11:39

+5

与双精度相比,SSE(或任何vertor浮点单元)能够以单精度处理两次触发器数量。如果你只是做x87(或任何标量)浮点,那么它可能无所谓。 – 2009-07-02 14:37:22

0

double有更高的精确度,而浮动内存更少,速度更快。一般来说,你应该使用float,除非你有一个不够准确的情况。

+3

在典型的现代计算机上,double与浮动一样快。 – 2009-09-26 19:49:29

6

我personnaly所有时间去双倍,直到我看到一些瓶颈。然后我考虑移动浮动或优化其他部分

3

这取决于编译器如何实现双重。 double和float是合法的,它是相同的类型(它在某些系统上)。

这就是说,如果他们确实不同,主要问题是精确度。由于它的大小不同,双精度的精度要高得多。如果您使用的数字通常会超过浮点数,请使用double。

其他人已经提到过性能问题。这在我的考虑清单中恰好是最后一个。正确性应该是您的首要考虑因素。

1

我认为不管区别如何(正如所有人指出的那样,花车占用更少的空间,而且速度通常更快)......有没有人会遇到使用双重性能问题?我说使用双倍...如果稍后你决定“哇,这真的很慢”...找到你的性能瓶颈(这可能不是你使用双倍的事实)。那么,如果它对你来说太慢了,看看你可以牺牲一些精度并使用浮点数。

0

这取决于高度在CPU上最明显的折衷是在精度和内存之间。使用GB的RAM,内存不是什么大问题,所以通常使用double

至于性能,它高度依赖于CPU。在32位机器上,float通常会比double获得更好的性能。在64位上,double有时会更快,因为它通常是原生大小。尽管如此,重要的是您是否可以利用处理器上的SIMD指令来处理您选择的数据类型。

11

Double更精确,但是编码在8个字节上。 float只有4个字节,所以空间更小,精度更低。

如果你的应用程序中有double和float,你应该非常小心。由于过去我有一个错误。代码的一部分使用float,而其余代码使用double。将double复制为float并将其浮动为double可能会导致精度错误,从而可能产生重大影响。在我的情况下,这是一家化工厂...希望它没有造成严重后果:)

我认为这是因为阿里安6号火箭几年前爆炸的这种缺陷! !

仔细想想用于可变

26

这个问题是不可能回答的类型,因为没有上下文的问题。这里有一些可以影响选择的事情:

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

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

    因此,所有三个在内存中可以是相同的大小。

  2. 存在FPU。并非所有的CPU都具有FPU,有时会模拟浮点类型,有时仅支持浮点类型。

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

  4. 内存带宽。如果double需要比float更多的存储空间,那么读取数据需要更长的时间。这是一个天真的答案。在现代IA32上,这完全取决于数据来自何处。如果它在L1缓存中,只要数据来自单个缓存行,则负载可以忽略不计。如果它跨越多个缓存线,则会有小的开销。如果它来自L2,它需要一段时间,如果它在RAM中,那么它会更长,最后,如果它在磁盘上,这是一个很长的时间。所以float或double的选择不如数据的使用方式重要。如果你想对大量的连续数据进行小的计算,那么最好使用小数据类型。对小数据集进行大量计算可以让您使用更大的数据类型,并带来显着的效果。如果您非常随机地访问数据,那么选择数据大小并不重要 - 数据将以页面/缓存行加载。所以,即使你只需要RAM中的一个字节,也可以传输32个字节(这非常依赖于系统的体系结构)。除此之外,CPU/FPU可能超级标量(又称流水线)。因此,即使负载可能需要几个周期,CPU/FPU也可能忙于做其他事情(例如乘法),以便在一定程度上隐藏加载时间。

  5. 该标准不强制执行浮点值的任何特定格式。

如果您有一个规范,那么这将指导您的最佳选择。否则,就需要体验使用什么。

26

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

也许令人惊讶的是,它是C(和C++)中的“常规”浮点类型的双精度浮点型。标准的数学函数,如sinlog以双打为参数,并返回双打。一个正常的浮点文字,就像在程序中编写3.14一样,它的类型是double。不漂浮。

在典型的现代计算机上,双打可以像浮动一样快,甚至更快,所以即使对于大型计算,性能通常也不是一个需要考虑的因素。 (并且这些必须是计算,或者性能甚至不应该进入你的想法。我的新i7台式计算机可以在一秒内完成60亿次双打乘法运算)。