Vanilla_Fury

2020 laba_1_3

Oct 5th, 2021
284
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.04 KB | None | 0 0
  1. #include <iostream>
  2. #include <cmath>
  3.  
  4. int main(int argc, const char * argv[]) {
  5.     bool isIncorrect;
  6.     float a;
  7.     float b;
  8.     float tochnost;
  9.     int kolvoCifr = 0; // Кол-во цифр после запятой
  10.     float middlePoint = 0;
  11.     // x и функции от x:
  12.     double xLeft;
  13.     double fXLeft;
  14.     double xRight;
  15.     double fXRight;
  16.    
  17.     double f1X; //производная для функции в определённой точке в прошлой итерации
  18.     float koren1 = 0;
  19.     float koren2 = 0;
  20.     int kolvoKorney;
  21.     bool fAIsPositive; //положительна ли функция при x=a
  22.     bool fBIsPositive; //положительна ли функция при x=b
  23.     bool answerIsNotReady = true;
  24.     int i;
  25.    
  26.     std::cout << "Задание: уточните корень уравнения e^x - 10x = 0 на отрезке [a, b] комбинированным методом хард и касательных\n";
  27.    
  28.     std::cout << "\nВведите число A (от -10 до 10): ";
  29.     do {
  30.         isIncorrect = false;
  31.         std::cin >> a;
  32.         if (abs(a) > 10) {
  33.             std::cout << "Число A должно быть от -10 до 10. Введите число из этого промежутка: ";
  34.             isIncorrect = true;
  35.         }
  36.     } while (isIncorrect);
  37.    
  38.     std::cout << "Введите число B (до 10): ";
  39.     do {
  40.         isIncorrect = false;
  41.         std::cin >> b;
  42.         if (b <= a) {
  43.             std::cout << "Число B должно быть больше A. Введите число больше " << a << ", но до 10: ";
  44.             isIncorrect = true;
  45.         }
  46.         if (!isIncorrect and b > 10) {
  47.             std::cout << "Число B не может быть больше 10. Пожалуйста, введите число до 10: ";
  48.             isIncorrect = true;
  49.         }
  50.     } while (isIncorrect);
  51.    
  52.     std::cout << "Введите требуемое количество цифр после запятой (от 1 до 6): ";
  53.     do {
  54.         isIncorrect = false;
  55.         std::cin >> kolvoCifr;
  56.         if (kolvoCifr < 1 or kolvoCifr > 6) {
  57.             std::cout << "Введите количество цифр после запятой от 1 до 6: ";
  58.             isIncorrect = true;
  59.         }
  60.     } while (isIncorrect);
  61.     tochnost = pow(10, -kolvoCifr);
  62.    
  63.     fAIsPositive = exp(a) - 10 * a > 0;
  64.     fBIsPositive = exp(b) - 10 * b > 0;
  65.    
  66. //  определение количества корней и, если корней два, нахождение икс между корнями, чтобы f(middlePoint) было с другим знаком, чем f(xLeft) и f(xRight).
  67.     if (fAIsPositive == fBIsPositive) {
  68.         if (fAIsPositive) {
  69.             kolvoKorney = 2;
  70.             // Нахождение такой точки xMiddle, что f(xMiddle) < 0, чтобы у нас была точка на графике функции с отличным от f(a) и f(b) знаком.
  71.             middlePoint = a;
  72.             do {
  73.                 middlePoint++;
  74.                 if (middlePoint > b - 1) {
  75.                     kolvoKorney = 0;
  76.                     answerIsNotReady = false;
  77.                 }
  78.             } while ((answerIsNotReady) and (exp(middlePoint) - 10 * middlePoint > 0));
  79.         } else {
  80.             kolvoKorney = 0;
  81.             answerIsNotReady = false;
  82.         }
  83.     } else {
  84.         kolvoKorney = 1;
  85.     }
  86.    
  87. //  нахождение корней, если они есть
  88.     if (answerIsNotReady) {
  89.         for (i = 0; i < kolvoKorney; i++) {
  90.             if (i == 0) {
  91.                 xLeft = a;
  92.                 if (kolvoKorney == 1) {
  93.                     xRight = b;
  94.                 } else {
  95.                     xRight = middlePoint;
  96.                 }
  97.             } else {
  98.                 xLeft = middlePoint;
  99.                 xRight = b;
  100.             }
  101.            
  102.             // У данной функции две ветви, направленные вверх.
  103.             // Чтобы не писать код отдельно для двух ветвей, можно просто мысленно поменять их местами.
  104.             // То есть, если мы находимся на левой ветви функции, то надо поменять местами все переменные ...Left и ...Right.
  105.             // Это произойдёт автоматически, если поменять местами 2 переменные: xRight и xLeft.
  106.             fXRight = exp(xRight) - 10 * xRight; // если fXRight < 0, то мы находимся на левой ветви функции.
  107.             if (fXRight < 0) {
  108.                 xRight += xLeft;  // эти 3 строки свапают 2 переменные
  109.                 xLeft = xRight - xLeft;
  110.                 xRight -= xLeft;
  111.             }
  112.             // xRight > xLeft ? - это опять же проверка на то, на какой мы ветви функции
  113.             while (xRight > xLeft ? xRight - xLeft > tochnost : xLeft - xRight > tochnost) {
  114.                 fXRight = exp(xRight) - 10 * xRight;
  115.                 fXLeft = exp(xLeft) - 10 * xLeft;
  116.                 f1X = ((exp(xRight + tochnost*tochnost) - 10 * (xRight + tochnost*tochnost)) - fXRight) / (tochnost*tochnost);
  117.                
  118.                 xLeft = (xRight * fXLeft - xLeft * fXRight)/ (fXLeft - fXRight);
  119.                 xRight = xRight - fXRight / f1X;
  120.             }
  121.             if (i == 0) {
  122.                 koren1 = (xRight + xLeft) / 2;
  123.             } else {
  124.                 koren2 = (xRight + xLeft) / 2;
  125.             }
  126.         }
  127.     }
  128.    
  129.     if (kolvoKorney < 1) {
  130.         std::cout << "Нет корней\n";
  131.     } else if (kolvoKorney > 1) {
  132.         printf("Корни: %.*f и %.*f \n", kolvoCifr, koren1, kolvoCifr, koren2);
  133.     } else {
  134.         printf("Корень: %.*f\n", kolvoCifr, koren1);
  135.     }
  136.     return 0;
  137. }
  138.  
Advertisement
Add Comment
Please, Sign In to add comment