相同的数字代码returns不同的输出无论是在C++还是C
Same numerical code returns different output whether it is in C++ or C
我得到了一个示例 C++ 数字代码以三种不同的方式计算导数。我必须将它转换为 C。我认为它不会给我任何问题,因为无论如何原始使用 cmath,但我错了。原代码如下:
#include <iostream>
#include<string>
#include <cmath>
#include <fstream>
using namespace std;
double metoda_pochodna_1(int x, double h)
{
return (sin(x+h) - sin(x)) / h;
}
double metoda_pochodna_2(int x, double h)
{
return (sin(x+(0.5*h)) - sin(x-(0.5*h))) / h;
}
double metoda_pochodna_3(int x, double h)
{
return ((sin(x-2*h) - 8*sin(x-h) + 8*sin(x+h) - sin(x+2*h)) / (12*h));
}
int main()
{
double h, w1, w2, w3, kos = cos(1.0);
int x=1;
ofstream wyniki;
wyniki.open("wyniki.dat");
for (h = pow(10.0, -15.0); h < 1; h *= 1.01)
{
w1 = log10(abs(metoda_pochodna_1(x,h) - kos));
w2 = log10(abs(metoda_pochodna_2(x,h) - kos));
w3 = log10(abs(metoda_pochodna_3(x,h) - kos));
wyniki << log10(h)<<" "<< w1 <<" "<< w2 <<" "<< w3 << "\n";
cout << log10(h)<<" "<< w1 <<" "<< w2 <<" "<< w3 << "\n";
}
wyniki.close();
cout << endl;
/*system("pause");*/ //uruchamiane z windowsa
return 0;
}
这是我的 C 版本;我刚刚更改了文件处理。注意:我在故障排除期间更改为 long double
,但生成的输出与使用常规 double
.
的版本完全相同
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
long double metoda_pochodna_1(int x,long double h)
{
return (sin(x+h) - sin(x)) / h;
}
long double metoda_pochodna_2(int x,long double h)
{
return (sin(x+(0.5*h)) - sin(x-(0.5*h))) / h;
}
long double metoda_pochodna_3(int x, long double h)
{
return ((sin(x-2*h) - 8*sin(x-h) + 8*sin(x+h) - sin(x+2*h)) / (12*h));
}
int main()
{
long double h, w1, w2, w3, kos = cos(1.0);
int x=1;
FILE * file;
file = fopen("wyniki.dat","w+");
for (h = pow(10.0, -15.0); h < 1; h *= 1.01)
{
w1 = log10(abs(metoda_pochodna_1(x,h) - kos));
w2 = log10(abs(metoda_pochodna_2(x,h) - kos));
w3 = log10(abs(metoda_pochodna_3(x,h) - kos));
fprintf(file,"%f %Lf %Lf %Lf\n",log10(h), w1,w2,w3);
printf("%f %Lf %Lf %Lf\n",log10(h), w1,w2,w3);
//wyniki << log10(h)<<" "<< w1 <<" "<< w2 <<" "<< w3 << "\n";
//cout << log10(h)<<" "<< w1 <<" "<< w2 <<" "<< w3 << "\n";
}
fclose(file);
printf("\n");
return 0;
}
这是 C++ 代码的输出,我假设它是正确的:
-15 -1.82947 -1.82947 -1.28553
-14.9957 -2.03091 -2.03091 -1.33768
14.9914 -2.41214 -2.41214 -1.39632
-14.987 -2.81915 -2.81915 -1.46341
[...]
而这是C版的输出,明显不同(前排加精度来自long double
,但其他三列都是-inf
不管是否double
或使用 long double
):
-15.000000 -inf -inf -inf
-14.995679 -inf -inf -inf
-14.991357 -inf -inf -inf
-14.987036 -inf -inf -inf
[...]
我转换后的代码有什么问题?
您正在使用 abs
,它是一个整数函数。 C浮点函数是fabs
。
将您的三行更改为
后
w1 = log10(fabs(metoda_pochodna_1(x,h) - kos));
w2 = log10(fabs(metoda_pochodna_2(x,h) - kos));
w3 = log10(fabs(metoda_pochodna_3(x,h) - kos));
程序输出更合理的值。
我得到了一个示例 C++ 数字代码以三种不同的方式计算导数。我必须将它转换为 C。我认为它不会给我任何问题,因为无论如何原始使用 cmath,但我错了。原代码如下:
#include <iostream>
#include<string>
#include <cmath>
#include <fstream>
using namespace std;
double metoda_pochodna_1(int x, double h)
{
return (sin(x+h) - sin(x)) / h;
}
double metoda_pochodna_2(int x, double h)
{
return (sin(x+(0.5*h)) - sin(x-(0.5*h))) / h;
}
double metoda_pochodna_3(int x, double h)
{
return ((sin(x-2*h) - 8*sin(x-h) + 8*sin(x+h) - sin(x+2*h)) / (12*h));
}
int main()
{
double h, w1, w2, w3, kos = cos(1.0);
int x=1;
ofstream wyniki;
wyniki.open("wyniki.dat");
for (h = pow(10.0, -15.0); h < 1; h *= 1.01)
{
w1 = log10(abs(metoda_pochodna_1(x,h) - kos));
w2 = log10(abs(metoda_pochodna_2(x,h) - kos));
w3 = log10(abs(metoda_pochodna_3(x,h) - kos));
wyniki << log10(h)<<" "<< w1 <<" "<< w2 <<" "<< w3 << "\n";
cout << log10(h)<<" "<< w1 <<" "<< w2 <<" "<< w3 << "\n";
}
wyniki.close();
cout << endl;
/*system("pause");*/ //uruchamiane z windowsa
return 0;
}
这是我的 C 版本;我刚刚更改了文件处理。注意:我在故障排除期间更改为 long double
,但生成的输出与使用常规 double
.
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
long double metoda_pochodna_1(int x,long double h)
{
return (sin(x+h) - sin(x)) / h;
}
long double metoda_pochodna_2(int x,long double h)
{
return (sin(x+(0.5*h)) - sin(x-(0.5*h))) / h;
}
long double metoda_pochodna_3(int x, long double h)
{
return ((sin(x-2*h) - 8*sin(x-h) + 8*sin(x+h) - sin(x+2*h)) / (12*h));
}
int main()
{
long double h, w1, w2, w3, kos = cos(1.0);
int x=1;
FILE * file;
file = fopen("wyniki.dat","w+");
for (h = pow(10.0, -15.0); h < 1; h *= 1.01)
{
w1 = log10(abs(metoda_pochodna_1(x,h) - kos));
w2 = log10(abs(metoda_pochodna_2(x,h) - kos));
w3 = log10(abs(metoda_pochodna_3(x,h) - kos));
fprintf(file,"%f %Lf %Lf %Lf\n",log10(h), w1,w2,w3);
printf("%f %Lf %Lf %Lf\n",log10(h), w1,w2,w3);
//wyniki << log10(h)<<" "<< w1 <<" "<< w2 <<" "<< w3 << "\n";
//cout << log10(h)<<" "<< w1 <<" "<< w2 <<" "<< w3 << "\n";
}
fclose(file);
printf("\n");
return 0;
}
这是 C++ 代码的输出,我假设它是正确的:
-15 -1.82947 -1.82947 -1.28553 -14.9957 -2.03091 -2.03091 -1.33768 14.9914 -2.41214 -2.41214 -1.39632 -14.987 -2.81915 -2.81915 -1.46341
[...]
而这是C版的输出,明显不同(前排加精度来自long double
,但其他三列都是-inf
不管是否double
或使用 long double
):
-15.000000 -inf -inf -inf -14.995679 -inf -inf -inf -14.991357 -inf -inf -inf -14.987036 -inf -inf -inf
[...]
我转换后的代码有什么问题?
您正在使用 abs
,它是一个整数函数。 C浮点函数是fabs
。
将您的三行更改为
w1 = log10(fabs(metoda_pochodna_1(x,h) - kos));
w2 = log10(fabs(metoda_pochodna_2(x,h) - kos));
w3 = log10(fabs(metoda_pochodna_3(x,h) - kos));
程序输出更合理的值。