Реализация функции вычисления корня на С++

      Комментарии к записи Реализация функции вычисления корня на С++ отключены

Главная Форумы Программирование Программирование на С++ Решение задач на С++ Реализация функции вычисления корня на С++

В этой теме 0 ответов, 1 участник, последнее обновление  Васильев Владимир Сергеевич 3 мес., 2 нед. назад.

  • Автор
    Сообщения
  • #3842

    Я приведу тут две реализации алгоритмов вычисления корня. Более подробно алгоритмы рассмотрены в статье «Алгоритмы вычисления корня«.

    Разработка модульных тестов

    Перед написанием кода, я пишу модульные тесты. Если вы не пишите и считаете, что это лишнее — пропустите раздел. Если вы не знакомы с unit-тестами, но хотите узнать что это такое — советую прочитать статьи:

    Итак, я добавил в класс sqrt_nsp заглушки для двух функций вычисления корня (разными алгоритмами) — sqrt_nsp::rect_sqrt и sqrt_nsp::dichotomy_sqrt. Класс я использовал для задания пространства имен:

    class sqrt_nsp {
    public:
      struct SqrtFromNegqtive {};
      static constexpr double Eps = 0.00001;
    
      static double rect_sqrt(double value) {
        return 0;
      }
    
      static double dichotomy_sqrt(double value) {
        return 0;
      }
    };

    Теперь можно написать тесты для них:

    #include <boost/test/unit_test.hpp>
    
    BOOST_AUTO_TEST_SUITE(RectSqrtTest)
    BOOST_AUTO_TEST_CASE(double_sqrt625) {
      double result = -1;
      BOOST_CHECK_NO_THROW(result = sqrt_nsp::rect_sqrt(625));
      BOOST_REQUIRE_CLOSE(result*result, 625, sqrt_nsp::Eps*100);
    }
    
    BOOST_AUTO_TEST_CASE(int_sqrt26) {
      double result = -1;
      BOOST_CHECK_NO_THROW(result = sqrt_nsp::rect_sqrt(26));
      BOOST_REQUIRE_CLOSE(result*result, 26, sqrt_nsp::Eps*100);
    }
    BOOST_AUTO_TEST_SUITE_END()
    
    BOOST_AUTO_TEST_SUITE(DichotomySqrtTest)
    BOOST_AUTO_TEST_CASE(double_sqrt625) {
      double result = -1;
      BOOST_CHECK_NO_THROW(result = sqrt_nsp::dichotomy_sqrt(625));
      BOOST_REQUIRE_CLOSE(result*result, 625, sqrt_nsp::Eps*100);
    }
    
    BOOST_AUTO_TEST_CASE(int_sqrt26) {
      double result = -1;
      BOOST_CHECK_NO_THROW(result = sqrt_nsp::dichotomy_sqrt(26));
      BOOST_REQUIRE_CLOSE(result*result, 26, sqrt_nsp::Eps*100);
    }
    BOOST_AUTO_TEST_SUITE_END()

    Теперь мы можем запустить наши тесты и убедиться что они работают (код проваливается):

    Реализация алгоритмов вычисления корня

    Алгоритмы реализуются достаточно просто, по приведенным блок-схемам:

      static double rect_sqrt(double value) {
        if (value < 0)
          throw SqrtFromNegqtive();
        double height = 1, width = value;
        while(std::abs(width - height) > Eps) {
          height = (height+width) / 2;
          width = value / height;
        }
        return width;
      }

    static double dichotomy_sqrt(double value) {
        if (value < 0)
          throw SqrtFromNegqtive();
        double left = 1, right = value, middle, approx;
        do {
          middle = left + (right-left)/2;
          approx = middle*middle;
          if (approx > value)
            right = middle;
          else
            left = middle;
        } while(std::abs(approx - value) > Eps);
        return middle;
      }

    Теперь после запуска тестов, увидим что все они проходят успешно:

Для ответа в этой теме необходимо авторизоваться.