Проект основан на исходниках (на С++) библиотеки MPIR, Edition 3.0.0.
Полностью написан на С/С++.
Скорость на порядок выше предыдущего решения.
Реализовал два блока в проекте:
1.DLL c COM интерфейсом.
Реализованы dual-интерфейсы с Automation-совместимыми типами данных, структур
(поддержка как раннего вывязывания, так и позднего). Ранний предпочтительнее в части скорости (на 50% быстрее).
Реализовано два класса: класс целых чисел с арифметикой (BignumArithmeticInteger) и класс чисел с плавающей точкой (BignumArithmeticFloat). При создании экземпляра класса создается массив из 256 чисел с арифметикой.
К числам можно обращаться по номерам (была задумка ввести имя, но оправдывает ли это удобство потери в скорости?)
BignumArithmeticInteger (Bignum) увеличивается в памяти по мере расчета автоматически, перераспределяя память.
BignumArithmeticFloat (Bignum), задается изначально, т.к. дробь может быть бесконечной (по умолчанию принимается минимальный размер).
Размер чисел ничем не ограничен, кроме вашей оперативки.
Регистрация COM реализовано как под админом, так и под пользователем (актуально в офисной части клиентов)
Регистрация стандартная:
Админ: Regsvr32 "...\полный путь\FulName.DLL"
Пользователь: Regsvr32 /i /n "...\полный путь\FulName.DLL"
Примеры использования см. ниже.
2.XLL для Excel с C API - функциями.
Добавил базовый набор. Будет потребность в дополнительных - добавлю по запросу.
Для функций создано два раздела в стандартном списке с названиями классов в COM (+один общий).
Функции поддерживают многопоточные расчеты.
Работа с функциями как с обычными (различий нет). Обычные написаны тоже на С/С++ под C API.
В XLL ресурсы упакована COM.DLL, распаковывается и устанавливается под пользователем - автоматом.
Поэтому открываем XLL или устанавливаем как надстройку - готово (ничего регистрировать не надо).
Пишем код в VBA и работаем. Советую раннее связывание. Видим свойства и методы объекта.
Оные можно посмотреть и в диспетчере объектов (см. рис.)
Примеры см. ниже.
Где тестировалось:
VBA:
Версия 0.0.0.1 под x64 (x32 - пока не поддерживаю).
Прошу протестировать, написать, что хотелось бы видеть в финальной версии.
Реализована простенькая справка с интерфейсом (будет интерес - можно причесать красивее).
Help:
Спойлер
interface IBignumArithmeticInteger : IDispatch
{
[id(1), helpstring("Help")] HRESULT Help();
[propget, id(2), helpstring("Bignum(Bignum-number in the array, BignumBase(optional)=10 - the base may vary from 2 to 36). Convert Bignum/String(BSTR)")] HRESULT Bignum([in] BYTE Bignum, [in, defaultvalue(10L)] LONG BignumBase, [out, retval] BSTR* pVal);
[propput, id(2), helpstring("Bignum(Bignum-number in the array, BignumBase(optional)=10 - the base may vary from 2 to 36). Convert Bignum/String(BSTR)")] HRESULT Bignum([in] BYTE Bignum, [in, defaultvalue(10L)] LONG BignumBase, [in] BSTR newVal);
[propget, id(3), helpstring("Sign(Bignum). Sign Bignum. Return +1 if Bignum > 0, 0 if Bignum = 0, and -1 if Bignum < 0")] HRESULT Sign([in] BYTE Bignum, [out, retval] LONG* pVal);
[propget, id(4), helpstring("Even(Bignum). Determine whether Bignum is odd or even. Return 1 - even, 0 - odd")] HRESULT Even([in] BYTE Bignum, [out, retval] LONG* pVal);
[id(5), helpstring("Bignum(Bignum-number in the array, BignumBase(optional)=10 - the base may vary from 2 to 36). Convert String(BSTR) to Bignum")] HRESULT BignumSet([in] BSTR StringBSTR,[in] BYTE Bignum, [in, defaultvalue(10L)] LONG BignumBase);
[id(6), helpstring("Compare(Bignum1,Bignum2). Compare Bignum1 and Bignum2. Return +1 if Bignum1 > Bignum2, 0 if Bignum1 = Bignum2, and -1 if Bignum1 < Bignum2")] HRESULT Compare([in] BYTE Bignum1, [in] BYTE Bignum2, [out, retval] LONG* pVal);
[id(7), helpstring("Sum(BignumSet, Bignum1, Bignum2). BignumSet = Bignum1 + Bignum2")] HRESULT Sum([in] BYTE BignumSet, [in] BYTE Bignum1, [in] BYTE Bignum2);
[id(8), helpstring("SumL(BignumSet, Bignum1, LONGLONG). BignumSet = Bignum1 + LongLong")] HRESULT SumL([in] BYTE BignumSet, [in] BYTE Bignum1, [in] LONGLONG LONGLONG);
[id(9), helpstring("Abs(BignumSet, Bignum1). Set absolute value. BignumSet = Abs(Bignum1)")] HRESULT Abs([in] BYTE BignumSet, [in] BYTE Bignum1);
[id(10), helpstring("Negate(BignumSet, Bignum1). BignumSet = - Bignum1")] HRESULT Negate([in] BYTE BignumSet, [in] BYTE Bignum1);
[id(11), helpstring("Subtract(BignumSet, Bignum1, Bignum2). BignumSet = Bignum1 - Bignum2")] HRESULT Subtract([in] BYTE BignumSet, [in] BYTE Bignum1, [in] BYTE Bignum2);
[id(12), helpstring("SubtractL(BignumSet, Bignum1, ULONGLONG). BignumSet = Bignum1 - LongLong")] HRESULT SubtractL([in] BYTE BignumSet, [in] BYTE Bignum1, [in] ULONGLONG ULONGLONG);
[id(13), helpstring("Multiply(BignumSet, Bignum1, Bignum2). BignumSet = Bignum1 * Bignum2")] HRESULT Multiply([in] BYTE BignumSet, [in] BYTE Bignum1, [in] BYTE Bignum2);
[id(14), helpstring("MultiplyL(BignumSet, Bignum1, ULONGLONG). BignumSet = Bignum1 * LongLong")] HRESULT MultiplyL([in] BYTE BignumSet, [in] BYTE Bignum1, [in] ULONGLONG ULONGLONG);
[id(15), helpstring("Divide(BignumQuotient, BignumRemainder, Bignum1, Bignum2). BignumQuotient, BignumRemainder = Bignum1 / Bignum2. Divide(BignumQuotient - method 'truncate' , BignumRemainder, Bignum1, Bignum2)")] HRESULT Divide([in] BYTE BignumQuotient, [in] BYTE BignumRemainder, [in] BYTE Bignum1, [in] BYTE Bignum2);
[id(16), helpstring("DivideL(BignumQuotient, BignumRemainder, Bignum1, ULONGLONG). BignumQuotient, BignumRemainder = Bignum1 / ULONGLONG. DivideL(BignumQuotient - method 'truncate' , BignumRemainder, Bignum1, ULONGLONG")] HRESULT DivideL([in] BYTE BignumQuotient, [in] BYTE BignumRemainder, [in] BYTE Bignum1, [in] ULONGLONG ULONGLONG);
[id(17), helpstring("Power(BignumSet, Bignum1, ULONGLONG). BignumSet = Bignum1 ^ ULONGLONG")] HRESULT Power([in] BYTE BignumSet, [in] BYTE Bignum1, [in] ULONGLONG ULONGLONG);
[id(18), helpstring("Clone(BignumSet, Bignum1). BignumSet = Bignum1")] HRESULT Clone([in] BYTE BignumSet, [in] BYTE Bignum1);
[id(19), helpstring("RootRem(BignumSet, Bignum1, ULONGLONG n_root). BignumRoot, BignumRemainder = (n-th root)√ Bignum1")] HRESULT RootRem([in] BYTE BignumRoot, [in] BYTE BignumRemainder, [in] BYTE Bignum1, [in] ULONGLONG n_root);
[id(20), helpstring("Factorial(BignumSet, ULONG n). BignumSet = !n")] HRESULT Factorial([in] BYTE BignumSet, [in] ULONG n);
[id(21), helpstring("Fibonacci(BignumSet, ULONGLONG n). BignumSet = Fn, the n’th Fibonacci number")] HRESULT Fibonacci([in] BYTE BignumSet, [in] ULONGLONG n);
[id(22), helpstring("LucNum(BignumSet, ULONGLONG n). BignumSet = Ln, the n’th Lucas number")] HRESULT LucNum([in] BYTE BignumSet, [in] ULONGLONG n);
};
interface IBignumArithmeticFloat : IDispatch
{
[id(1), helpstring("Help")] HRESULT Help();
[propget, id(2), helpstring("SizeBits(Bignum). SizeBits - Set/Get bit size Bignum")] HRESULT SizeBits([in] BYTE Bignum, [out, retval] LONGLONG* pVal);
[propput, id(2), helpstring("SizeBits(Bignum). SizeBits - Set/Get bit size Bignum")] HRESULT SizeBits([in] BYTE Bignum, [in] LONGLONG newVal);
[propget, id(3), helpstring("Bignum(Bignum-number in the array, BignumBase(optional)=10 (2 to 36), Separator(optional)='.', Exponential(optional) = 1 (1-Exponential entry, 0 - decimal), Precision(optional) = 0 (0-Max, 1-... - number of digits). Convert Bignum/String(BSTR)")] HRESULT Bignum([in] BYTE Bignum, [in, defaultvalue(10L)] LONG BignumBase, [in, defaultvalue(".")] BSTR Separator, [in, defaultvalue(-1)] VARIANT_BOOL Exponential, [in, defaultvalue(0)] LONGLONG Precision, [out, retval] BSTR* pVal);
[propput, id(3), helpstring("Bignum(Bignum-number in the array, BignumBase(optional)=10 (2 to 36), Separator(optional)='.', Exponential(optional) = 1 (1-Exponential entry, 0 - decimal), Precision(optional) = 0 (0-Max, 1-... - number of digits). Convert Bignum/String(BSTR)")] HRESULT Bignum([in] BYTE Bignum, [in, defaultvalue(10L)] LONG BignumBase, [in, defaultvalue(".")] BSTR Separator, [in, defaultvalue(-1)] VARIANT_BOOL Exponential, [in, defaultvalue(0)] LONGLONG Precision, [in] BSTR newVal);
[propget, id(4), helpstring("Sign(Bignum). Sign Bignum. Return +1 if Bignum > 0, 0 if Bignum = 0, and -1 if Bignum < 0")] HRESULT Sign([in] BYTE Bignum, [out, retval] LONG* pVal);
[id(5), helpstring("SizeBitsSet(Bignum, SizeBits). Set bit size Bignum")] HRESULT SizeBitsSet([in] BYTE Bignum, [in] LONGLONG SizeBits);
[id(6), helpstring("BignumSet(StringBSTR - string-in, Bignum-number in the array, BignumBase(optional)=10 (2 to 36), Separator(optional)='.', Exponential(optional) = 1 (1-Exponential entry, 0 - decimal), Precision(optional) = 0 (0-Max, 1-... - number of digits). Convert String(BSTR) to Bignum")] HRESULT BignumSet([in] BSTR StringBSTR,[in] BYTE Bignum, [in, defaultvalue(10L)] LONG BignumBase, [in, defaultvalue(".")] BSTR Separator, [in, defaultvalue(-1)] VARIANT_BOOL Exponential, [in, defaultvalue(0)] LONGLONG Precision);
[id(7), helpstring("Compare(Bignum1,Bignum2). Compare Bignum1 and Bignum2. Return +1 if Bignum1 > Bignum2, 0 if Bignum1 = Bignum2, and -1 if Bignum1 < Bignum2")] HRESULT Compare([in] BYTE Bignum1, [in] BYTE Bignum2, [out, retval] LONG* pVal);
[id(8), helpstring("Sum(BignumSet, Bignum1, Bignum2). BignumSet = Bignum1 + Bignum2")] HRESULT Sum([in] BYTE BignumSet, [in] BYTE Bignum1, [in] BYTE Bignum2);
[id(9), helpstring("Abs(BignumSet, Bignum1). Set absolute value. BignumSet = Abs(Bignum1)")] HRESULT Abs([in] BYTE BignumSet, [in] BYTE Bignum1);
[id(10), helpstring("Subtract(BignumSet, Bignum1, Bignum2). BignumSet = Bignum1 - Bignum2")] HRESULT Subtract([in] BYTE BignumSet, [in] BYTE Bignum1, [in] BYTE Bignum2);
[id(11), helpstring("Multiply(BignumSet, Bignum1, Bignum2). BignumSet = Bignum1 * Bignum2")] HRESULT Multiply([in] BYTE BignumSet, [in] BYTE Bignum1, [in] BYTE Bignum2);
[id(12), helpstring("Divide(BignumSet, Bignum1, Bignum2). BignumSet = Bignum1 / Bignum2")] HRESULT Divide([in] BYTE BignumSet, [in] BYTE Bignum1, [in] BYTE Bignum2);
[id(13), helpstring("Root(BignumSet, Bignum1). BignumSet = √ Bignum1")] HRESULT Root([in] BYTE BignumSet, [in] BYTE Bignum1);
[id(14), helpstring("Negate(BignumSet, Bignum1). BignumSet = - Bignum1")] HRESULT Negate([in] BYTE BignumSet, [in] BYTE Bignum1);
[id(15), helpstring("Power(BignumSet, Bignum1, Bignum2). BignumSet = Bignum1 ^ Bignum2.")] HRESULT Power([in] BYTE BignumSet, [in] BYTE Bignum1, [in] ULONGLONG ULONGLONG);
[id(16), helpstring("Clone(BignumSet, Bignum1). BignumSet = Bignum1")] HRESULT Clone([in] BYTE BignumSet, [in] BYTE Bignum1);
};
Ресурсы:
MPIR library, Edition 3.0.0 (freely distributable librarys)http://mpir.org/
+ my code written in C / C ++
©2018, BedvitCOM v.0.0.0.1
License: Freely distributable libraryВсегда актуальные версии библиотек здесь. Сделал в одном месте, что бы было проще поддерживать.