C:翻倍到int转换误差在GCC 6.3.0

问题描述 投票:3回答:1

我有以下的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。

谢谢您的帮助。

c gcc output
1个回答
5
投票

从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使其中确切的结果都是可能的情况下,确实返回精确的结果,而一些应用程序实现这一目标。

© www.soinside.com 2019 - 2024. All rights reserved.