Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

g++ выдает nan

29K
14 октября 2008 года
Robotex
47 / / 02.10.2008
Задание было написать программу, в которой все операторы заменены функциями (чтобы потом легко перенести на лисп). Причем нельзя использовать циклы и степень... Нужно было вычислить выражение arctg((x+z)/(1-x*z))
Код:
#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++ -o lab1 lab1.c

Здесь x и z операнды, eps точность... При eps=0.1 вычисляет нормально, и значение очень похоже на значение встроенной функции, но при увеличении точности (eps=0.01 eps=0.001 и т.д.), вместо значения выдается nan. В чем проблема?
1.6K
14 октября 2008 года
Vov4ick
476 / / 01.02.2007
Арктангенс умеет вычислять сам сопроцессор. Зачем применять разложение в ряд?
245
14 октября 2008 года
~ArchimeD~
1.4K / / 24.07.2006
Разбираться в этом ужасном коде непонятного предназначения нет никакого желания.

Но если модифицировать две функции, которые работают последними непосредственно перед выводом результата:
Код:
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;
}

то результат будет такой:
Цитата:
$ ./lab1
result_0 = 0.488883
result_1 = nan
nan
0.488852


Т.е. видно, что возвращаемый параметр неожиданно ломается при передаче из одной функции в другую. Почему так - в душе не знаю, может где переполнения буферов или еще что. Дебаггер в руки - и отлаживайте. Где, на первый взгляд, кроется косяк, я показал.

14
14 октября 2008 года
Phodopus
3.3K / / 19.06.2008
Еще гляньте сюда
29K
14 октября 2008 года
Robotex
47 / / 02.10.2008
Цитата: 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;
}


Действительно теряется при возврате... Но я переписал код на паскаль и скомпилил под Delphy 7. Там тоже при eps=0.1 выдает правильное значение, а при увеличении точности выдает -0,9. Даже не знаю в чем проблема...
245
14 октября 2008 года
~ArchimeD~
1.4K / / 24.07.2006
код ужасен не только начертанием;), но и изобилием однобуквенных переменных. к тому же return вызов функции (куча параметров) тоже не очень смотрятся.
Проблема скорее всего, в логике. Как я предположил, могут переполняться стеки или хз что. Я серьезно - отладчик тут полезная вещь. Посмотри, что у тебя лежит в стеке при возврате из y_telo в y_func и куда указывает esp.

З.Ы. забыл добавить - для отладки заюзай еще флаг -g3
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог