Большие целые числа в C#
-
05-07-2019 - |
Вопрос
В настоящее время я являюсь заимствование java.math.BigInteger
из библиотек J #, как описано здесь.Поскольку я никогда раньше не использовал библиотеку для работы с большими целыми числами, это кажется медленным, порядка в 10 раз медленнее, даже для ulong
числа длины.Есть ли у кого-нибудь лучшие (желательно бесплатные) библиотеки, или такой уровень производительности нормальный?
Решение
Начиная с .NET 4.0 вы можете использовать класс System.Numerics.BigInteger. См. Документацию здесь: http: // msdn.microsoft.com/en-us/library/system.numerics.biginteger(v=vs.110).aspx р>
Другой альтернативой является класс IntX . Р>
IntX - произвольная точность библиотека целых чисел, написанная на чистом C # 2.0 с быстрым - O (N * log N) - алгоритмы умножения / деления реализация. Это обеспечивает все основные операции над целыми числами, такими как сложение, умножение, сравнение, сдвиг по битам и т. д.
Другие советы
F #
также поставляется с одним. Вы можете получить его по адресу Microsoft.FSharp.Math
.
Класс System.Numerics.BigInteger
в .NET 4.0 основан на Microsoft.SolverFoundation.Common.BigInteger
от Microsoft Research.
Класс BigInteger
Фонда Солвера выглядит очень производительно. Я не уверен, под какой лицензией она выпущена, но вы можете получить ее здесь (загрузить и установите Solver Foundation и найдите файл Microsoft.Solver.Foundation.dll).
Я думаю, вы могли бы оптимизировать реализацию, если бы выполнили все операции с BigInts, которые будут возвращать результаты меньшего размера, чем собственный тип (например.int64) для собственных типов и иметь дело только с большим массивом, если вы собираетесь переполниться.
Редактировать Это реализация в codeproject, кажется , всего в 7 раз медленнее ...Но с помощью приведенной выше оптимизации вы могли бы заставить его работать почти идентично собственным типам для небольших чисел.
Вот несколько реализаций BigInteger в C #. Я использовал реализацию MonIn BigInteger, работает довольно быстро (я использовал ее в CompactFramework)
Моно р>
Я не уверен насчет производительности, но у IronPython также есть класс BigInteger. Он находится в пространстве имен Microsoft.Scripting.Math.
Да, это будет медленно, и разница в 10 раз - это то, что я ожидал. BigInt использует массив для представления произвольной длины, и все операции должны выполняться вручную (в отличие от большинства математических операций, которые могут выполняться непосредственно с процессором)
Я даже не знаю, даст ли вам ручное кодирование в сборке большую часть прироста производительности в 10 раз, это чертовски близко. Я бы искал другие способы его оптимизации - иногда, в зависимости от вашей математической задачи, есть небольшие приемы, которые можно сделать, чтобы сделать это быстрее.
Я использовал Biginteger на предыдущей работе. Я не знаю, какие у тебя должны быть результаты. Я не использовал его в ситуации с высокой производительностью, но у меня никогда не было с этим проблем.
Это может показаться странным предложением, но вы проверили десятичный тип, чтобы увидеть, как быстро он работает?
Десятичный диапазон - & # 177; 1.0 & # 215; От 10 ^ 28 до 28,9; 21,9; 10 ^ 28, поэтому он все еще может быть недостаточно большим, но он больше, чем ulong.
В .NET 3.5 должен был быть класс BigInteger, но его вырезали .
Это вам не поможет, но в .Net 3.5 должен был быть класс BigInteger; это было сокращено, но из заявлений, сделанных в PDC, это будет в .Net 4.0. Очевидно, они потратили много времени на его оптимизацию, поэтому производительность должна быть намного лучше, чем сейчас.
Кроме того, этот вопрос по сути является копией Как я могу представить очень большое целое число в .NET?
См. ответы в этом нить . Вам нужно будет использовать одну из доступных сторонних библиотек / классов больших целых чисел или дождаться C # 4.0, который будет включать собственный тип данных BigInteger.
Это выглядит очень многообещающе. Это оболочка C # над GMP .
http://web.rememberingemil.org/Projects/GnuMpDotNet/GnuMpDotNet.hml / a>
Существуют также другие варианты BigInteger для .Net здесь , в частности, Mpir.Net
Вы также можете использовать Math.Gmp.Native . Пакет Nuget, который я написал. Его исходный код доступен на GitHub , а документация доступна здесь . Он предоставляет .NET все функциональные возможности библиотеки GMP , известной как высокооптимизированная арифметика с произвольной точностью библиотека.
Целое число произвольной точности представлено как mpz_t type. Все операции над этими целыми числами начинаются с префикса mpz _
. Например, mpz_add или mpz_cmp . Примеры исходного кода приведены для каждой операции.