在C ++中使用一种代替另一种的优缺点是什么?
Answers:
如果您想知道真正的答案,则应该阅读 每位计算机科学家应该了解的有关浮点算法的内容。
简而言之,尽管double
允许其表示更高的精度,但是对于某些计算,它将产生更大的误差。“正确”的选择是:根据需要使用尽可能多的精度,而不是更多,然后选择正确的算法。
无论如何,许多编译器都在“非严格”模式下进行了扩展浮点数学运算(即,使用硬件中可用的更宽泛的浮点类型,例如80位和128位浮点),这也应予以考虑。实际上,您几乎看不到任何速度差异-无论如何它们都是硬件的本机。
double
-在大多数情况下,它是更安全的。
除非您有其他特殊原因,否则请使用double。
也许令人惊讶的是,它是double(而不是float),它是C(和C ++)中的“常规”浮点类型。标准数学函数(例如sin和log)将double用作参数,并返回double。普通的浮点文字,例如在程序中编写3.14时,其类型为double。不浮动。
在典型的现代计算机上,双精度可以与浮点数一样快,甚至更快,因此,即使对于大型计算,性能通常也不是要考虑的因素。(而且这些操作可能需要很大的计算,否则性能甚至都不会进入您的视线。我的新i7台式计算机可以在一秒钟内完成60亿倍的倍增。)
这个问题没有上下文,因此无法回答。以下是一些可能影响选择的事项:
浮点数,双打和长双打的编译器实现。C ++标准规定:
共有三种浮点类型:float,double和long double。double类型至少提供与float相同的精度,long long类型提供至少与double一样高的精度。
因此,这三个内存的大小可以相同。
FPU的存在。并非所有的CPU都有FPU,有时会仿真浮点类型,有时不支持浮点类型。
FPU体系结构。IA32的FPU内部为80位-32位和64位浮点数在负载时扩展到80位,并在存储时减少。还有SIMD,它可以并行执行四个32位浮点或两个64位浮点。SIMD的使用未在标准中定义,因此需要编译器进行更复杂的分析才能确定是否可以使用SIMD,或者需要使用特殊功能(库或内部函数)。80位内部格式的结果是,您可以根据将数据保存到RAM的频率来获得略有不同的结果(因此,精度会下降)。因此,编译器不能特别好地优化浮点代码。
内存带宽。如果双精度型需要比浮点型更多的存储空间,则读取数据将花费更长的时间。那是天真的答案。在现代的IA32上,这完全取决于数据来自何处。如果它在L1高速缓存中,则只要数据来自单个高速缓存行,负载就可以忽略不计。如果它跨越多个缓存行,则开销很小。如果来自L2,则需要花费更长的时间,如果位于RAM中,则需要更长的时间,最后,如果位于磁盘上,则需要花费很多时间。因此,选择float或double的重要性不及使用数据的方式重要。如果要对大量顺序数据进行小的计算,则最好使用小的数据类型。在较小的数据集上进行大量计算将使您可以使用较大的数据类型,而不会产生重大影响。如果你' 重新随机访问数据,则数据大小的选择并不重要-数据加载在页面/缓存行中。因此,即使您只希望从RAM中获取一个字节,也可以传输32个字节(这在很大程度上取决于系统的体系结构)。最重要的是,CPU / FPU可能是超标量的(又名流水线)。因此,即使负载可能要花费几个周期,CPU / FPU可能仍在忙于做其他事情(例如乘法),从而将负载时间隐藏到一定程度。
该标准不对浮点值强制采用任何特定格式。
如果您有规格,那将指导您进行最佳选择。否则,将无法使用什么东西。
Double更为精确,但编码为8个字节。浮点数只有4个字节,因此空间较小且精度较低。
如果应用程序中有double和float,则应格外小心。由于过去,我有一个错误。代码的一部分使用浮点数,其余的代码使用double。将double复制为float,然后将float复制为double会导致精度误差,这可能会产生很大的影响。就我而言,这是一家化工厂...希望它不会产生重大后果:)
我认为正是由于这种错误,几年前Ariane 6火箭才爆炸了!!!
仔细考虑要用于变量的类型
使用达到所需结果所需的精度。然后,如果您发现自己的代码性能不佳(使用了正确的性能分析?),请看一下:
double具有更高的精度,而float则占用更少的内存并且速度更快。通常,除非情况不够准确,否则应使用float。