C++ C+中双精度数字的数量+;在windows和Linux中是不同的。为什么?Linux显示20多个非零精度数字

C++ C+中双精度数字的数量+;在windows和Linux中是不同的。为什么?Linux显示20多个非零精度数字,c++,c,C++,C,就这样做了: double val1=numeric_limits<double>::max(); cout.precision(70); cout<<"\nVal1: "<<val1; double val1=numeric_limits::max(); 计算精度(70); cout一旦超过了double中包含的位数,编译器的库实现将决定您的命运。从二进制到十进制转换的不同算法将导致不同的输出。两者都不可能比另一个更精确。当您打印出一个双精度时,您通常需要

就这样做了:

double val1=numeric_limits<double>::max();
cout.precision(70);
cout<<"\nVal1: "<<val1;
double val1=numeric_limits::max();
计算精度(70);

cout一旦超过了double中包含的位数,编译器的库实现将决定您的命运。从二进制到十进制转换的不同算法将导致不同的输出。两者都不可能比另一个更精确。

当您打印出一个
双精度
时,您通常需要打印出很多很多数字,然后才能打印出
双精度
的准确值。可以准确地打印出
double
。例如,最接近1/3的
double
具有以下值:

0.333333333333333314829616256247390992939472198486328125
打印此值需要小数点后54位。但是人们说一个
double
只有大约16位精度。有什么好处

当你说一个双精度表有16位精度时,这意味着你至少需要16位才能使双精度表在往返过程中保持有效。即,以下过程保留输入数据:

double -> 16 digit decimal -> double
所以超过16的额外数字不一定是垃圾,它们只是不必要的。根据标准,它们几乎可以是任何东西——只要读取结果,就会得到相同的
双倍

摘要:我猜Linux上的标准库正在打印double的确切值,而Windows库正在截断结果。标准允许这两种行为

几乎可以肯定的是,您不需要double的精确值,因为浮点数的算术运算通常是不精确的。

非常简洁地定义了十进制数字和double值之间转换的边界错误:

这给出了15-17位有效小数的精度。如果 将最多包含15个有效小数的十进制字符串转换为 IEEE 754双精度,然后转换回相同的数字 则最后一个字符串应与 起初的如果IEEE 754双精度转换为 至少包含17个有效小数的十进制字符串,然后进行转换 返回到double,则最终数字必须与原始数字匹配


我认为您已经在windows上安装了g++32位版本,在linux上安装了64位版本。
只要验证您正在运行的程序,如果是32位或64位(您可以在任务管理器中查看它)

您使用的是同一个编译器吗?也就是说,
g++
两者都适用。为了让我们能够重现您所看到的-什么是
SOME BIG\u VALUE
?@Michael:刚刚更改了SOME BIG\u数值,比如说最大值为double。@todda:Windows中的Visual Studio,LinuxI上的g++我认为MSC和g++都有控制浮点精度的选项(精度与速度)。也许您在MSC上的选项与g++不同?这是否意味着小数点后的第16位在Linux中是垃圾?因为cout@gandalf34,这是完全正确的-多余的数字是垃圾。通过输出一个具有已知重复值(如1.0/3.0.Yes,(1.0/3.0))的数字来证明这一点显示:0.333333333314829616256247390992939472198486328125所以额外的数字似乎是垃圾。另外,你能告诉我为什么什么时候cout@Mark甘道夫:这些数字不是垃圾,它们是最接近1/3的
double
的精确值。错误是由除法引入的,而不是由打印引入的(在本例中)@gandalf34,从二进制数字到十进制数字之间没有严格的映射,它是近似的。如果前导数字足够小,第16位可能是可靠的。你也可能会幸运,而第16位恰好是正确的。因此,我可以安全地丢弃(或当作垃圾处理)小数点后第15位之后的任何数字。因为它可能无法保证在每次计算中都会被保留。在任何操作中,只有小数点后的15位才能保证被操作?@gandalf:double没有小数点,句号。每一次操作都会保证一定的错误,通常用术语表示对于ULP,有些运算是“正确的四舍五入”,就好像它们是以无限精度完成的,然后四舍五入为双精度。但是如果将一些运算组合在一起,精度可能会降到零。(这很复杂,这就是为什么他们教浮点数课程。)@甘道夫:例如,如果它真的是16位数字,你可以计算
(0.3-0.2)*10
得到1。你只需要一个微乎其微的精度就可以得到正确的方程式。但是,如果你使用双精度数字,你会得到不同的答案。@gandalf34,你可以在一次操作后依赖15位数字,但错误会累加起来。例如,如果你从1e16开始,并将1添加到1e16次,结果应该是2e16-但很可能是1e16。正如迪特里希所说,它变得复杂了。@Dietrich:0.3-0.2*10表达式。Got:0.999999999999977795539507496868699152736663818359375我理解double在试图将十进制数拟合到内存中的二进制数时会失去精度。但我想对自己说清楚的是,小数点后15位的任何东西肯定不会被认为是可靠的,即使它可能是正确的(更接近)十进制数的表示形式。正确吗?即使使用32位库,
double
的大小也是64位。
double -> 16 digit decimal -> double