будь-який документ, який точно говорить, для якого діапазону чисел розроблені .NET BigIntegers?


12

Я граю з .NET BigInteger, і в основному мені цікаво, яке число - розрахункова відповідь буде добре - це точка відхилення кривої (графік (збільшення часу, необхідного для операцій) vs (значення BigInteger))?

або вони розроблені без такого відхилення, що якщо ми побудуємо збільшення часу, необхідного для операцій проти значення BigInteger від 1 до нескінченності, у нас буде вся плавна крива?

наприклад, якщо припустити, що масиви розроблені з можливістю обробки 50 елементів. це означає, що якщо у мене є 1 елемент, операції виконують f (1) час. і коли у мене є 2 пункти, операції - f (2) час. якщо у мене 50 предметів, операції будуть f (50) часом. але оскільки він призначений для обробки лише 50 предметів, операції, виконані, коли у нас є 51 предмет, будуть g (51), де g (51)> f (51).

Якщо правильно реалізовано, складність арифметики BigInteger повинна бути гладкою кривою. Наприклад, часова складність множення повинна бути O (NM), де N - кількість цифр у першому множині, а M - кількість цифр у другому множині. Звичайно, є практичні обмеження в тому, що ви можете вибрати N і M настільки великі, що цифри не вмістяться у вашій машині.

Чи є хтось / хто знає якісь документи, які стверджують, що він реалізований як такий?


3
@ Зібралися виборці, голоси вниз не означають нічого, якщо ви не можете залишити коментар, пояснюючи, чому це питання не є гарним. Я підтримав це, оскільки не бачу проблем з цим.
The Muffin Man

Я не заявив, але не впевнений, у чому тут питання. Ви хочете знати складність виконання операцій / пам'яті операцій над bigint (складання, множення, ділення тощо)?
nikie

наприклад, якщо припустити, що масиви розроблені з можливістю обробки 50 елементів. це означає, що якщо у мене є 1 елемент, операції виконуються f (1) час. і коли у мене є 2 пункти, операції - f (2) час. якщо у мене 50 предметів, операції є f (50) часом. але оскільки він призначений для обробки лише 50 предметів, то операції, виконані, коли у нас є 51 предмет, будуть g (51), де g (51)> f (51)
Pacerier

@Charles E. Грант так! це те, про що я говорю. питання: чи є / хтось знає якісь документи, які стверджують, що він реалізований як такий?
Pacerier

@Paceier Я перемістив свій коментар до своєї відповіді та додав посилання на документ, що обговорював саме це.
Чарльз Е. Грант

Відповіді:


7

Будь-яке число, яке, можливо, може бути більшим, ніж ULong.MaxValue, або менше Long.MinValue, повинно бути представлене за допомогою BigInteger.

Якщо НЕ (Long.MinValue <= X <= ULong.MaxValue), то BigInteger

BigInteger - це занадто велика кількість, ніж звичайні примітиви.

Наприклад, якщо ваше ціле число знаходиться поза діапазоном Long, ви, ймовірно, повинні використовувати BigInteger. Ці випадки є дуже рідкісними, і використання цих класів має значно вищі накладні витрати, ніж їхні примітивні аналоги.

Наприклад, longширина 64 біта і може утримувати діапазон: від -9,223,372,036,854,775,808 до 9,223,372,036,854,775,80. ulong може вмістити від 0 до 18,446,744,073,709,551,615. Якщо ваші номери більше або менше, BigInteger - ваш єдиний варіант

Єдиний раз, коли я їх бачив, як вони використовувались у реальному додатку, - це програма для початкових діаграм.

Дивіться також: Примітивні діапазони в .NET


я маю на увазі, звичайно, я знаю, що ми повинні використовувати звичайні примітиви, коли ми можемо .. я маю на увазі, як скажімо, BigInteger призначений для чисел у 100 разів більше, ніж ULong.MaxValue, або BigInteger розрахований на числа в 100 к разів більше, ніж ULong.MaxValue? я маю на увазі, що я знаю, що він може підтримувати в 100 разів більше, ніж ULong.MaxValue, але чи розроблений він з урахуванням цього діапазону, або він розроблений з таким діапазоном, оголошеним "нестандартним вимогою"?
Pacerier

5
Ви не можете представити число, яке навіть більше, ніж ULong.MaxValue, не використовуючи BigInteger, тому це для цього. Будь-яке число, яке може бути більшим, ніж ULong.MaxValue, повинно бути BigInteger.
Мальфіст

звичайно, є способи представити числа, більші, ніж ULong.MaxValue і без використання BigInteger. я міг би просто написати власну структуру, що складається з ULong та булевого та альта, я можу представляти до двох разів ULong.MaxValue
Pacerier

Так, але використання BigInteger набагато складніше, і, мабуть, це не буде набагато швидшим, якби швидше, і не було б таким гнучким, як BigInteger. Ви також можете представляти дуже великі числа з масивом булевих, але це занадто складно.
Malfist

2
@Mavrik, він змінив це на зовсім інше питання, ніж на те, на що я відповів.
Malfist

4

У певному сенсі сенс BigInteger - це не стільки абсолютний розмір, скільки необмежена точність. Числа з плаваючою комою теж можуть бути дуже великими, але мають обмежену точність. BigInteger дозволяє виконувати арифметику, не турбуючись про помилки округлення або переповнення. Ціна, яку ви платите, полягає в тому, що вона в сотні разів повільніше, ніж арифметична із звичайними цілими числами чи числами з плаваючою комою.

Як зазначали інші, улонг може містити від 0 до 18,446,744,073,709,551,615, і поки ви залишаєтеся в цьому діапазоні, ви можете робити точну арифметику. Якщо ви перейдете навіть на 1 межі за межі цього діапазону, ви отримаєте переповнення, тому відповідь на ваше запитання - використовувати BigInteger, якщо вам потрібна точна арифметика і є ймовірність, що будь-який проміжний результат перевищить 18,446,744,073,709,551,615.

Більшість проблем науки, техніки та фінансів можуть жити з наближеннями, вимушеними числами з плаваючою комою, і не можуть собі дозволити арифметику вартості BigInteger. Більшість комерційних розрахунків не можуть жити з наближеннями арифметики з плаваючою комою, але працюють у межах від 0 до 18,446,744,073,709,551,615, тому вони можуть використовувати звичайну арифметику. BigInteger потрібен при використанні алгоритмів з теорії чисел, що включає в себе такі речі, як криптографія (подумайте, 50-значне просте число). Він також іноді використовується в комерційних програмах, коли потрібні точні розрахунки, швидкість не надто важлива, а налаштування правильної системи з фіксованою десятковою точкою - це занадто багато проблем.

Якщо правильно реалізовано, складність арифметики BigInteger повинна бути гладкою кривою. Наприклад, часова складність множення повинна бути O (NM), де N - кількість цифр у першому множині, а M - кількість цифр у другому множині. Звичайно, є практичні обмеження в тому, що ви можете вибрати N і M настільки великі, що цифри не вмістяться у вашій машині.

Якщо ви перейдете в Google "Комп'ютерна складність biginteger", ви отримаєте більше посилань, ніж можете потиснути палицю. Одне, що безпосередньо відповідає на ваше запитання, це таке: Порівняння двох довільних арифметичних пакетів точності .


4

Обмеження пам’яті

BigInteger покладається на масив int для зберігання. Припускаючи це, теоретичний ліміт максимальної кількості, який BigInteger здатний представляти, може бути отриманий з максимального розміру масиву, наявного в .net. Тут є SO-тема щодо масивів: Пошук того, скільки пам'яті я можу виділити для масиву в C # .

Припускаючи, що ми знаємо максимальний розмір масиву, ми можемо оцінити максимальну кількість, яку може представляти BigInteger: (2 ^ 32) ^ max_array_size, де:

  • 2 ^ 32 - максимальна кількість у комірці масиву (int)
  • max_array_size - максимально дозволений розмір масиву int, який обмежений розміром об'єкта 2 Гб

Це дає число з 600 мільйонами десяткових цифр.

Обмеження продуктивності

Що стосується продуктивності, BigInteger використовує алгоритм Карацуби для множення та лінійний алгоритм додавання. Складність множення полягає в тому 3 * n ^ 1,585, що це означає, що він буде масштабуватися досить навіть для великої кількості ( графік складності ), однак ви все одно можете вражати ефективність штрафу залежно від розміру оперативної пам’яті та кеш-пам'яті процесора.

Оскільки максимальний розмір номерів обмежений 2 Гб, на машині спуску ви не побачите несподіваного розриву в продуктивності, але все-таки працює на 600 мільйонних цифр буде мертво повільно.


це чудова інформація, проте де ваше джерело, що BigInteger покладається на масиви int?
Pacerier

Я щойно заглибився у джерела .net за допомогою dotPeek. Здається, саме число зберігається всередині uint [] _даних структури BigInteger.
Валера Колупаєв

* Оновлено більш детальною відповіддю, однак я не можу знайти жодного вихідного коду .net, на який я можу посилатися, за винятком декомпільованих фрагментів.
Валера Колупаєв

Мені здається, що в .NET існує алгоритм множення стандартів, як це можна зрозуміти з ILSpy: .NET множення BigInteger
Іван Кочуркін

1

Обмеження - це розмір вашої пам’яті (та час, який у вас є). Отже, у вас може бути дійсно велика кількість. За словами Кевіна, у криптографії треба множити або експонувати екстрентенцію чисел на кілька тисяч (двійкових) цифр, і це можливо без проблем.

Звичайно, часто алгоритми стають повільнішими, оскільки числа збільшуються, але не набагато повільніше.

Коли ви використовуєте цифри в мегазначному діапазоні, ви, можливо, захочете подумати і над іншими рішеннями - оскільки справді обчислення з ними теж стає повільним.


0

У науковому співтоваристві є декілька застосувань (тобто відстань між галактиками, кількість атомів у трав'яному полі тощо)


е, не бути грубим .. але як ця відповідь стосується питання?
Pacerier

2
Питання, написане, звучить так, ніби він шукав приклад у реальному світі щодо того, чому потрібно створити такий тип даних.
Дейв Мудрий

кращою фразовою фразою було б "чи дійсно BigInteger підходить для чисел, розмірів яких становить 10 ^ 30"?
Pacerier

Для цього я б краще скористався doubleабо float- у вас все одно немає необхідної точності.
Paŭlo Ebermann

кращою фразовою фразою було б "чи дійсно BigInteger підходить для чисел, більших 10 ^ 30, коли нам потрібна точність"?
Pacerier

0

Як підказує відповідь Кевіна Клайна, BigNumbers були додані до бібліотек .NET, головним чином тому, що вони були необхідними як будівельний блок для багатьох сучасних криптографічних алгоритмів (цифрових підписів, шифрування відкритих / приватних ключів тощо). Багато сучасних криптографічних алгоритмів передбачають обчислення цілих значень з розмірами до декількох тисяч біт. Оскільки клас BigNumber описує чітко визначений та корисний клас, вони вирішили оприлюднити його (а не зберігати його як внутрішню деталь криптографічних API).


btw просто цікаво, звідки у вас джерело того, що BigNumbers додано до бібліотек .NET насамперед тому, що вони потрібні були як будівельний блок для багатьох сучасних криптографічних алгоритмів (а значить, вони повинні мати можливість підтримувати значення до кількох тисяч біт)?
Pacerier
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.