[英]C: double to int conversion error in gcc 6.3.0
我有以下c程序,有些时候我运行它,输出不同,基于编译器和平台。 我知道double to 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));
当我同时使用gcc 6.3.0和Windows 10 x64时,输出为99,但在其他情况下则不然。
以下是一些结果:
//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。
谢谢您的帮助。
对于pow(10, 2)
, pow
一些实现返回值不同于100。 例如,可以返回99.9999999999999857891452847979962825775146484375。 当此double
值转换为int
,结果为99。
这是pow
实现质量的问题。 当精确结果可能时,良好的pow
实现会返回精确的结果。
另外,我怀疑printf("%.20lf\\n", pow(10, d))
在Windows实现中没有正确格式化 - 它可能在内部转换为15位有效十进制数字之前将其格式化为20位数字输出。 您可以通过打印printf("%.20g\\n", pow(10, d)-100)
。 这将在double
算术中从pow(10, d)
中减去100。 如果它显示非零输出,你知道pow(10, d)
不完全是100,所以printf("%.20lf\\n", pow(10, d))
显示不正确的结果。
请注意, pow
是很难实现的功能。 只有有限数量的案例具有确切的结果,因此大多数结果必然是不准确的。 但是,即使在这些情况下,获得正确舍入到最接近的可表示值的结果也很困难。 据我所知,没有人用这种质量实现pow
。 大多数pow
实现允许一些额外的错误,因此你不应该依赖pow
来正确舍入。 但是,有可能实现pow
以便确切结果可能的情况确实返回确切的结果,并且一些实现实现了这一点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.