为什么在 IT 技术中会使用 float 而不是 double,或者使用 double 而不是 long double?

25

我仍然是一个编程初学者,总是有比我们的书或互联网搜索更多的问题无法回答(除非我错过了什么)。因此,如果这个问题已经被解答过,但我没有找到,请提前道歉。

我知道浮点数的范围比双精度浮点数小,因此精度较低,并且根据我的理解,长双精度浮点数甚至更加精确(?). 所以我的问题是,为什么你想要在第一次使用不太精确的变量呢?它是否与不同平台、不同操作系统版本、不同编译器有关? 还是在编程的特定时刻使用浮点数比使用双精度浮点数 / 长双精度浮点数更具战略优势?

谢谢大家!


2
当使用采用较窄形式的函数时,您不会失去精度(或者至少不会冒险这样做并收到警告)。 - chris
有时候,精度不如内存占用重要。 - Captain Obvlious
5个回答

32
在几乎所有的处理器中,“更小”的浮点数在执行时需要的时钟周期相同或更少。有时差别不是很大(或没有差别),但其他时候,doublefloat相比可以多达两倍的周期。当然,占用缓存的内存占用也是一个因素。float的大小是double的一半,而long double则更大。
编辑:更小的大小的另一个副作用是处理器的SIMD扩展(在x86中有3DNow!、SSE、AVX和其他架构中也有类似的扩展)可能只使用float,或者可以比double处理两倍的float数据量(据我所知,在任何处理器上都没有可用于long double的SIMD指令)。 因此,如果使用float而不是double,则会提高性能,一次可以处理两倍的数据。结束编辑。
因此,假设6-7位数字的精度对你所需的功能足够好,范围为+/-10^+/-38,则应使用float。 如果需要更多数字或更大范围,请使用double,如果还不够好,请使用long double。但对于大多数事情来说,double应该是完全足够的。

显然,在需要大量计算或处理大量数据时,“使用正确的大小”变得更加重要——如果有5个变量,并且您只在程序中使用每个变量几次,这会导致什么问题吗?但如果您正在进行流体动力学计算以确定一辆时速200英里的赛车表现如何,那么您可能需要计算数千万个数据点,并且需要对每个数据点进行几十次计算才能模拟出汽车行驶的每秒钟情况。然后,在每次计算中额外使用了几个时钟周期将使整个模拟过程变慢。


非常感谢,这真的帮助我理解了这些数据类型的要点。我只是希望我们的书能够说明为什么在初学者书籍中使用double(现在我知道了),而不是float,因为那些小程序从未接近过任何数据类型的边界。我只是在没有完全理解某些事情的情况下很难记忆。 - floatfil
3
单从速度上来看,浮点数并不一定比双精度数更快,通常它们在乘法运算方面都需要一个时钟周期。 - aaronman
1
@aaronman:谢谢。当评论是明智/正确的时候,我会考虑它们。这是“学习”的一部分,即使没有别的。 (尽管在这种情况下更多的是“保持简单”,而不是列举所有可能的相等、更快和更慢的变化情况,我只写了一个句子,我认为足够好了...) - Mats Petersson
@EricPostpischil 我并没有说延迟总是相同的,至于simd请看我的回答。 - aaronman
@MSalters 我想我被误解了,我的观点是有些指令的速度是相等的,所以如果这些指令占据了你代码的大部分,那么速度可能并不重要。 - aaronman
显示剩余5条评论

5
使用浮点数有两个成本,一个明显的是它的范围和精度有限,另一个则不太明显,就是这些限制会带来更加困难的分析。
通常情况下很容易确定使用双精度就足够了,即使在需要付出大量分析工作去证明浮点数足够的情况下也是如此。这样可以节省开发成本,并且如果没有正确执行更加困难的分析,则可以减少错误结果的风险。
在许多处理器上,浮点数最大的优势是其较小的内存占用。这意味着每个缓存线路上有更多的数字,并且在数字每秒传输方面有更多的内存带宽。任何计算性能的提升通常都相对较小 - 实际上,流行的处理器都会使用一种比双精度更宽的格式进行所有浮点运算。
除非满足以下两个条件,否则最好使用双精度 - 有足够的数字使其内存占用成为重要的性能问题,并且开发人员可以证明浮点数足够精确。

2
基本原则是不要超出你所需的范围。
首要考虑因素是内存使用,如果只创建一个double变量,那没什么大不了的,但如果你创建了十亿个,那么你就使用了两倍于必需的内存空间。
其次是处理器利用率。我认为,在许多处理器上,如果使用较小的数据类型,它可以执行一种多线程形式的操作。
因此,对答案的这一部分的扩展是SSE指令,基本上可以使用打包的数据同时进行多个浮点运算,在理想情况下可以将程序速度提高一倍。
最后是可读性。当有人阅读您的代码时,如果使用float,则会立即意识到您不会超过某个数字。在我看来,有时正确的精度数字会更好地流动在代码中。

1
不要过度使用:这是一个有效的观点,但正如Patricia的答案所强调的那样,降低准确性的程度是一个难以回答的问题,因此您必须在开发费用与运行时之间进行权衡... 不进行过早优化也是一个同样有效的观点。 - aka.nice
@aka.nice 我不确定这条评论的意义是什么,问题是为什么要使用float,而不是为什么要使用double。 - aaronman
是的,你提出的使用float的理由是合理的,但必须将它们与其他权衡因素相平衡,这就是我想表达的。 - aka.nice
@aka.nice 我理解这个问题并没有要求另一方的回答,暗示他们已经知道了那一面,所以我认为没有必要重复。 - aaronman

2
你可能对这里发布的答案感兴趣:Should I use double or float? 但是,问题归结为内存占用与特定情况下所需精度的平衡。在物理引擎中,你可能更关心精度,因此使用double或long double更有意义。
底线: 对于给定的算法,你只需要使用所需的精度。

并没有真正回答问题,只是同意他的陈述。 - aaronman
您应该将问题标记为重复,而不是将重复的答案发布为答案。 - aaronman

1
浮点数占用的内存比双精度浮点数少,因此,如果您不需要将数字大小设置为双精度浮点数大小,那么最好使用浮点数,因为它会占用更少的内存。
就像您不会开巴士去海滩自驾游一样...您最好选择一款两人座汽车。
对于双精度浮点数和长双精度浮点数也是如此...只要保留所需的内存。否则,在更复杂的代码中,您的进程可能会因为使用过多的内存而变慢或崩溃。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接