Проблемы с циклом c++

Задача заключается в следующем:

Условие

Решить нужно обязательно с использованием постусловия. Написал следующее:

#include <iostream>
#include <stdio.h>
#include <iomanip>
#include <math.h>

using namespace std;



int main()
{
    setlocale(LC_ALL, "Russian");

    float a, b, c, x, xn, xk, dx, y, z;
    float const Pi = 3.1415;
    cout << "Введите a, b, c, xn, xk, dx \n";
    cin >> a >> b >> c >> xn >> xk >> dx;
    x = xn;
    do {
        if (x < 5)
            if (a * x + 1 >= 0) {
                z = cbrt(a * x + 1) + b;
            }
            else cout << "x= "<<x<<"Не выводится из-под корня"<<endl;

        if (x == 5) z = sin((b * x + 2) * Pi / 180);
        if (x > 5) z = b * cos((c * x + 3) * Pi / 180);

        y = (sqrt(z) + b * cos(z * Pi / 180)) / log(z * x);

        cout << "x=" <<setw(3)<<setprecision(2) << x <<" y="<<setw(3)<<setprecision(2)<<y<< endl;


        x = x + dx;

    } while (x >= xk);

    system("pause");
    return(0);
}

Есть следующие проблемы:

  1. Когда срабатывает условие "Не выводится из-под корня" программа прекращает свою работу, видимо из-за того, что невозможно вычисление y. Хотелось бы, чтобы в таблицу консоли просто фиксировалось, что при x= таком-то не выводится из-под корня.
  2. Проблема с сами циклом, когда на ввод даю положительный x, который гарантированно не вызовет проблем, программа делает только одну итерацию. Задаю xn = 0, а xk= 4, но итерация происходит только одна.
  3. Вроде бы, для возможности вычисления y необходимо добавить следующие условия:
if (sqrt(z) < 0) cout << "Не выводится из-под корня";
else if (z * x < 0) cout << "Невозможно вычислить логарифм";
else if (z * x == 0) cout << "Деление на ноль";
else y = (sqrt(z) + b * cos(z * Pi / 180)) / log(z * x);

Но это не точно... Однако как это прикрутить, когда и так ничего не работает, для меня загадка.

В общем и целом в результате в консоли должна быть небольшая табличка со значениями y при соответствующих значениях x.


Ответы (1 шт):

Автор решения: Stanislav Volodarskiy

Это пример вычислений в цикле с контролем ошибок и печатью сообщений. Вычисление разбиты на этапы. Каждый этап или вычисляет значение или оставляет описание ошибки в переменной error. Если переменная error уже установлена, все следующие этапы пропускаются:

#include <cmath>
#include <iomanip>
#include <iostream>

using namespace std;

int main()
{
    const double x1 = -2;
    const double x2 = 4;
    const double dx = 0.25;
    double x = x1;

    do {
        const char *error = nullptr;

        double ln_x; // ln(x)

        if (error == nullptr) {
            if (x > 0) {
                ln_x = log(x);
            } else {
                error = "логарифм отрицательного числа или нуля";
            }
        }

        double y; // y = 1 / ln(x)

        if (error == nullptr) {
            if (ln_x != 0) {
                y = 1. / ln_x;
            } else {
                error = "деление на ноль";
            }
        }

        cout << "x =" << fixed << setw(5) << setprecision(2) << x << "  ";
        if (error == nullptr) {
            cout << " y =" << setw(5) << setprecision(2) << y << '\n';
        } else {
            cout << ' ' << error << '\n';
        }

        x += dx;
    } while (x <= x2);
}
$ g++ tabulation.cpp 

$ ./a.out
x =-2.00   логарифм отрицательного числа или нуля
x =-1.75   логарифм отрицательного числа или нуля
x =-1.50   логарифм отрицательного числа или нуля
x =-1.25   логарифм отрицательного числа или нуля
x =-1.00   логарифм отрицательного числа или нуля
x =-0.75   логарифм отрицательного числа или нуля
x =-0.50   логарифм отрицательного числа или нуля
x =-0.25   логарифм отрицательного числа или нуля
x = 0.00   логарифм отрицательного числа или нуля
x = 0.25   y =-0.72
x = 0.50   y =-1.44
x = 0.75   y =-3.48
x = 1.00   деление на ноль
x = 1.25   y = 4.48
x = 1.50   y = 2.47
x = 1.75   y = 1.79
x = 2.00   y = 1.44
x = 2.25   y = 1.23
x = 2.50   y = 1.09
x = 2.75   y = 0.99
x = 3.00   y = 0.91
x = 3.25   y = 0.85
x = 3.50   y = 0.80
x = 3.75   y = 0.76
x = 4.00   y = 0.72
→ Ссылка