【问题标题】:The same arithmetic operations give different results in C++ and Python相同的算术运算在 C++ 和 Python 中给出不同的结果
【发布时间】:2017-10-16 13:28:52
【问题描述】:

我必须找到函数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++ 的答案是错误的。

【问题讨论】:

  • 浮点数没有对错,只是或多或少准确
  • 顺便说一句,如果您确实关心准确性,那么您应该使用doule 而不是float
  • 哼。有趣的。如果你用手写的python指数怎么办?此外,来自int main() 的可编译示例和 python sn-p 的类似示例可能会让反对者远离。并从输入中读取:硬编码p
  • 欢迎来到浮点运算。检查这个问题:stackoverflow.com/questions/3846631/c-vs-python-precision
  • 我猜,python 在底层使用 cmath,区别在于解析。 C++ 给出与 std::pow(1.f-p, 2.f) 相同的结果

标签: python c++ floating-point


【解决方案1】:
#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 使用双精度,你使用浮点数。

【讨论】:

  • 是的,如果你按照自己的方式来表达,这很明显。差异太大了,不可能是其他任何东西。投赞成票。
  • 你们在这里都完全不正确。他们都使用浮点数,但精度不同。看代码,都是用float的。
  • @EamonnKenny:我不同意。请参阅 stackoverflow.com/questions/34518653/… ** 强制评估 double 或“更高”。
  • @EamonnKenny Per this float 在 python 中是 double 在 C++ 中。
  • 你对**的看法是对的,但你的逻辑仍然是错误的。如果您使用 (1-p)*(1-p) 您会得到相同的答案。 Stackoverflow 不是这方面的权威,Stroustrup 是。精度有差别。而且上面的结论是完全错误的。
【解决方案2】:

Python 实现了 IEEE 754 双精度,因此其输出更接近真实答案。

来自文档:https://docs.python.org/3/tutorial/floatingpoint.html#representation-error

今天(2000 年 11 月)几乎所有机器都使用 IEEE-754 浮点 算术,几乎所有平台都将 Python 浮点数映射到 IEEE-754 “双精度”。

在 C++ 中,浮点数是单精度的。使用 double 而不是 float 应该会给你类似的输出。

【讨论】:

    【解决方案3】:

    正如其他人所指出的,python 中的浮点数是使用 C 中的 double 类型实现的。请参阅 Python 文档的 section 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多