Windows和Linux中C ++中double的精度数字。 为什么? Linux显示超过20个非零精度数字

刚刚这样做了:

double val1=numeric_limits::max(); cout.precision(70); cout<<"\nVal1: "<<val1; 

在Windows中,我开始在17位(小数点后16位)后得到0。 但是在Linux中,随着我不断增加cout.precision(NUMBER),越来越多的数字继续显示,它们不是零。

此外,运行以下代码在Windows和Linux上都显示“15”。 Windows系统是32位,Linux一个是64位,如果这有任何区别。

 typedef std::numeric_limits dl; cout << "\tdigits (decimal):\t" << dl::digits10 << endl; 

任何人都可以帮忙解释一下这里发生了什么吗? 我认为在Windows和Linux中精度数字的数量是相同的,因为sizeof(double)在它们两个上都是8。

一旦超过double中包含的位数,就会受到编译器库实现的影响。 从二进制转换为十进制的不同算法将导致不同的输出。 两者都不比另一个更准确。

当您打印出double精度数时,在打印double精确值之前,通常需要打印多个数字。 可以准确地打印出double精度数。 例如,最接近1/3的double精度值为:

 0.333333333333333314829616256247390992939472198486328125 

打印此值确切地要求小数点后54位数。 但人们说double只有大约 16位数的精度。 是什么赋予了?

当你说双精度具有16位数的精度时,这意味着你需要至少16位数来使双精度数在往返中存活。 也就是说,以下过程保留输入数据:

 double -> 16 digit decimal -> double 

因此,超过16的额外数字不一定是垃圾 ,它们只是不必要的。 根据标准,它们几乎可以是任何东西 – 只要阅读结果会给你同样的double背。

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

你几乎肯定不需要双精确值,因为浮点数的算术通常是不精确的。

双精度维基百科条目非常简洁地定义十进制数字和双精度值之间的转换的边界错误:

这给出了15-17个有效十进制数字精度。 如果具有最多15个有效小数的十进制字符串转换为IEEE 754双精度,然后转换回相同的有效小数,则最终字符串应与原始字符串匹配; 如果将IEEE 754双精度转换为具有至少17个有效小数的十进制字符串,然后再转换回双精度,则最终数字必须与原始数字匹配。

我认为你在windows上安装了g ++ 32位版本,在linux上安装了64位版本。 只需validation您正在运行的程序,如果它是32位或64位(您可以通过在任务管理器中观察来检查它)