Поиск  Пользователи  Правила 
Закрыть
Логин:
Пароль:
Забыли свой пароль?
Регистрация
Войти
 
Страницы: 1
RSS
Длинная арифметика (Bignum arithmetic ) c COM-интерфейсом и C API Functions для Excel. С/С++
 
Проект основан на исходниках (на С++) библиотеки MPIR, Edition 3.0.0.
Полностью написан на С/С++.
Скорость на порядок выше предыдущего решения на C#.NET.
Реализовал два блока в проекте:
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:
Код
Sub RUN() 'ЗАПУСКАЕМ
Dim I As Long: With ThisWorkbook.VBProject.References 'подключаем библу для раннего связывания
  For I = 1 To .Count: If .Item(I).GUID = "{77D79CA3-15A0-4310-B8D8-0BCBE3F72D96}" Then Continue: Exit Sub 'если "BedvitCOM" в подключенных - завершаем
  Next I
  .AddFromGuid "{77D79CA3-15A0-4310-B8D8-0BCBE3F72D96}", 1, 0: Continue: End With ' подключаем библу "BedvitCOM"
End Sub
Sub Continue()
Dim I As BignumArithmeticInteger
Set I = New BignumArithmeticInteger 'Создаем массив целых больших чисел и арифметикой (класс)
Dim F As BignumArithmeticFloat
Set F = New BignumArithmeticFloat 'Создаем массив больших чисел с плавающей точкой и арифметикой (класс)
 
I.Bignum(1) = "111" & String$(100, "1") 'добавляем число из 103 единиц в первое целое длинное число
I.BignumSet "111" & String$(100, "1"), 1 'или так
F.SizeBits(1) = 256 'задаем размер в битах для 1го числа с плавающей точкой
F.SizeBits(2) = 256 'задаем размер в битах для 2го числа с плавающей точкой
F.SizeBits(3) = 256 'задаем размер в битах для 3го числа с плавающей точкой
F.Bignum(1) = I.Bignum(1) 'копируем данные из одного класса чисел в другой (из первого в первое)
F.Clone 2, 1 'копируем в рамках одного класса число из первого во второе, т.е. число 2 = числу 1
'в рамках одного класса такое копирование на порядки быстрее
F.Root 3, 2 'вычисляем корень из второго числа в третье.
'логика всей арифметики в классах предполагает получение результата в первом параметре(левой части выражения),
'по аналогии с "=", т.е. число3 = кореньиз(2число)
Debug.Print F.Bignum(3) 'смотрим результат в третьем числе
'1.054092553389459777332964514810906177906518379775072275619168284264198146213079E+51
 
I.Help 'смотрим Help
End Sub

1С:
Код
F = Новый COMОбъект("BedvitCOM.BignumArithmeticDouble"); //Создаем массив больших чисел с плавающей точкой и арифметикой (класс)
F.SizeBitsSet(1,256); //задаем размер в битах для 1го числа с плавающей точкой
F.SetBignum( "11111",1); //присваиваем данные для 1го числа
F.Power(1,1,51561); //возводим в степень 51561 первое число и кладем его в первое же число.
f = F.Bignum(1); //кладем данные в переменную из первого числа
Сообщить(f); //смотрим

Версия 0.0.0.1 под x64 (x32 - пока не поддерживаю).
Прошу протестировать, написать, что хотелось бы видеть в финальной версии.
Реализована простенькая справка с интерфейсом (будет интерес - можно причесать красивее).
Help:
Скрытый текст

Ресурсы:
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

Файлы не пролезли, потому на ресурсе здесь.
BedvitCOM.PNG (23.48 КБ)
BedvitCOM2.PNG (7.4 КБ)
BedvitXLL.PNG (22.99 КБ)
BedvitXLL2.PNG (14.77 КБ)
Изменено: bedvit - 26 Мар 2018 23:01:05
«Бритва Оккама» или «Принцип Калашникова»?
 
Большая работа проведена. А кому такие числа нужны? Финансистам, математикам, астрономам?) Из перечисленных наверное только первые пользуются Excel  в той или иной степени.

Ни в коей мере не пытаюсь критиковать и т.д..
 
Критику принимаю, не барышня). Писал для интереса. пользоваться можно любым приложением поддерживающим COM. Сфера применения - вычисления с большой точностью, а так же поклонники нестандартных решений, и тестирование возможностей ПК и программ (для таких, как я).
Изменено: bedvit - 26 Мар 2018 23:00:28
«Бритва Оккама» или «Принцип Калашникова»?
 
Доброе время суток.
Виталий, большое спасибо, интересное решение. Эх, ещё бы время, чтобы изучить... :(  Сохранил ссылку, вдруг получится поковырять.
 
Андрей Приветствую! Буду рад, если пригодится это решение. С вопросами, если будут, обращайся, отвечу. :)
«Бритва Оккама» или «Принцип Калашникова»?
 
bedvit, очень мощно! Сохранил в закладки))) спасибо!
«Тот, кто несет фонарь, спотыкается чаще, чем тот, кто идет следом.»
Иоганн Пауль Фридрих Рихтер
 
Jack Famous, спасибо за оценку, пользуйтесь :)
«Бритва Оккама» или «Принцип Калашникова»?
 
Уважаемый Виталий! Спасибо за большую проделанную работу по предоставлению доступа широкому кругу любителей VBA к одной из самых замечательных математических библиотек!
Владимир
 
sokol92, Считается одной из быстрейших. Тестируйте)
«Бритва Оккама» или «Принцип Калашникова»?
 
Поделился и на Киберфоруме.
«Бритва Оккама» или «Принцип Калашникова»?
 
05/04/2018 - Новая версия BedvitCOM v.1.0.0.2 и BedvitXLL v.1.0.0.2

Изменения:
1. Изменен порядок аргументов в методе "BignumSet" (теперь, как во всех других методах, номер длинного числа в массиве - стоит первым аргументом), см.под спойлером

Скрытый текст


2. Добавлены новые методы в два класса (запись длинного числа в файл .txt и чтение из файла)
.FileSet, .FileGet (описание в .Help и ниже)
3. Собраны библиотеки COM и XLL в 32-разрядной версии (с корректным Help-ом, описанием интерфейса).

Свойства и методы (интерфейс) последней версии библиотеки COM (есть в .Help):
Скрытый текст

Библиотеки не пролезают, поэтому здесь.
«Бритва Оккама» или «Принцип Калашникова»?
 
24/04/2018 - Новая версия BedvitCOM v.1.0.0.3 и BedvitXLL v.1.0.0.3 (поддержка х32 и х64)

1. Добавлены новые функции в два класса библиотеки COM - арифметика длинных чисел с обычными, т.е. теперь можно совершать арифметические действия длинных чисел с обычными.
2. Добавлен механизм очистки/освобождения памяти как для одного числа, так и для класса/объекта в целом.
3. Сделано новое описание для всех свойств и методов двух классов на русском языке в справке (см. под спойлером и в .HELP)
4. XLL теперь удаляет данные из реестра (COM.DLL) под пользователем при закрытии надстройки.

Список C API - функций в Excel:
Блок BedvitXLLBignumArithmeticInteger:
1.ConvertBaseInteger - конвертирование целого числа (строки) из одной базы в другую (от 2 до 36).
Блок BedvitXLLBignumArithmeticFloat:
1.SumFloat - сложение двух длинных/обычных чисел с плавающей точкой
2.SubtractFloat - вычитание двух длинных/обычных чисел с плавающей точкой
3.MultiplyFloat - умножение двух длинных/обычных чисел с плавающей точкой
4.DivideFloat - деление двух длинных/обычных чисел с плавающей точкой
5.PowerFloat - возведение в степень длинного/обычного числа
6.RootFloat - извлечение квадратного корня из длинного/обычного числа

Еще раз уточню: при открытии XLL можно работать как с новыми C API функциями, так и с COM.DLL через VBA.

Работать с длинными числами можно не только через индексы, но и через буквенные переменные.

Пример №3: VBA - через буквенное обозначение, позднее связывание
Код
Dim A, B, C: A = 1: B = 2: C = 3
Dim I As Object: Set I = CreateObject("BedvitCOM.BignumArithmeticInteger") 'Создаем массив целых больших чисел и арифметикой (класс)
I.BignumSet A, "12324344435654132546546546564453131" 'задаем данные в число A
I.BignumSet B, "34534534546546546546554665513213211" 'задаем данные в число B
I.Sum C, A, B 'C=A+B
Debug.Print I.Bignum(B) 'смотрим
I.Clear  'освобождаем память для всего объекта I


Пример №4: 1С - через буквенное обозначение
Код
A=1; B=2; C=3; 
I = Новый COMОбъект("BedvitCOM.BignumArithmeticInteger"); //Создаем массив целых больших чисел и арифметикой (класс)
I.BignumSet(A,"12324344435654132546546546564453131");  //задаем данные в число A
I.BignumSet(B,"34534534546546546546554665513213211");  //задаем данные в число B
I.Sum(C,A,B); //C=A+B
Сообщить(f); //смотрим
I.Clear; //освобождаем память для всего объекта I


Свойства и методы последней версии библиотеки COM (есть в .Help, в .Help оформлено красивее):
Скрытый текст

Библиотеки не пролезают, поэтому здесь.
«Бритва Оккама» или «Принцип Калашникова»?
Страницы: 1
Читают тему (гостей: 1)