Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Вылетает ошибка


Автор: Grr 17.8.2007, 12:08
Код

#include <iostream>
using namespace std;
/*Написать перегруженные шаблоны функций для нахождения корней линейного (a*x + b = 0) и 
квадратного (a*x2+b*x + c = 0) уравнений. Замечание: в функции передаются коэффициенты уравнений. */
float vichislenie (int a, int b, int c)
{
    float koren_1, koren_2, temp, d=0;
    temp = (b*b-4*a*c);
    for (; (d*d)<temp;)
    {
        d++;
    }
    d=0? koren_1 = (-b + d) / (2*a) : false;
    d>0? koren_2 = (-b - d) / (2*a) : false;
    return koren_1, koren_2;
}

void main()
{
    int a, b, c;
    cout<<"vvedite a, b, c\n";
    cin>>a; cin>>b; cin>>c; cout<<"\n\n";
    cout<<"korni uravneniya (a*x2+b*x + c = 0) : "<<vichislenie (a, b, c);
}

Пытаюсь написать для второго уравнения и вылетает ошибка на этапе выполнения. Помогите найти ошибку (-ки) пожалуйста.

Автор: bsa 17.8.2007, 12:26
вообще-то для вычисления корня можно использовать sqrt...

Автор: Fazil6 17.8.2007, 12:26
мда... ахереть... Жесть просто, а не функция...


Автор: _Michael 17.8.2007, 12:38
Код

.....
   return koren_1, koren_2;
}


Grr ты ж ведь два значения хочешь возвратить  smile 

Автор: Grr 17.8.2007, 12:39
Ребята, я недавно начал учить. Что такое sqrt не знаю. И что такого в функции? Я рад бы сделать её лучше, но не знаю как smile

Добавлено через 1 минуту и 13 секунд
_Michael, да, корней два, по идее должно возвращать оба, если "д" больше нуля

Автор: _Michael 17.8.2007, 12:44
Да корней у квадратного уравнения действительно может быть два, но функция то в С возвращает только одно значение. Т-е таким макаром у тебя никак не выйдет. Тебе или надо выводить твои корни в консоль прямо в функции vichislenie  или ж передавать ей еще два дополнительных параметра - адреса переменных в которые ты будеш записывать полученные корни.

Автор: MAKCim 17.8.2007, 12:52
Код

#define ANSWER_NO_SOLUTION      (1 << 0)
#define ANSWER_ONE_SOLUTION    (1 << 1)
#define ANSWER_TWO_SOLUTION    (1 << 2) 

struct answer {
    union {
        char array[2 * sizeof(double)];
        double x1, x2;
        double x;
    }
    int flags;
};

struct answer calculate(int a, int b, int c) {
    struct answer answer = {0};
    int d = b * b - 4 * a * c;
    if (d < 0) {
        answer.flags |= ANSWER_NO_SOLUTION;
        return answer;
    } else if (d == 0) {
        answer.flags |= ANSWER_ONE_SOLUTION;
        answer.x = (double) -b / (2 * a);
    } else {
        answer.flags |= ANSWER_TWO_SOLUTION;
        answer.x1 = (double) (-b + sqrt((double) d)) / (2 * a);
        answer.x2 = (double) (-b - sqrt((double) d)) / (2 * a);
    }
    return answer;
}

Автор: Grr 17.8.2007, 12:53
_Michael, до обращений к памяти я ещё не дошёл) буду выводить в функции значит, спасибо smile

Автор: _Michael 17.8.2007, 12:58
Grr,   smile Не за что.
MAKCim, ето даже больше чем требовалось  smile 

Автор: bsa 17.8.2007, 12:58
Цитата(Grr @ 17.8.2007,  12:39)
Ребята, я недавно начал учить. Что такое sqrt не знаю. И что такого в функции? Я рад бы сделать её лучше, но не знаю как smile

Цитата(man 3 sqrt)
ИМЯ
       sqrt - вычисление квадратного корня

СИНТАКСИС
       #include <math.h>

       double sqrt(double x);

ОПИСАНИЕ
       Функция  sqrt()  возвращает неотрицательный квадратный корень аргумента
       x.  Функция завершается с ошибкой и присваивает errno значение  EDOM  в
       том случае, если x - отрицательное число.

КОДЫ ОШИБОК
       EDOM   x - отрицательное число.

СООТВЕТСТВИЕ СТАНДАРТАМ
       SVID 3, POSIX, BSD 4.3, ISO 9899

СМОТРИ ТАКЖЕ
       hypot(3)

Автор: hkklr 17.8.2007, 13:44
А зачем здесь вообще отдельная функция? Мне кажется(хотя я могу ошибаться), что здесь она только мешает. Почему бы не написать так:
Код

#include<iostream>
#include<cmath>
using namespace std;
void main()
{
   double a,b,c;
   cin>>a,b,c;
   if(a==0)
   {
       if(b==0)
       {
           if(c==0)
          {
              cout<<"Бесконечное число решений";
          }
          else
          {
              cout<<"Решений нет";
          }
       } 
       else
       {
           cout<<-c/b;
       }  
   }
    else
    {
        float d=b*b-4*a*c;
        if(d<0)
       {
           cout<<"Комплексные корни";
       }
       if(d==0)
       {
           cout<<-b/(2*a);
       }
       if(d>0)
      {
           cout<<(-b-sqrt(d))/(2*a)<<','<<(-b+sqrt(d))/(2*a);
      }
    }
}

Много, но зато надеюсь понятно smile

Добавлено через 48 секунд
В моём коде возможны ошибки - я не проверял.

Автор: Rockie 17.8.2007, 14:05
Grr, глянь http://algolist.manual.ru/maths/findroot/quadrantic.php. И http://www.google.md/search?hl=ru&q=%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D0%B5+%D0%BA%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BD%D0%BE%D0%B3%D0%BE+%D1%83%D1%80%D0%B0%D0%B2%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F+C%2B%2B&btnG=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA&lr=


Автор: Grr 17.8.2007, 14:33
bsa, спасибо, буду использовать библиотеку теперь. Только учительница может ругаться, что вперёд забежал)))

hkklr, это домашнее задание, где чётко нужно придержаться условия. Получу двойку, если найду оптимальнее, чем нужно) а хуже всего, что в перегруженных функциях нельзя использовать иф и свитч, с которыми эта и следующие д/з намного легче было бы выполнить. 
Rockie, тоже благодарю, только гуглю я с самого начала юзал smile))

Автор: hkklr 18.8.2007, 06:48
Grr пишет:
Цитата

hkklr, это домашнее задание, где чётко нужно придержаться условия. Получу двойку, если найду оптимальнее, чем нужно) а хуже всего, что в перегруженных функциях нельзя использовать иф и свитч, с которыми эта и следующие д/з намного легче было бы выполнить. 

Да, я тебя понимаю... Что это за система обучения, где ставят двойки за оптимальное решение...  Все забывают про разумную достаточность. А почему нельзя использовать if и switch в перегруженных функциях? Это что, условие домашнего задания что ли?

Автор: bsa 18.8.2007, 07:20
ну вместо if можно использовать operator?: Вместо свича тоже.

Автор: hkklr 18.8.2007, 07:28
Но это не всегда удобно.

Автор: Grr 18.8.2007, 08:28
hkklr, получится ошибка на этапе копмиляции)) 
bsa, да, им и делаю smile
через 2 часа выложу 3 задания, которые отказываются получаться корректно)

Автор: Grr 18.8.2007, 10:08
Код

#include <iostream>
using namespace std;
/*Написать функцию, которая принимает в качестве параметров вещественное число и количество знаков после 
десятичной точки, которые должны остаться. Задачей функции является округление вышеуказанного вещественного 
числа с заданной точностью. */
float vichislenie (float ch, int vish)
{
    int sum = 0, sum_1 = 0; float drob, drob_1, itog;
    for (int i=ch; i>1; i--)
        sum++;
    drob=ch-sum; (int)ch;
    for (int i = 1; i < vish; i++)
        sum_1++;
    drob_1 = drob * sum_1; (int)drob_1;
    itog = (float)drob_1/sum_1;
    return itog+ch;
}
void main()
{
    float chislo;
    int tochnost;
    cout<<"Vvedite chislo dlya okrugleniya \n"; cin>>chislo;
    cout<<"\nZadayte kol-vo znakov kotorie dolgni ostatsya "; cin>>tochnost;
    cout<<"\n\n"<<vichislenie(chislo, tochnost)<<"\n\n";
}

беру число 12.1212, провожу округление до двух знаков, но получается 13.2424. Почему, не понимаю)
Код

#include <iostream>
#include <time.h>
#include <stdlib.h>
/*Написать шаблон функции для поиска среднего арифметического значений массива.*/
long Sred_arif (int n, int chisla[])
{
    double rezultat=0;
    for (int i=0; i<n; i++)
    {
        chisla[i]<n ? rezultat+=chisla[i] : false;
    }
    return rezultat/n;
}

/*тело программы для проверки*/
using namespace std;
void main()
{
    int massiv[15];
    srand(time(NULL));
    for (int i=0; i<15; i++)
        massiv[i] = rand()%10;
    for (int i=0; i<15; i++)
        cout<<massiv[i]<<", ";
    cout<<"\n\nSrednee arifmeticheskoe massiva : "<<Sred_arif(15, massiv)<<"\n";
}

как ни странно, но работает корректно smile
Код

#include <iostream>
#include <math.h>
using namespace std;
/*Написать перегруженные шаблоны функций для нахождения корней линейного (a*x + b = 0) и 
квадратного (a*x2+b*x + c = 0) уравнений. Замечание: в функции передаются коэффициенты уравнений. */
float vichislenie (int a, int b, int c)
{
    float x_1, x_2;
    int temp;
    double d;
    d=(b*2-4*a*c);
    a!=0 ? x_1=(-b+sqrt((double)d))/(2*a) : false;
    a!=0 ? x_2=(-b-sqrt((double)d))/(2*a) : false;
    d>=0 ? temp = 1 : false;
    d>0 ? temp = 2 : false;
    cout<<"uravnenie a*x2+b*x+c=0 imeet ";
    temp == 2 ? cout<<"2 kornya"<<x_1<<"\t"<<x_2<<"\n\n" : cout<<"1 koren"<<x_1<<"\n\n";
    return 0;
}

void main()
{
    int a, b, c;
    cout<<"vvedite a, b, c\n";
    cin>>a; cin>>b; cin>>c; cout<<"\n\n";
    cout<<"korni uravneniya (a*x2+b*x + c = 0) : "<<vichislenie (a, b, c);
}

попробовал через скрт, но всё равно ошибка :(

Автор: MAKCim 18.8.2007, 10:44
Grr
первая задача
Код

double convert(double number, int precision) {
    double result = (double)((int)number), multiply = 10.0;
    number -= result;
    while (precision--) {
        number *= 10.0;
        result += (int)number / multiply;
        number -= (int)number;
        multiply *= 10.0;
    }
    return result;
}


Добавлено через 12 минут и 1 секунду
квадратное уравнение
Код

int calculate(int a, int b, int c) {
    int d = b * b - 4 * a * c;
    d == 0 ? printf("one solution: x = %F\n", (double) - b / (2 * a)) :
    d < 0 ? printf("no solutions\n") :
        printf("two solutions: x1 = %F, x2 = %F\n",
        ((double) - b + sqrt(d)) / (2 * a),
        ((double) - b - sqrt(d)) / (2 * a));
    return 0;
}

Автор: bsa 18.8.2007, 11:01
Вообще-то шаблонная функция - это несколько не то, что ты написал.
1. Функция округления:
Код
#include <cmath>
float my_round(float value, unsigned dig)
{
     const float pow_10 = static_cast<float>( pow(10, dig) );
/*pow - это стандартная функция возведения в степень
   если ее нельзя использовать, то можешь воспользоваться следующим кодом вместо этой строчки:
     float pow_10 = 1;
     for(unsigned i = 0; i < dig; ++i)
          pow_10 *= 10;
*/
     return static_cast<unsigned long>( value * pow_10  + 0.5) / pow_10;
}

2. Шаблон функции подсчета среднего арифметического:
Код
template<typename T>
T measure(const T *array, unsigned count)
{
    T sum = 0;
    for(unsigned i = 0; i < count; ++i, ++array)
       sum += *array;
    return sum / count;
}

3. Шаблон функции для нахождения корней квадратного уравнения:
Код
template<typename T>
struct SquareEquationResult
{
     T val1;
     T val2;
     SquareEquationResult(const T &v1, const T &v2) : val1(v1), val2(v2) {}
};
template <typename T>
SquareEquationResult<T> calcEquation(const T &a, const T &b, const T &c)
{
    const T d = b * b - 4 * a * c; //вообще-то надо считать не 2b-4ac, как у тебя, а b^2 - 4ac
    if (d < 0)
       throw("Invalid values");
    const T sqd = static_cast<T>( sqrt( static_cast<double>(d) ) );
    return SquareEquationResult<T>( (-b + sqd) / (2*a), (-b - sqd) / (2*a) );
}

Автор: Grr 18.8.2007, 11:37
Офигеть, я тоже хочу всё знать, что и вы))
сейчас буду разбираться, половина в алгоритмах не понятно)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)