На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
  
> Библиотека для работы с длинными числами (BigInteger)
    Всех приветствую!

    Ищу библиотеку для работы с длинными целыми (длинные вещественные и комплексные числа особо не интересуют, но если будет в комплекте, будет только плюсом).
    Такие большие библиотеки, как GMP (особенно которые тащат за собой DLL) не нужны, надо что-то попроще, но быстрое и функциональное.

    Есть отличная (очень быстрая и функциональная) библиотека для Delphi: http://www.rvelthuis.de/programs/bigintegers.html
    Хотелось бы найти что-то такое же для C++ (скажем, одну или несколько связок из файлов h+cpp).

    Нашёл вот это: https://sourceforge.net/projects/cpp-bigint/
    Не такая шустрая, конечно, вещь, как хотелось бы, но всё равно более или менее. Но со странностями (например, реализован оператор +=, но не реализован *= ; можно умножать на int, но при делении нужно вызывать BigInt::Rossi(int)).

    p.s. Ещё находил вот это: https://github.com/maemual/BigInt – вещь вообще простая, не самая быстрая, но с багами (как минимум при делении, как я понял). Не годится.
      Ну думаю, что подойдёт, судя по характеристикам запроса, однако не могу не упомянуть boost::multiprecision. Для плавающей точки можно сразу быстрый пример, ибо уже есть готовый:
      ExpandedWrap disabled
        #include <iostream>
        #include <iterator>
        #include <vector>
        #include <algorithm>
        #include <iomanip>
        #include <boost/multiprecision/cpp_bin_float.hpp>
         
        #include <chrono>
        #include <cmath>
        #include <typeinfo>
         
        // вывод времени в микросекундах
        template <typename Ch, typename Tr>
        std::basic_ostream<Ch, Tr>& operator<<(std::basic_ostream<Ch, Tr>& os,
                                               std::chrono::high_resolution_clock::duration time)
        {
          return os << std::chrono::duration_cast<std::chrono::microseconds>(time).count();
        }
         
        // точная тестовая  функция
        template <typename T>
        T func(T x)
        {
          return pow(x-5, 6);
        }
         
        // тестовая функция с потерей точности
        template <typename T>
        T poly(T x)
        {
          return pow(x, 6) - 30 * pow(x, 5) + 375 * pow(x, 4) - 2500 * pow(x, 3) + 9375 * pow(x, 2) - 18750 * x + 15625;
        }
         
        // запуск тестовой функции на критическом интервале с малым шагом
        template <typename T, T Fn(T), typename It>
        void run(It it)
        {
          const T start = static_cast<T>(4.98),
                  end   = static_cast<T>(5.02),
                  step  = static_cast<T>(0.0001);
         
          for (T f = start; f < end; f += step)
            *it++ = Fn(f);
        }
         
        // запуск теста COUNT раз с замером времени
        template <typename T, T Fn(T), typename Cont>
        void test(Cont &cont)
        {
          std::cerr << typeid(T).name() << ":\n";
         
          const int COUNT = 100;
          auto      start = std::chrono::high_resolution_clock::now();
         
          for (int i = 0; i < COUNT; ++i)
          {
            cont.clear();
            run<T, Fn>(std::back_inserter<Cont>(cont));
          }
         
          auto      diff  = std::chrono::high_resolution_clock::now() - start;
          std::cerr << diff << " mcs" << std::endl;
        }
         
        // тестирование обоих тестовых функций с выводом их результатов
        template <typename T> void boost_test()
        {
          std::vector<T> vT_1;
          std::vector<T> vT_2;
         
          test<T, func>(vT_1);
          test<T, poly>(vT_2);
         
          for (int i = 0; i < std::min(vT_1.size(), vT_2.size()); ++i)
            std::cout << i << ":\t" << std::setw(20) << vT_1[i] << '\t'
                                    << std::setw(20) << vT_2[i] << '\n';
          std::cout << std::endl;
        }
         
        int main()
        {
          using namespace boost::multiprecision;
         
          typedef number<cpp_bin_float<50,  digit_base_10>> cpp_dec_50;
          typedef number<cpp_bin_float<1000, digit_base_2>> cpp_bin_float_1000;
         
          boost_test<cpp_bin_float_double>();// IEEE's double precision
          boost_test<cpp_bin_float_quad>();  // IEEE's quad precision
          boost_test<cpp_dec_50>();          // 50-dec
          boost_test<cpp_bin_float_1000>();  // 1000-bit
        }
      Ну как быстрый... тут сразу несколько в одном: фактор увеличения точности с ростом битности мантиссы, время заполнения массивов каждой точности и лёгкая адаптация для других условий тестирования.
      Для целочисленной арифметики тоже есть подобные шаблоны. Комплексные легко подхватываются std::complex. Может работать с готовыми фреймворками GMP, libtommath, libquadmath и/или MPFR, если их нет, имеет свои классы. Но есть минус: это буст.
        Цитата Qraizer @
        Но есть минус: это буст.
        А что не так с бюстом? :)
          Цитата Jin X @
          Есть отличная (очень быстрая и функциональная) библиотека для Delphi: http://www.rvelthuis.de/programs/bigintegers.html
          Хотелось бы найти что-то такое же для C++ (скажем, одну или несколько связок из файлов h+cpp).

          Если не найдёшь, то можно на её основе сделать dll.
          И используй дальше, как хочешь.
            ЫукпШ, не хочу DLL.
            Тут люди MPIR предлагают. Она без DLL идёт и перегружено там всё нормально...
            0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
            0 пользователей:


            Рейтинг@Mail.ru
            [ Script execution time: 0,0289 ]   [ 16 queries used ]   [ Generated: 19.04.24, 05:14 GMT ]