Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   Решение квадратных уравнений на С++ (http://forum.oszone.net/showthread.php?t=131169)

ShadowMas 06-02-2009 14:22 1031282

Решение квадратных уравнений на С++
 
Люди подскажите плиз, пробую написать тестовую програмку на С++ , чего то не правельно считает "sqrt" от числа , тип переменной назначаю с плавающей тачкой(навсякмй случа).
Вот пример

для проверки можно взять такое квадратное уравнение

y = 4x^2 + 3x - 5

Програмка

Код:

#include <iostream.h>
#include <conio.h>
#include <math.h>
 main()
{
float b,a,x,c,D,y,z;
D=0;

cout <<"Davayte reshim kvadratnoe uravnenie sleduyushego vida y=ax**2+b*x+c "<<endl;
cout <<"Dla etogo vnesite znacheniya v posledovatelnosti a,b,c"<<endl;getch();clrscr();
cout <<"a="<<endl;
cin>>a;
if (a==0)
{
cout <<"Esli znachenie a=0 - Net resheniy"<<endl;getch();clrscr();
}
if (a!=0)
{
cout <<"b="<<endl;
cin>>b;
cout <<"c="<<endl;
cin>>c;
D=b*b-4*a*c;
cout <<"Diskremenant="<<D<<endl;getch();clrscr();
}
if (D<0)
{
cout <<"Net resheniy"<<endl;getch();clrscr();
}
if (D==0)
{
x=b*b/2*a;
cout <<"naydeno odno vozmoznoe reshenie x="<<x<<endl;getch();clrscr();
}
if (D>0)
{
y=b*b+sqrt(D)/2*a;
z=b*b-sqrt(D)/2*a;

cout <<"naydeni znacheniya x1 i x2"<<endl;
cout <<"x1="<<y<<" x2="<<z<<endl;getch();clrscr();
 }
 }

Вопрос то сам как раз в выделеной части, почему то неправельно считает?
Может структура записи формулы не правельная?

Drongo 06-02-2009 15:07 1031322

ShadowMas, Гляньте в комментарий 2. И ещё я бы
Сделал так

Код:

...
  cout <<"a = ";
  cin>>a;
  while(a == 0){ // Вместо 'if' - разовой, прикрутил бы циклическую проверку
    cout <<"Esli znachenie a = 0 - Net resheniy"<<endl;
    clrscr();
    cout <<"a = ";
    cin>>a;
  }
...

Тогда отпадёт необходимость в следующем условии:
Код:

...
//  if(a != 0){
    cout <<"b = ";
    cin>>b;
    cout <<"c = ";
    cin>>c;
    D = b * b + 4 * a * c;
    cout <<"Diskriminant = "<<D<<endl;
    // getch();
    // clrscr();
  // }
...

Картина в целом
Код:

...
  cout <<"a = ";
  cin>>a;
  while(a == 0){
    cout <<"Esli znachenie a = 0 - Net resheniy"<<endl;
    clrscr();
    cout <<"a = ";
    cin>>a;
  }
  cout <<"b = ";
  cin>>b;
  cout <<"c = ";
  cin>>c;
  D = b * b + 4 * a * c;
  cout <<"Diskriminant = "<<D<<endl;
...

Ко всему ещё стоит добавить 'else', тогда не будет ненужной проверки всех условий
Код:

...
  if(D < 0){
    // Код 
  }
  else if(D == 0){
    // Код
  }
  else if(D > 0){
    // Код
...


lxa85 06-02-2009 16:40 1031424

Цитата:

Цитата ShadowMas
y=b*b+sqrt(D)/2*a;
z=b*b-sqrt(D)/2*a; »

Элементарная ошибка в последовательности выполнения операторов с числами.
Сначала выполняется умножения/деления, потом сложения/вычитания.
сначала все, что в скобках, потом все что вне скобок.
У нас числитель равен b*b-sqrt(D)
знаменатель 2*a
т.е. ( b*b+sqrt(D) ) / ( 2*a )
Тем самым мы сделаем нужный нам, правильный, порядок выполнения операций.

ShadowMas 06-02-2009 16:41 1031426

Спасибо огромное за совет!

Drongo 06-02-2009 17:16 1031452

Цитата:

Цитата ShadowMas
А если целое " int " то результат вобще левый? »

Не левый, а приведённый к типу 'int', без дробной части:
х1 = 0
х2 = -1

Призабыл уже как вычисляется это уравнение... Погуглил, нашёл, вот только не пойму
У тебя

Код:

...
  x = b * b / 2 * a;
...

Получается, что неправильно?
Цитата:

при D = 0 корень один:
x = –b/2a.
Код:

...
  x = -b / (2 * a);
...

И ещё один момент, авторский вариант
Код:

...
(b * b + sqrt(D)) / (2 * a);
...

Почему не так?
Код:

...
(-b + sqrt(D)) / (2 * a);
(-b - sqrt(D)) / (2 * a);
...


ShadowMas 06-02-2009 17:29 1031464

Да спасибо огромное я уже разобрался,я там просто с арихметикой на тупил решил что корень от 89 сто пудово должен быть 9 :) и с это вот увереностью тут вам и морочу голову
:)
Ещё раз огромное спасибо за вашу помощь и терпение!

Drongo 06-02-2009 17:44 1031474

ShadowMas, Значит твой код считает правильно? :)

Admiral 06-02-2009 18:43 1031518

ShadowMas, это
Цитата:

Цитата Drongo
...
if(D < 0){
// Код
} »

оставить с заделом на будущие, ибо в случаи изучении высшей математики станет известно, что при дискриминанте меньшем нуля корни тоже есть, но они лежат в комплексном множестве.

lxa85 06-02-2009 20:49 1031621

Admiral, Drongo, Мо-лод-цы! :clapping:

Drongo 06-02-2009 21:24 1031658

Цитата:

Цитата lxa85
Admiral, Drongo, Мо-лод-цы! »

А сам чего не с нами? Тоже ж помогал, значит и ты - мо-ло-дец! :up

Admiral 07-02-2009 00:37 1031780

А что я? Это вы ребята. Я лишь посоветовал не забивать голову фразой что корней при дискриминанте меньше нуля не существует, а в программе предусмотреть на будущее этот вариант.
Я когда-то на VB6 сделал сабжевую прогу, и выводил сообщение о том что корней нет при дискриминанте меньше нуля.

Drongo 07-02-2009 18:33 1032178

Я вот отсюда оттолкнулся, Как вычислить дискриминант квадратного уравнения? Там и формула есть, но вот не могу найти ссылку, где тоже говорилось что-то о высшей математике касательно квадратных уравнений.

Admiral 07-02-2009 18:56 1032201

Drongo есть эксперт в этой области, портал http://exponenta.ru/
на нём и ссылка http://model.exponenta.ru/bt/bt_001141.html
Цитата:

Таким образом, при решении квадратного уравнения может оказаться, что решения его среди действительных чисел от -∞ до +∞ не имеется. Можно было бы воспринять это как данность и считать, что операция вычисления корней может выводить решение за пределы существующих чисел. Но математики пошли по другому пути, добиваясь того, чтобы каждое квадратное уравнение имело корни. Они обобщили понятие числа, добавив к числам новые математические объекты, которые получаются из обычных чисел домножением их на корень квадратный из -1.
Так что автор может теперь апгредить прогу.

Drongo 07-02-2009 20:07 1032271

Хорошие ссылки.
Цитата:

Цитата Admiral
Так что автор может теперь апгредить прогу. »

Да в принципе я думаю, при таком варианте
Код:

...
if(D < 0){
// Код
}
...

Вместо сообщения "корней нет", достаточно вывести уведомление
Цитата:

Цитата Admiral
при дискриминанте меньшем нуля корни тоже есть, но они лежат в комплексном множестве. »


Admiral 07-02-2009 20:21 1032285

А когда знаний и опыта хватать будет считать комплексные, как математические программы.
complex.h в помощь.

ShadowMas 21-02-2009 21:44 1045161

Огромное спачибо всем участникам темки очень помогли,узнал много нового!

Ещё раз ОГРОМНОЕ СПАСИБО!!!

Drongo 22-02-2009 14:05 1045552

Цитата:

Цитата ShadowMas
y = 4x^2 + 3x - 5 »

В общем, немножко проконсультировался со своей знакомой педагогом-математики, и получилось следующее, одним словом я запутался, итак дано:
Уравнение и размышления вслух:

Код:

4х^2 + 3х – 5 = 0
Оно же в общем виде
Код:

ах^2 + bх – с = 0.
Дискриминант:
Код:

D =  b^2 – 4ac
корни:
Код:

х1 = (-b + sqrt(D)) / 2a
x2 = (-b - sqrt(D)) / 2a

Ключевой момент 4х^2 + 3х – 5 = 0
Если человек учитывает такое число –5, то программе, в формуле нет этого, там задаётся только положительное число, в смысле в переменной отрицательное храниться может, но хранится в этом случае, неправильное, положительное! Тоесть в случае
Код:

...
  cin>>c;
...

нужно явно указывать отрицательное!
Цитата:

Цитата ShadowMas
Код:

...
  cout<<"c = "<<endl;
  cin>>c;
  D = (b * b) - (4 * a * c);
...

»

и получается следующее
Код:

D = (3 * 3) - (4 * 4 * 5) = 71, Корней нет!
вместо
Код:

D = (3 * 3) – (4 * 4 * (-5)) = 89,  Корень = 9,43

Х1 = (-3 + 9,43) / 8 = 0,8
Х2 = (-3 – 9,43) / 8 = -1,55

Так что нужно ещё учесть знаковые числа. Либо использовать следующую конструкцию, принудительно ставить знак минус
Код:

...
  D = (b * b) - (4 * a * (c));
...



Или я ошибся? :dont-know

Admiral 23-02-2009 09:58 1046207

Drongo,
Цитата:

Цитата Drongo
в переменной отрицательное храниться может, но хранится в этом случае, неправильное, положительное! »

правильно, в этом случаи если
Цитата:

Цитата ShadowMas
float b,a,x,c,D,y,z; »

с & другие переменные могут принимать лишь положительные значения в вещественном диапазоне зависящем от платформы и от компилятора (от заданного в float.h/cfloat).
Нужно указывать signed float.
В аналогичном сабже так и поступили. У них float только дискриминант. :happy:

Drongo 23-02-2009 11:41 1046289

Цитата:

Цитата Admiral
В аналогичном сабже так и поступили »

Я видел это решение, когда искал первый раз, грамотно написано, но у меня не компилировалось, выдаёт ошибку:
[C++ Ошибка] Unit1.cpp(25): E2176 Too many types in declaration
Код:

...
  mes("Введите квадратное уравнение (типа 2x^2+3x-6=0): ");
  string input, a, b, c;
  signed float fA=1, fB=1, fC=1; // Ошибка на этой строке
  getline(cin,input);
...

И что нужно сделать, я не знаю.

Alan85 23-02-2009 16:26 1046512

Drongo, помоему слово signed лишнее :

Код:

float fA=1, fB=1, fC=1;

Drongo 23-02-2009 16:57 1046534

Цитата:

Цитата Alan85
помоему слово signed лишнее »

Цитата:

Цитата Admiral
Нужно указывать signed float »

Мнения разделились? :dont-know


Без signed ошибки нет, но появляется ошибка:
Цитата:

[C++ Ошибка] PolinomTwoStepeny1.cpp(75): E2203 Goto bypasses initialization of a local variable
Попробовал, прикинул, если все
Код:

goto end;
заменить на
Код:

break;
логично? Логично. Тогда программа компилируется и работает. :yes:
Но всё же два вопроса:
1. Эта замена в данном случае мне кажется равноценной, верно?
2. Чего всё же надо было при ошибке goto? (Этот вопрос я ещё сегодня вечером попробую решить, возьму книгу, сверюсь, уточню)

Alan85 23-02-2009 17:37 1046570

1. Нет. Так как автор предлагал этим трюком закончить выполнение программы окончательно, а break лишь выводит из текущего блока и все идет далее по тексту. Лучше уж тогда exit.
2. Потому что между goto end и самим есть есть два объявления переменных (выходит что они могут быть не объявлены - как будто вырезается часть исходника между goto end и самой меткой, но не в момент компиляции а в реал тайм. Что приведет к ошибки. Исправляется переносом объявления переменных и их инициализации до первого использования goto end. В данном случаи это переменные int i и float D.

Drongo 23-02-2009 17:59 1046581

Цитата:

Цитата Alan85
1. Нет. Так как автор предлагал этим трюком закончить выполнение программы окончательно, а break лишь выводит из текущего блока и все идет далее по тексту. Лучше уж тогда exit. »

Спасибо за поправку. Неучёл этого, думал будет выход в конец программы. :up
Цитата:

Цитата Alan85
2. Потому что между goto end и самим есть есть два объявления переменных (выходит что они могут быть не объявлены - как будто вырезается часть исходника между goto end и самой меткой, но не в момент компиляции а в реал тайм. Что приведет к ошибки. Исправляется переносом объявления переменных и их инициализации до первого использования goto end. В данном случаи это переменные int i и float D. »

Спасибо!!! :yahoo: Получилось. :up Сместил объявления вверх:
Код:

...
int main()
{
  int i;
  float D = 0;
...


lxa85 23-02-2009 23:12 1046846

Цитата:

Цитата Drongo
Код:
4х^2 + 3х – 5 = 0
Оно же в общем виде
Код:
ах^2 + bх с = 0. »

Ошибка в минусе. Общий случай неизменный
ax^2 + bx + c = 0
При вводе в программу, мы указываем с = -5. предварительно указав правильный тип переменной.
Нашел здесь
Цитата:

float f; double d; // Single or double precision real (never unsigned)
Т.е. тип float он в любом случае знаковый.
В справке NetBeans ничего про unsignet float не нашел.

Admiral 24-02-2009 00:47 1046928

Drongo, алгоритм ответа был таков, я помнил что для типов существует такая приставка как signed, но не был уверен доступна ли она для float. Через поиск провёл данную комбинацию (вместо того что б проверить компилятором) и вышел на ту тему. Как оказал безграмотное. Насчёт signed float я ошибся - ибо signed/unsigned только для char/int Is unsigned float legal?
Компилятор говорит что много типов так как, по его мнению объявляют signed int и float.
Что делать, оставить всё как есть. Я проверил, на практике никакого минуса выставлять не требуется. Минус сохраняется в переменной, скомпилив
данный код
Код:

#include <stdio.h>

int main(int argc, char* argv[])
{
        float b,a,c,D;

        printf("a=");
        scanf("%f",&a);

        printf("b=");
        scanf("%f",&b);

        printf("c=");
        scanf("%f",&c);

        D = (b * b) - (4 * a * c);
        printf("Answer %f",D);

        return 0;
}


И запустив на выполнение с предложенными параметрами
получим корректный расчёт
Цитата:

a=3
b=4
c=-5
Answer 76.000000


Если интересно то минус можно задать так c=-c.
Мнение не разделись, а были предложены варианты.
Alan85 не просто лишние, а кардинально не к месту и недопустимо его с float использовать.

Кроме exit можно использовать return 0 если конечно не void main/WinMain/etc то есть если главная функция программы не без типовая.

lxa85 видимо и в Java (или NetBeans может быть IDE и для С\С++?) решили не вносить путаницу по данному вопросу.

lxa85 24-02-2009 09:21 1047096

Цитата:

Цитата Admiral
или NetBeans может быть IDE и для С\С++? »

NetBeans - это просто среда разработки. У нее есть модули и для C\C++ как одного из основных языков программирования. Есть и для Java, Python, Ruby, MySQL, Pascal и пр.
Но сама среда да, написана на Java.

XEN_STRANGER 24-03-2009 11:08 1073020

Вот мой вариант проги:


Код:

int x2yravn ()
{
        double a, b, c, x1, x2;
        double error;
        unsigned short int back;
        cout << "Ввод уравнения: " << endl;
        cout << endl << "(a=) ";
        cin >> a;
        cout << "(b=) ";
        cin >> b;
        cout << "(c=) ";
        cin >> c;


    error = GetX2yravn (a, b, c, &x1, &x2);
        if (!error)
        {
                backer ();
        }

    else
        {
                cout << endl << "Ошибка! а=0, уравнение не квадратное" << endl;
        }
        char response;
        cin >> response;
        return 0;

}


// Функция нахождения корней

double GetX2yravn (double a, double b, double c, double *px1, double *px2)
{
        double value = 0;
        if (a == 0)
                value = 1;
        else
        {
                double D;
            D = b*b - 4*a*c;
                cout << endl << "Дискриминант равен " << D << endl;
                if (D < 0)
                {
                        cout << "=====РЕЗУЛЬТАТ============================================";
                        cout << endl << "Корней не найдено, дискриминант меньше ноля" << endl;
                        cout << "==========================================================" << endl;
                }
                if (D == 0)
                {
                        *px1 = -b / (2*a);
                        cout << "=====РЕЗУЛЬТАТ============================================";
                        cout << endl << "Найден один корень, x = " << *px1 << endl;
                        cout << "==========================================================" << endl;
                }
                if (D > 0)
                {
                        *px1 = (-b + sqrt(D)) / (2*a);
                        *px2 = (-b - sqrt(D)) / (2*a);
                        cout << "=====РЕЗУЛЬТАТ============================================";
                        cout << endl << "Найдено два корня, x1 = " << *px1 << ", x2 = " << *px2 << endl;
                        cout << "==========================================================" << endl;
                }
                value = 0;
        }
        return value;



//----Функция возврата------------------------------------------------------------------------------

int backer ()
{
        unsigned short int back;
        cout << endl << endl<< "Вернуться в главное меню? (Да - 1, Нет - 2)";
        cin >> back;
        cout << endl << endl;
        switch (back)
        {
        case 1:
                {
                  cout << "-----END---------------------------------------------------------";
                  cout << endl << endl << endl << endl << endl << endl << endl;
                  return int x2yravn();
                }
                break;

        case 2:
                {
                                  cout << endl << "Можете закрыть программу.";
                      char response;
                                  cin >> response;
                  return 0;
                }
            break;
        default:
                {
                          cout << endl << "<Ошибка! Введите коректное число!>" << endl << endl;
                  return backer ();
                }
        }
}


gusenkovs 19-05-2011 19:55 1679212

Программа решения квадратных уравнений

Drongo 19-05-2011 21:46 1679259

gusenkovs, где описание программы? Что она делает и т.д.?

gusenkovs 20-05-2011 17:23 1679715

Программа решает уравнния вида ax^2+bx+c
Код:

#include <math.h>
#include <iostream>
#include <fstream>
using namespace std;
double kkui_discremenant (double a,double b,double c)
{double discreminant=pow(b,2)-4*a*c;
 return discreminant;
}
double x1v (double a,double b,double c)
{double discreminant=kkui_discremenant(a,b,c);
if (discreminant>=0)
{double x1=(sqrt(discreminant)-b)/(2*a);
return x1;}return 0;}

double x2v (double a,double b,double c)
{double discreminant=kkui_discremenant(a,b,c);
if (discreminant>=0)
{double x2=(-sqrt(discreminant)-b)/(2*a);
return x2;};return 0;}
void log(double a,double b,double c,double discremenant,double x1,double x2)
{
        ofstream outfile("C:\\kku.log",ios::app);
    outfile<<a<<"x^2+"<<b<<"x+"<<c<<endl<<"дискрименант"<<discremenant<<endl<<"x1="<<x1<<endl<<"x2="<<x2<<endl<<"Теорема Виетта"<<"(x-("<<x1<<")(x-("<<x2<<"))"<<endl;
    outfile.close();}



Время: 12:31.

Время: 12:31.
© OSzone.net 2001-