C++ 我应该使用double还是float?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1074474/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Should I use double or float?
提问by AraK
What are the advantages and disadvantages of using one instead of the other in C++?
在 C++ 中使用一种代替另一种的优点和缺点是什么?
回答by J-16 SDiZ
If you want to know the true answer, you should read What Every Computer Scientist Should Know About Floating-Point Arithmetic.
如果你想知道真正的答案,你应该阅读 每个计算机科学家应该知道的关于浮点运算的知识。
In short, although double
allows for higher precisionin its representation, for certain calculations it would produce larger errors. The "right" choice is: use as much precision as you need but not moreand choose the right algorithm.
简而言之,虽然在其表示中double
允许更高的精度,但对于某些计算,它会产生更大的误差。“正确”的选择是:根据需要使用尽可能多的精度,但不要更多,并选择正确的算法。
Many compilers do extended floating point math in "non-strict" mode anyway (i.e. use a wider floating point type available in hardware, e.g. 80-bits and 128-bits floating), this should be taken into account as well. In practice, you can hardly see any difference in speed-- they are natives to hardware anyway.
许多编译器无论如何都会在“非严格”模式下进行扩展浮点数学运算(即使用硬件中可用的更广泛的浮点类型,例如 80 位和 128 位浮点),这也应该考虑在内。在实践中,您几乎看不到速度上的任何差异——无论如何,它们都是硬件的本机。
回答by Thomas Padron-McCarthy
Unless you have some specific reason to do otherwise, use double.
除非您有其他特殊原因,否则请使用 double。
Perhaps surprisingly, it is double and not float that is the "normal" floating-point type in C (and C++). The standard math functions such as sinand logtake doubles as arguments, and return doubles. A normal floating-point literal, as when you write 3.14in your program, has the type double. Not float.
也许令人惊讶的是,C(和 C++)中的“普通”浮点类型是 double 而不是 float。sin和log等标准数学函数将双精度数作为参数,并返回双精度数。一个普通的浮点文字,就像你在你的程序中写3.14 一样,具有 double 类型。不浮。
On typical modern computers, doubles can be just as fast as floats, or even faster, so performance is usually not a factor to consider, even for large calculations. (And those would have to be largecalculations, or performance shouldn't even enter your mind. My new i7 desktop computer can do six billion multiplications of doubles in one second.)
在典型的现代计算机上,双精度数可以与浮点数一样快,甚至更快,因此性能通常不是要考虑的因素,即使是大型计算也是如此。(而且这些必须是大型计算,否则性能甚至不应该进入您的脑海。我的新 i7 台式计算机可以在一秒钟内完成 60 亿次双精度运算。)
回答by Skizz
This question is impossible to answer since there is no context to the question. Here are some things that can affect the choice:
这个问题是不可能回答的,因为这个问题没有上下文。以下是一些会影响选择的因素:
Compiler implementation of floats, doubles and long doubles. The C++ standard states:
There are three floating point types: float, double, and long double. The type double provides at least as much precision as float, and the type long double provides at least as much precision as double.
So, all three can be the same size in memory.
Presence of an FPU. Not all CPUs have FPUs and sometimes the floating point types are emulated and sometimes the floating point types are just not supported.
FPU Architecture. The IA32's FPU is 80bit internally - 32 bit and 64 bit floats are expanded to 80bit on load and reduced on store. There's also SIMD which can do four 32bit floats or two 64bit floats in parallel. Use of SIMD is not defined in the standard so it would require a compiler that does more complex analysis to determine if SIMD can be used, or requires the use of special functions (libraries or intrinsics). The upshot of the 80bit internal format is that you can get slightly different results depending on how often the data is saved to RAM (thus, losing precision). For this reason, compilers don't optimise floating point code particularly well.
Memory bandwidth. If a double requires more storage than a float, then it will take longer to read the data. That's the naive answer. On a modern IA32, it all depends on where the data is coming from. If it's in L1 cache, the load is negligible provided the data comes from a single cache line. If it spans more than one cache line there's a small overhead. If it's from L2, it takes a while longer, if it's in RAM then it's longer still and finally, if it's on disk it's a huge time. So the choice of float or double is less important than the way the data is used. If you want to do a small calculation on lots of sequential data, a small data type is preferable. Doing a lot of computation on a small data set would allow you to use bigger data types with any significant effect. If you're accessing the data very randomly, then the choice of data size is unimportant - data is loaded in pages / cache lines. So even if you only want a byte from RAM, you could get 32 bytes transferred (this is very dependant on the architecture of the system). On top of all of this, the CPU/FPU could be super-scalar (aka pipelined). So, even though a load may take several cycles, the CPU/FPU could be busy doing something else (a multiply for instance) that hides the load time to a degree.
The standard does not enforce any particular format for floating point values.
浮点数、双精度数和长双精度数的编译器实现。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,或者需要使用特殊函数(库或内在函数)。80 位内部格式的结果是,根据数据保存到 RAM 的频率(因此会降低精度),您可以获得略有不同的结果。出于这个原因,编译器并没有特别好地优化浮点代码。
内存带宽。如果 double 比 float 需要更多的存储空间,那么读取数据将需要更长的时间。这是天真的答案。在现代 IA32 上,这完全取决于数据的来源。如果它在 L1 缓存中,如果数据来自单个缓存行,则负载可以忽略不计。如果它跨越多个缓存行,则开销很小。如果它来自 L2,它需要更长的时间,如果它在 RAM 中,那么它仍然更长,最后,如果它在磁盘上,它是一个巨大的时间。所以选择 float 还是 double 不如数据的使用方式重要。如果您想对大量连续数据进行小型计算,则最好使用小型数据类型。在小数据集上进行大量计算将允许您使用更大的数据类型并产生任何显着影响。如果你' 非常随机地重新访问数据,那么数据大小的选择并不重要 - 数据加载到页面/缓存行中。因此,即使您只需要 RAM 中的一个字节,也可以传输 32 个字节(这非常依赖于系统的架构)。最重要的是,CPU/FPU 可以是超标量(又名流水线)。因此,即使加载可能需要几个周期,CPU/FPU 也可能忙于做其他事情(例如乘法),在一定程度上隐藏加载时间。
该标准不强制任何特定的浮点值格式。
If you have a specification, then that will guide you to the optimal choice. Otherwise, it's down to experience as to what to use.
如果您有规范,那么它将指导您做出最佳选择。否则,这取决于使用什么的经验。
回答by luc
Double is more precise but is coded on 8 bytes. float is only 4 bytes, so less room and less precision.
Double 更精确,但编码为 8 个字节。float 只有 4 个字节,所以空间更小,精度也更低。
You should be very careful if you have double and float in your application. I had a bug due to that in the past. One part of the code was using float while the rest of the code was using double. Copying double to float and then float to double can cause precision error that can have big impact. In my case, it was a chemical factory... hopefully it didn't have dramatic consequences :)
如果您的应用程序中有 double 和 float ,您应该非常小心。由于过去,我有一个错误。一部分代码使用浮点数,而其余代码使用双精度数。将 double 复制到 float 然后将 float 复制到 double 会导致精度错误,这可能会产生很大的影响。就我而言,它是一家化工厂……希望它没有造成严重后果:)
I think that it is because of this kind of bug that the Ariane 6 rocket has exploded a few years ago!!!
我想,几年前阿丽亚娜6号火箭爆炸就是因为这种bug!!!
Think carefully about the type to be used for a variable
仔细考虑用于变量的类型
回答by Eric
I personnaly go for double all the time until I see some bottlenecks. Then I consider moving to float or optimizing some other part
我个人一直在加倍,直到我看到一些瓶颈。然后我考虑转向浮动或优化其他部分
回答by JaredPar
This depends on how the compiler implements double. It's legal for double and float to be the same type (and it is on some systems).
这取决于编译器如何实现 double。double 和 float 是相同类型是合法的(并且在某些系统上是这样)。
That being said, if they are indeed different, the main issue is precision. A double has a much higher precision due to it's difference in size. If the numbers you are using will commonly exceed the value of a float, then use a double.
话虽如此,如果它们确实不同,主要问题是精度。由于大小不同,double 具有更高的精度。如果您使用的数字通常会超过浮点数的值,则使用双精度数。
Several other people have mentioned performance isssues. That would be exactly last on my list of considerations. Correctness should be your #1 consideration.
其他几个人提到了性能问题。这将是我的考虑清单上的最后一个。正确性应该是您的第一考虑因素。
回答by user7116
Use whichever precision is required to achieve the appropriate results. If you then find that your code isn't performing as well as you'd like (you used profiling correct?) take a look at:
使用达到适当结果所需的任何精度。如果您随后发现您的代码表现不佳(您使用了正确的分析?),请查看:
回答by Tom
I think regardless of the differences (which as everyone points out, floats take up less space and are in general faster)... does anyone ever suffer performance issues using double? I say use double... and if later on you decide "wow, this is really slow"... find your performance bottleneck (which is probably not the fact you used double). THEN, if it's still too slow for you, see where you can sacrifice some precision and use float.
我认为无论差异如何(正如每个人所指出的,浮点数占用的空间更少,而且通常速度更快)......有没有人遇到过使用双精度数的性能问题?我说使用 double ......如果稍后你决定“哇,这真的很慢”......找到你的性能瓶颈(这可能不是你使用 double 的事实)。然后,如果它对你来说仍然太慢,看看你可以牺牲一些精度并使用浮点数。
回答by Zifre
It depends highly on the CPU the most obvious trade-offs are between precision and memory. With GBs of RAM, memory is not much of an issue, so it's generally better to use double
s.
它高度依赖于 CPU,最明显的权衡是精度和内存之间的权衡。对于 GB 的 RAM,内存不是什么大问题,因此通常最好使用double
s。
As for performance, it depends highly on the CPU. float
s will usually get better performance than double
s on a 32 bit machine. On 64 bit, double
s are sometimes faster, since it is (usually) the native size. Still, what will matter much more than your choice of data types is whether or not you can take advantage of SIMD instructions on your processor.
至于性能,它高度依赖于CPU。float
sdouble
在 32 位机器上通常会获得比s更好的性能。在 64 位上,double
s 有时更快,因为它(通常)是本机大小。尽管如此,比您选择的数据类型更重要的是您是否可以利用处理器上的 SIMD 指令。
回答by Micha?l Larouche
The main difference between float and double is precision. Wikipedia has more info about Single precision(float) and Double precision.
float 和 double 之间的主要区别是精度。维基百科有更多关于 Single precision(float) 和Double precision 的信息。