C++和Python中相同的算术运算符会得出不同的结果

4

我需要求解一个函数 f(x) = x / (1-x)^2, 其中 0 < x < 1。并且需要将结果保留小数点后 6 位。

这是我的C++代码:

float x; scanf("%f",&x);
printf("%.6f",x/((1-x)*(1-x)));

我用Python做了同样的事情:

 x = float(input()) 
 print ("%.6f" % (x/((1-x)**2)))

对于某些x的值,这两个程序给出的答案是不同的。

例如,当x = 0.84567时,

C++给出的结果为35.505867,而Python给出的结果为35.505874

为什么会发生这种情况?
根据解决方案,Python的答案是正确的,而C++的答案是错误的。


浮点数没有对错之分,只有更或者更少准确的区别。 - 463035818_is_not_a_number
1
顺便提一下,如果你关心精度的话,应该使用 double 而不是 float - 463035818_is_not_a_number
1
嗯,有趣。如果您手写Python指数运算会怎样呢?此外,从“int main()”中提供一个可编译的示例以及类似的Python代码片段可能会避免被踩。在输入中读取时,请硬编码“p”。 - Bathsheba
欢迎来到浮点算术。请查看此问题:https://dev59.com/SlDTa4cB1Zd3GeqPM-Ed - schorsch312
related/dupe: https://dev59.com/G3RB5IYBdhLWcg3wj36c - NathanOliver
显示剩余3条评论
3个回答

4
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <iomanip>

int main()
{
    const char data[] = "0.84567";
    float x; 
    sscanf(data, "%f",&x);

    double x2;
    sscanf(data, "%lf",&x2);

    std::cout << std::setprecision(8) << (x/((1-x)*(1-x))) << std::endl;
    std::cout << std::setprecision(8) << (x2/((1-x2)*(1-x2))) << std::endl;
}

样例输出:

35.505867
35.505874

总结:

Python使用双精度浮点数,而你使用的是单精度浮点数。


是的,如果你这样表达的话,这很明显。差异太大了,不可能是其他什么。点个赞。 - Bathsheba
你们两个在这里都是完全错误的。他们都使用了浮点数,但精度不同。看看代码,它们都使用了浮点数。 - Eamonn Kenny
@EamonnKenny:我不同意。请参见https://dev59.com/NpLea4cB1Zd3GeqP3ITJ#34518772中的内容。 ** 强制在 double 或更高级别中进行评估。 - Bathsheba
根据说明,Python中的float在C++中是double - NathanOliver
@EamonnKenny 自从什么时候 Stroustrup 成为 Python 的权威了? - 463035818_is_not_a_number
显示剩余5条评论

3
Python已经实现了IEEE 754双精度,因此其输出更接近真实答案。根据文档:https://docs.python.org/3/tutorial/floatingpoint.html#representation-error。几乎所有计算机(截至2000年11月)都使用IEEE-754浮点运算,几乎所有平台将Python浮点数映射到IEEE-754“双精度”中。在C++中,float是单精度。使用double而不是float应该会给出类似的输出。

3
正如其他人指出的那样,Python中的浮点数是使用C语言中的“double”类型实现的。请参见Python文档的第5.4节
Coliru上运行此示例:
#include <cmath>
#include <cstdio>

int main()
{
    float pf = 0.84567f;
    printf("%.6f\n",pf/((1-pf)*(1-pf)));

    double pd = 0.84567;
    printf("%.6f\n",pd/((1-pd)*(1-pd)));

    return 0;
}

展示差异:
35.505867
35.505874

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接