#include <stdio.h>
#include <math.h>
float plus(float x, float z)
{
return x+z;
}
float del(float x, float z)
{
return x/z;
}
float umn(float x, float z)
{
return x*z;
}
int ravno(float n, float k)
{
return (n==k)?1:0;
}
int bolshe(float n, float k)
{
return (n>k)?1:0;
}
int menshe(float n, float k)
{
return (n<k)?1:0;
}
float kvadrat(float x)
{
return umn(x,x);
}
float abs(float x)
{
if(bolshe(x,0))
return x;
else
return -x;
}
float a0(float x) {return x;}
float b0(float z) {return z;}
float anext(float a, float x, int k)
{
return umn(a, umn(-1, del(umn(kvadrat(x), plus(umn(2, k), 1)), plus(umn(2,k), 3))));
}
float bnext(float b, float z, int k)
{
return umn(b, umn(-1, del(umn(kvadrat(z), plus(umn(2, k), 1)), plus(umn(2,k), 3))));
}
float y_telo(float x, float z, float acount, float bcount, float a, float b, float a_next, float b_next, float eps, int k)
{
if(menshe(abs(plus(a_next,b_next)), eps))
{
return plus(plus(acount, bcount), plus(a_next, b_next));
}
else
{
y_telo(x,z, acount+a_next, bcount+b_next, a_next,b_next,anext(a_next,x,plus(k,1)),bnext(b_next,z,plus(k,1)), eps, plus(k,1));
}
}
float yfunc(float x, float z, float eps)
{
return y_telo(x,z,a0(x),b0(z),a0(x),b0(z),anext(a0(x),x,0),bnext(b0(z),z,0), eps, 0);
}
int main()
{
float x = 0.2; float z = 0.3; float eps = 0.1;
printf("%f\n", yfunc(x,z,eps));
printf("%f\n", atan((x+z)/(1-x*z)));
return 0;
}
g++ выдает nan
Код:
компилирую так
Код:
g++ -o lab1 lab1.c
Здесь x и z операнды, eps точность... При eps=0.1 вычисляет нормально, и значение очень похоже на значение встроенной функции, но при увеличении точности (eps=0.01 eps=0.001 и т.д.), вместо значения выдается nan. В чем проблема?
Арктангенс умеет вычислять сам сопроцессор. Зачем применять разложение в ряд?
Но если модифицировать две функции, которые работают последними непосредственно перед выводом результата:
Код:
float y_telo(float x, float z, float acount, float bcount, float a, float b, float a_next, float b_next, float eps, int k)
{
if(menshe(abs(plus(a_next,b_next)), eps))
{
float result_0=plus(plus(acount, bcount), plus(a_next, b_next));
printf("result_0 = %f\n", result_0);
return result_0;
}
else
{
y_telo(x,z, acount+a_next, bcount+b_next, a_next,b_next,anext(a_next,x,plus(k,1)),bnext(b_next,z,plus(k,1)), eps, plus(k,1));
}
}
float yfunc(float x, float z, float eps)
{
float result_1 = y_telo(x,z,a0(x),b0(z),a0(x),b0(z),anext(a0(x),x,0),bnext(b0(z),z,0), eps, 0);
printf("result_1 = %f\n", result_1);
return result_1;
}
{
if(menshe(abs(plus(a_next,b_next)), eps))
{
float result_0=plus(plus(acount, bcount), plus(a_next, b_next));
printf("result_0 = %f\n", result_0);
return result_0;
}
else
{
y_telo(x,z, acount+a_next, bcount+b_next, a_next,b_next,anext(a_next,x,plus(k,1)),bnext(b_next,z,plus(k,1)), eps, plus(k,1));
}
}
float yfunc(float x, float z, float eps)
{
float result_1 = y_telo(x,z,a0(x),b0(z),a0(x),b0(z),anext(a0(x),x,0),bnext(b0(z),z,0), eps, 0);
printf("result_1 = %f\n", result_1);
return result_1;
}
то результат будет такой:
Цитата:
$ ./lab1
result_0 = 0.488883
result_1 = nan
nan
0.488852
result_0 = 0.488883
result_1 = nan
nan
0.488852
Т.е. видно, что возвращаемый параметр неожиданно ломается при передаче из одной функции в другую. Почему так - в душе не знаю, может где переполнения буферов или еще что. Дебаггер в руки - и отлаживайте. Где, на первый взгляд, кроется косяк, я показал.
Еще гляньте
Цитата: Vov4ick
Арктангенс умеет вычислять сам сопроцессор. Зачем применять разложение в ряд?
Потому что задание такое...
Могу ужасный код переписать по нормальному...
Код:
#include <stdio.h>
#include <math.h>
float abs(float x)
{
if(x > 0)
return x;
else
return -x;
}
float a0(float x) {return x;}
float b0(float z) {return z;}
float anext(float a, float x, int k)
{
return a * ((-1 * pow(x,2) * (2*k+1))/(2*k+3));
}
float bnext(float b, float z, int k)
{
return b * ((-1 * pow(z,2) * (2*k+1))/(2*k+3));
}
float y_telo(float x, float z, float acount, float bcount, float a, float b, float a_next, float b_next, float eps, int k)
{
if(abs(a_next + b_next) < eps)
{
printf("%f\n", (acount + bcount + a_next + b_next));
return (acount + bcount + a_next + b_next);
}
else
{
y_telo(x,z, acount+a_next, bcount+b_next, a_next,b_next,anext(a_next,x,k+1),bnext(b_next,z,k+1), eps, k+1);
}
}
float yfunc(float x, float z, float eps)
{
return y_telo(x,z,a0(x),b0(z),a0(x),b0(z),anext(a0(x),x,0),bnext(b0(z),z,0), eps, 0);
}
int main()
{
float x = 0.2; float z = 0.3; float eps = 0.00001;
printf("%f\n", yfunc(x,z,eps));
printf("%f\n", atan((x+z)/(1-x*z)));
return 0;
}
#include <math.h>
float abs(float x)
{
if(x > 0)
return x;
else
return -x;
}
float a0(float x) {return x;}
float b0(float z) {return z;}
float anext(float a, float x, int k)
{
return a * ((-1 * pow(x,2) * (2*k+1))/(2*k+3));
}
float bnext(float b, float z, int k)
{
return b * ((-1 * pow(z,2) * (2*k+1))/(2*k+3));
}
float y_telo(float x, float z, float acount, float bcount, float a, float b, float a_next, float b_next, float eps, int k)
{
if(abs(a_next + b_next) < eps)
{
printf("%f\n", (acount + bcount + a_next + b_next));
return (acount + bcount + a_next + b_next);
}
else
{
y_telo(x,z, acount+a_next, bcount+b_next, a_next,b_next,anext(a_next,x,k+1),bnext(b_next,z,k+1), eps, k+1);
}
}
float yfunc(float x, float z, float eps)
{
return y_telo(x,z,a0(x),b0(z),a0(x),b0(z),anext(a0(x),x,0),bnext(b0(z),z,0), eps, 0);
}
int main()
{
float x = 0.2; float z = 0.3; float eps = 0.00001;
printf("%f\n", yfunc(x,z,eps));
printf("%f\n", atan((x+z)/(1-x*z)));
return 0;
}
Действительно теряется при возврате... Но я переписал код на паскаль и скомпилил под Delphy 7. Там тоже при eps=0.1 выдает правильное значение, а при увеличении точности выдает -0,9. Даже не знаю в чем проблема...
Проблема скорее всего, в логике. Как я предположил, могут переполняться стеки или хз что. Я серьезно - отладчик тут полезная вещь. Посмотри, что у тебя лежит в стеке при возврате из y_telo в y_func и куда указывает esp.
З.Ы. забыл добавить - для отладки заюзай еще флаг -g3