我有以下的C程序,以及一些我运行它的时候,输出不同的基础上,编译器和平台。我的理解是双到INT的转换可能会导致问题。
下面是代码:
//Compiler version gcc 6.3.0
#include <stdio.h>
#include <math.h>
int main(void){
double d = 2;
printf("%.20lf\n", pow(10, d));
printf("%d\n", (int)pow(10, d));
printf("%d\n", (int)pow(10, 2));
}
100是预期值,但声明
printf("%d\n", (int)pow(10, d));
拥有99的输出,当我同时使用GCC 6.3.0和Windows 10 64,但不是在其他情况下。
下面是一些结果:
//gcc 6.3.0 (Sublime Text 3) in Windows 10 x64
100.00000000000000000000
99 ->this is the problem
100
//gcc 6.3.0 in Android (using Dcoder app)
100.00000000000000000000
100
100
//MSVC(VS 2017 x86) in Windows 10 x64
100.00000000000000000000
100
100
我还测试了一些网上的gcc(6.3.0)的编译器,但所有的输出分别为100。
谢谢您的帮助。
从100 pow
不同pow(10, 2)
返回值的一些实施方案。例如,99.9999999999999857891452847979962825775146484375可以返回。当此double
值转换为int
,结果是99。
这是pow
实施的质量问题。好pow
实现返回精确的结果时,确切的结果是可能的。
此外,我怀疑printf("%.20lf\n", pow(10, d))
未在Windows中正确格式化的实现,它可以在内部它格式化至20位数字输出之前四舍五入其转化为类似15个显著十进制数字。您可以通过打印printf("%.20g\n", pow(10, d)-100)
进行测试。这将在pow(10, d)
算术double
减去100。如果它显示了一个非零的输出,你知道pow(10, d)
不完全是100,所以printf("%.20lf\n", pow(10, d))
显示不正确的结果。
需要注意的是pow
是落实好困难功能。只有病例数量有限,有确切的结果,所以大多数的结果必然是不准确的。然而,即使在这种情况下,得到的是正确结果四舍五入取整到最接近的可表示值是困难的。据我所知,没有人实施pow
与品质。大多数pow
实现允许一些额外的误差,因此,你不应该依赖于pow
要正确舍入。但是,它是可以实现pow
使其中确切的结果都是可能的情况下,确实返回精确的结果,而一些应用程序实现这一目标。