Библиотеки, естественно, сишные. Делаю к ним заголовки для FreePascal.
https://github.com/VadimAnIsaev/GNU-MP-for-FreePascal
Сейчас почти готово для библиотеки GNU MP (GMP), в данный момент перевожу на Паскаль ихний бенчмарк.
Далее будут:
- GNU MPFR - библиотека для работы с длинными десятичными дробями, аналог модуля Math. Сам заголовочник готов, надо только снабдить его примерами;
- GNU MPC - библиотека для работы с длинными комплексными числами. Заголовочник почти готов, с идеями примеров пока испытываю затруднения. Думаю, может что-то из электротехники взять... ;
- GNU MPI - библиотека интервальной арифметики. В том, что она так уж необходима для Паскаля я не очень то и верю, поэтому пока за неё не брался. Но, наверное, пусть будет...
GMP в FCL есть, только сильно старый. Он перекочевал из GnuPascal и с тех пор за него никто не садился. Мои изменения по сравнению с существующей реализацией:
- Модуль сделан на основе последней на момент написания статьи версии библиотеки GMP - 6.1.2;
- Добавлены функции инициализации (и очистки) неопределённого количества переменных за раз (префикс_inits() и префикс_clears()) которые появились в версии 5 библиотеки GMP. В FCL'евской "gmp.pas" они отсутствуют;
- Добавлена функция префикс_sgn() позволяющая определить знак числа. В самой библиотеке её нет, но макрос определён в "gmp.h". Такой уж насущей необходимостью она не является, т.к. знак числа можно определить по полю "size" переменной. Но пусть будет на всякий случай;
- Добавлены типы данных, которые были в "gmp.h", однако по какой-то причине отсутствовали в старом "gmp.pas";
- Все типы параметров функций приведены к единому стандартному виду. Дело в том, что в старом модуле "gmp.pas" встречались параметры дополненные модификатором "var" в том случае, если функция их изменяет. Новые функции, типа префикс_inits() с таким модефикатором работать отказываются. Вдобавок встречаются функции (типа gmp_printf()) в которых параметры непременно нужно указывать в виде адреса. В новом модуле этот разнобой устранён. Все параметры требующие длинные числа передаются функциям как адрес с помощью "@";
- Все имена функций приведены к тому виду, в каком они описаны в оригинальной документации. Таким образом, не будет каких-либо излишних проблем, чтобы существующий сишный код быстро переделать в паскалевский;
- Параметры длинных чисел, которые не требуют изменения дополнены модификаторм "const", как это сделано в оригинальном коде библиотеки;
- В модуль не включены некоторые функции из "gmp.h", которые используют некоторые специфичные для Си типы данных, например "FILE" и "va_list". Хотя включить в модуль аналог сишного "FILE" не является сложным делом, однако проблемы будут у самой библиотеки GMP. Дело в том, что у разных компиляторов Си структура типа "FILE" разная. Даже, как ни странно, у "mingw" и "cygwin" у которых, казалось бы компилятор один и тот же - "gcc";
- Все функции, которые у разработчиков в документации помечены как "устаревшие" снабжены меткой "deprecated" на которую компилятор "fpc" будет выдавать предупреждение с рекоммендацией чем можно заменить;
- В модуль не включено всё, что касается ООП. Дело в том, что ООП в имеющемся в FCL модуле - это чистая отсебятина, которая к оригиналу не имеет ни какого отношения. Но это не главное. Исследование интернета показало, что даже те разработчики, которые в своих проектах с GMP используют компиляторы C++, предпочитают применять низкоуровневые, сишные типы данных.
Все функции разделены на несколько включаемых файлов:
- mpf.inc - функции относящиеся к десятичным дробям;
- mpn.inc - низкоуровневые функции. Эти функции непосредственно в программе с длинными числами не используются. Однако если есть необходимость сократить время исполнения чего-либо, то можно их применить;
- mpq.inc - функции обычных дробей;
- mpz.inc - функции для целых чисел;
- print.inc - общие функции относящиеся к вводуввыводу данных;
- random.inc - функции обслуживающие генераторы псевдослучайных чисел.
Такое разделение сделано на тот случай, если вы захотите сэкономить на размере программы, применяя только один тип данных. Например, если вам нужны только целочисленные вычисления, то в файле "gmp.pas" нужно закомментировать строки "{$include mpf.inc}", "{$include mpq.inc}", "{$include mpz.inc}".
В дополнение к "gmp.pas", предлагается модуль "gmp2.pas". В этом модуле я постарался сделать использование GMP более удобным, чем это предлагается в оригинале "gmp.h". Вот основные дополнения:
- Определены операторы присваивания всех основных стандартных типов переменным GMP;
- Определены операторы сравнения переменных GMP;
- Кое-какие процедуры сделаны функциями;
- Добавлены кое-какие информационные функции, например расчёта количества разряда в числе или максимальное количество разрядов, которое можно получить в представленном числе.
По основам использования GMP в скором времени будет статья на нашем сайте.
Добавлено спустя 17 минут 26 секунд:
Если кому интересно, принимаются пожелания, советы, вопросы, а так же строгие, но справедливые упрёки...