【问题标题】:Why does the same algorithm result in different outputs in C++ & Python?为什么相同的算法会在 C++ 和 Python 中产生不同的输出?
【发布时间】:2021-11-23 17:55:13
【问题描述】:

我正在运行一个小代码,其中存在周期性边界条件,即,对于点 0,左点是最后一个点,对于最后一个点,第零点是右点。当我在 Python 和 C++ 中运行相同的代码时,得到的答案大不相同。

Python 代码

    import numpy as np
    c= [0.467894,0.5134679,0.5123,0.476489,0.499764,0.564578]
    n= len(c)
    Δx= 1.0
    A= 1.0
    M = 1.0
    K=1.0
    Δt= 0.05

    def delf(comp):
        ans = 2*A*comp*(1-comp)*(1-2*comp)
        return ans

    def lap(e,v,w):
        laplace = (w -2*v+ e) / (Δx**2)
        return laplace

    for t in range(1000000):

        μ = np.zeros(n)
        for i in range(n):
            ans1= delf(c[i])
    
            east= i+1
            west= i-1
    
            if i==0:
                west= i-1+n
            if i== (n-1):
               east= i+1-n
        
            ans2= lap(c[east], c[i], c[west])
    
            μ[i] = ans1 - K* ans2

        dc_dt= np.zeros(n)
        for j in range(n):
            east= j+1
            west= j-1
    
            if j==0:
               west= j-1+n
            if j== (n-1):
               east= j+1-n
        
            ans= lap(μ[east], μ[j], μ[west])
    
         dc_dt[j] = M* ans
    
         for p in range(n):
             c[p] = c[p] + Δt * dc_dt[p]

    print(c)

Python 3.7.6 版本的输出是

    [0.5057488166795907, 0.5057488166581386, 0.5057488166452102,
     0.5057488166537337, 0.5057488166751858, 0.5057488166881142]

C++ 代码

    #include <iostream>

    using namespace std ;

    const float dx =1.0;
    const float dt =0.05;
    const float A= 1.0;
    const float M=1.0;
    const float K=1.0;
    const int n = 6 ;

    float delf(float comp){
        float answer = 0.0;
        answer= 2 * A* comp * (1-comp) * (1-2*comp);
        return answer; }

    float lap(float e, float v, float w){
        float laplacian= 0.0 ;
        laplacian = (e - 2*v +w) / (dx *dx);
        return laplacian; }

    int main(){
        float c[n]= {0.467894,0.5134679,0.5123,0.476489,0.499764,0.564578};
        
        for(int t=0; t<50;++t){
    
            float mu[n];
            for(int k=0; k<n; ++k){
                int east, west =0 ;
                float ans1,ans2 = 0;
        
                ans1= delf(c[k]);
        
                if (k ==0){ west = k-1+n; }
                else{ west = k-1; }
        
                if (k== (n-1)) { east = k+1-n;  }
                else{ east= k+1; }
        
                ans2= lap(c[east], c[k], c[west]);
        
                mu[k] = ans1 - K*ans2; 
            }
        
            float dc_dt[n];
            for(int p=0; p<n; ++p){
                float ans3= 0;
                int east, west =0 ;
        
                if (p ==0){ west = p-1+n; }
                else{ west = p-1;}
        
                if (p== (n-1)) { east = p+1-n; }
                else{ east= p+1; }
        
                ans3= lap(mu[east], mu[p], mu[west]);
        
                dc_dt[p] = M* ans3;
            }

            for(int q=0; q<n; ++q){         
                c[q] = c[q] + dt* dc_dt[q]; 
            }             
        }
        for(int i=0; i<n; ++i){
            cout<< c[i]<< " ";
        }            
        return 0;  
   }

C++ 中的输出是

    0.506677 0.504968 0.50404 0.50482 0.506528 0.507457

当我迭代小步时说 t

【问题讨论】:

  • 不要使用 unicode 变量名!大多数人无法输入它们...
  • 您的 C++ 代码使用 float,它具有有限的精度,并且是与 double 相对的单精度。 float 的有限精度会导致舍入问题,这使您使用已计算的值进行的计算越多。
  • 你的设置中浮动的长度是多少?
  • 你的设置中浮动的长度是多少?
  • 当我运行相同的代码时... -- 它不是相同的代码。一种代码是用 Python 编写的,另一种是用 C++ 编写的。您应该做的是查看 Python 代码,弄清楚它的作用,然后将其扔掉并在 C++ 中实现相同的东西。如果你这样做了,用 C++ 编写的代码可能看起来完全不同,但会产生相似的结果。

标签: python c++


【解决方案1】:

我拿走了你的代码,添加了大“for”循环缺少的右括号,并将长度从“50”更改为“1000000”,就像在 python 版本中一样。

然后我将所有“float”替换为“double”,结果输出为:

0.505749 0.505749 0.505749 0.505749 0.505749 0.505749

因此,当然,在 python 和 c++ 中实现相同的代码会得到相同的结果。但是,类型显然很重要。例如,整数在 python3 中的实现方式与在 c++ 或几乎任何其他语言中的实现方式非常不同。但这里要简单得多。根据定义,Python3“float”是 c++ 中的“double”。见https://docs.python.org/3/library/stdtypes.html

趣事

在 C++ 或大多数其他语言中难以重现的最简单的 Python 程序类似于

 myInt=10000000000000000000000000000000345365753523466666
 myInt = myInt*13 + 1
 print (myInt)

因为 python 可以处理任意大整数(直到你的整个计算机内存被填满)。对应的

#include <iostream>
int main(){ 
  long int myInt = 10000000000000000000000000000000345365753523466666;
  myInt = myInt*13 + 1;
  std::cout << myInt << std::endl;
  return 0;
}

只会报告警告:整数常量对于它的类型来说太大了并且会溢出并打印错误的结果。

【讨论】:

    猜你喜欢
    • 2012-06-07
    • 1970-01-01
    • 2021-10-07
    • 1970-01-01
    • 2022-12-05
    • 1970-01-01
    • 1970-01-01
    • 2013-10-21
    • 1970-01-01
    相关资源
    最近更新 更多