Один и тот же числовой код возвращает различный вывод, независимо от того, находится ли он в C ++ или 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
[…]

Что не так с моим преобразованным кодом?

0

Решение

Ты используешь 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));

программа выводит более разумные значения.

3

Другие решения

Других решений пока нет …