在 C++ 中使用其中一种方法与另一种方法相比,有哪些优缺点?
在 C++ 中使用其中一种方法与另一种方法相比,有哪些优缺点?
如果你想知道真实的答案,你应该阅读计算机科学家关于浮点运算应当了解的内容。
简单来说,虽然double
在表示精度上更高,但对于某些计算,它会产生更大的误差。正确的选择是:使用恰好所需的精度,而不要过多,并且选择正确的算法。
许多编译器在“非严格”模式下进行扩展浮点数学运算(即使用硬件中可用的更宽的浮点类型,例如80位和128位浮点),这也应考虑在内。实际上,你几乎看不到速度上的任何区别 - 它们本来就是硬件本地支持的。
除非你有特别的理由,否则请使用double。
或许令人惊讶的是,在C(和C ++)中,“正常”的浮点类型是double而不是float。标准数学函数(如sin和log)以double作为参数,并返回double。当你在程序中写下3.14时,普通的浮点字面值具有double类型,而不是float。
在典型现代计算机上,doubles的速度可以与floats一样快,甚至更快,因此性能通常不需要考虑,即使进行大量的计算。(那些必须是大量的计算,否则性能甚至不应该进入你的思维。我的新i7台式电脑可以在一秒钟内执行六十亿个double乘法运算。)
由于缺乏上下文,无法回答这个问题。以下是一些可能影响选择的因素:
浮点数、双精度浮点数和长双精度浮点数的编译器实现。C++标准规定:
有三种浮点类型:float、double和long double。类型double提供的精度至少与类型float相同,类型long double提供的精度至少与类型double相同。
因此,所有三种类型在内存中的大小都可能相同。
FPU的存在。并非所有CPU都有FPU,有时会模拟浮点类型,有时则不支持浮点类型。
FPU架构。IA32的FPU内部为80位 - 32位和64位浮点数在加载时扩展为80位,在存储时缩小。还有SIMD可以同时处理四个32位浮点数或两个64位浮点数。SIMD的使用在标准中未定义,因此需要编译器进行更复杂的分析,以确定是否可以使用SIMD,或者需要使用特殊功能(库或intrinsic函数)。80位内部格式的优点是,根据数据何时保存到RAM(从而丢失精度),可能会得到稍微不同的结果。因此,编译器无法特别优化浮点代码。
内存带宽。如果一个双精度数需要比一个浮点数更多的存储空间,那么读取数据就会花费更长的时间。这是一个简单的答案。在现代IA32上,所有这些都取决于数据来自哪里。如果数据在L1缓存中,只要数据来自单个缓存行,负载就可以忽略不计。如果跨越多个缓存行,则存在一些小的开销。如果来自L2,则需要更长的时间,如果在RAM中,则需要更长的时间,最后,如果在磁盘上,则需要很长时间。因此,与数据使用方式相比,选择float或double的重要性较小。如果您想对大量连续数据进行小的计算,则小型数据类型是首选。在小数据集上进行大量计算将允许您使用更大的数据类型而不会产生任何显着影响。如果您随机访问数据,则数据大小的选择无关紧要-数据以页面/缓存行方式加载。因此,即使您只想从RAM获取一个字节,也可能传输32个字节(这非常依赖于系统的架构)。除此之外,CPU/FPU可能是超标量(也称为流水线)的。因此,即使负载需要几个周期,CPU/FPU也可能会忙于执行其他任务(例如乘法),从而在一定程度上隐藏了负载时间。
标准不强制执行任何特定的浮点值格式。
如果您有规格说明,则可以指导您选择最佳选项。否则,就要依靠经验来确定使用什么。
double更精确,但编码占用8个字节。而float只占用4个字节,所以空间更少、精度也更低。
如果应用程序中同时使用了double和float,就需要非常小心。我曾经因此遇到过一个bug。代码的某一部分使用了float,而其他部分使用了double。将double复制为float,再将float复制为double可能会导致精度错误,对结果产生重大影响。在我的案例中,那是一个化工厂……幸运的是它没有造成严重后果 :)
我认为正是由于这种类型的错误,艾琳6号火箭几年前才会爆炸!!!
仔细考虑要为变量使用哪种类型。
个人意见,我一直使用双精度,直到遇到一些瓶颈。然后我考虑转换为单精度或优化其他部分。
我认为无论有何不同(正如每个人都指出的那样,浮点数占用更少的空间并且通常更快),使用double是否会导致性能问题?我建议使用double... 如果以后你发现“哇,这真的很慢”... 找到你的性能瓶颈(它可能不是你使用double的事实)。然后,如果对于你来说仍然太慢,请看看在哪里可以牺牲一些精度并使用float。
这取决于CPU,最明显的权衡在于精度和内存之间。有着GB级别的RAM,内存不是什么问题,所以通常最好使用double
。
至于性能,这高度依赖于CPU。在32位机器上,float
通常比double
获得更好的性能。在64位机器上,double
有时会更快,因为它(通常)是本地大小。然而,比起数据类型的选择,更重要的是你是否能够利用处理器上的SIMD指令。
double具有更高的精度,而float占用的内存较少且速度更快。一般来说,除非出现精度不够的情况,否则应使用float。