![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() ![]() |
![]() |
![]()
Сообщение
#1
|
|
![]() 🐓🐓🐓🐓🐓🐓🐓 Сообщений: 1 845 Спасибо сказали: 1570 раз ![]() |
Нужно реализовать деление с остатком больших чисел, но не могу разобраться в алгоритме - и читабельного не нашел к сожалению. Везде какие-то неточности, и абсурдные на мой взгляд вещи.
Во-первых, глупейший вопрос: если я для хранения больших чисел использую, к примеру, Код type TDigit = array[0..63] of dword; то наименьшему или наибольшему элементу массива логичнее хранить младшую часть числа? -------------------- using namespace fbx;
|
|
|
![]()
Сообщение
#2
|
|
![]() Etoslozhnostatus Сообщений: 8 575 Спасибо сказали: 15969 раз ![]() |
Обычно младшая часть в начальных ячейках, а старшая - в ячейках с бОльшим адресом.
Был бы ты сишник, а не паскалист - "послал" бы тебя по разным источникам. Например, http://algolist.manual.ru/maths/longnum.php -------------------- - Да ну!?
- Horn of the Argali гну! |
|
|
![]()
Сообщение
#3
|
|
![]() 🐓🐓🐓🐓🐓🐓🐓 Сообщений: 1 845 Спасибо сказали: 1570 раз ![]() |
Цитата var a,b,c: TDigit; ab mod c = ? ![]() для "Монтгомери" нужно сначала произвести деление... -------------------- using namespace fbx;
|
|
|
![]()
Сообщение
#4
|
|
![]() Etoslozhnostatus Сообщений: 8 575 Спасибо сказали: 15969 раз ![]() |
Можно поконкретнее описать, что нужно? И большая ли степень b? TDigit - целое число? Модуль c имеет какие-то особенности, например c=2N или c=2N+1?
Добавлено ([mergetime]1271183161[/mergetime]): С Монтгомери плохо знаком. -------------------- - Да ну!?
- Horn of the Argali гну! |
|
|
![]()
Сообщение
#5
|
|
![]() 🐓🐓🐓🐓🐓🐓🐓 Сообщений: 1 845 Спасибо сказали: 1570 раз ![]() |
Так вот я описал что нужно найти. Куда это вставляется сам точно не знаю. TDigit объявлен в первом посте, все три числа произвольные.
-------------------- using namespace fbx;
|
|
|
![]()
Сообщение
#6
|
|
![]() Etoslozhnostatus Сообщений: 8 575 Спасибо сказали: 15969 раз ![]() |
Всё равно не очень понятно.
Вариант: тупо умножать x="a" на "a" b-1 раз, а потом вычислить остаток от деления на "c". -------------------- - Да ну!?
- Horn of the Argali гну! |
|
|
![]()
Сообщение
#7
|
|
![]() 🐓🐓🐓🐓🐓🐓🐓 Сообщений: 1 845 Спасибо сказали: 1570 раз ![]() |
В том-то и дело, что это не вариант
![]() А вот статьи, в которых не понял смысла некоторых выражений и обозначений (похоже на опечатки, но кто знает): Деление: http://naukoved.ru/content/view/1300/45/ Монтгомери: http://dic.academic.ru/dic.nsf/ruwiki/1277680 http://naukoved.ru/content/view/1301/45/ -------------------- using namespace fbx;
|
|
|
![]()
Сообщение
#8
|
|
![]() Etoslozhnostatus Сообщений: 8 575 Спасибо сказали: 15969 раз ![]() |
Есть вариант для такого случая: после каждого умножения находить остаток от деления на "c" и потом умножать уже на него.
-------------------- - Да ну!?
- Horn of the Argali гну! |
|
|
![]()
Сообщение
#9
|
|
![]() 🐓🐓🐓🐓🐓🐓🐓 Сообщений: 1 845 Спасибо сказали: 1570 раз ![]() |
не, количество итераций умножения / деления все равно будет слишком большим.
-------------------- using namespace fbx;
|
|
|
![]()
Сообщение
#10
|
|
![]() Etoslozhnostatus Сообщений: 8 575 Спасибо сказали: 15969 раз ![]() |
Есть алгоритмы, оптимизирующие количество умножений при возведении в степень.
Например: x^16 - 15 умножений? A = x*x = x^2; B = A*A = x^4; C = B*B = x^8; D = C*C = x^16. То есть 4 умножения. Для x^31 придётся выполнить, кажется, 7 умножений. В среднем 2*log2b умножений. После каждого умножения находим остаток и потом используем его. -------------------- - Да ну!?
- Horn of the Argali гну! |
|
|
![]()
Сообщение
#11
|
|
![]() Яблочный произвол! Сообщений: 11 080 Спасибо сказали: 3988 раз ![]() |
Цитата(FBX @ 13 Apr 2010, 22:48) насколько я понял, это алгоритм компьютерного деления. еще вариант: ( a * b ) mod c = ( ( a mod c ) * ( b mod c ) ) mod c в твоем варианте: ( a ^ b ) mod c = ( ( a mod c ) ^ b ) mod c |
|
|
![]()
Сообщение
#12
|
|
![]() 🐓🐓🐓🐓🐓🐓🐓 Сообщений: 1 845 Спасибо сказали: 1570 раз ![]() |
Пришлось использовать для хранения чисел string, причем в читабельной десятичной форме. Сел сегодня, что-то сваял, для размера основания, степени и делителя по ~2048 бит программа работала 85 секунд. Если ~512 бит, то 1.5 секунд. Монтгомери ниасилил, поэтому сделал по-тупому.
Всем еще раз спасибо за помощь. -------------------- using namespace fbx;
|
|
|
![]()
Сообщение
#13
|
|
![]() допустим, мяў Сообщений: 24 070 Спасибо сказали: 13377 раз ![]() |
возведение в целую степень. быстрый алгоритм.
Код function Power (A, B: Int64): Int64; {или LongInt?} begin Result := 1; while (B > 0) do begin if (B and 1 = 1) then Result := Result * A; A := A + A; B := B shr 1; end; end; Или вот, в общем случае: Код function Power (A, B: Double): Double;
begin if (A < 0) then Result := -1 * Exp(B * Ln(Abs(A))) else if (A > 0) then Result := Exp(B * Ln(Abs(A))) else Result := 0; if (Round(B) mod 2 = 0) then Result :=Abs(Result); if (B = 0) then Result := 1; end; -------------------- Вокруг столько фильмов, книг, музыки - а природа какая невероятная!
Если тебе скучно жить - ты совсем дурак. (Татьяна Черниговская) |
|
|
![]()
Сообщение
#14
|
|
![]() Яблочный произвол! Сообщений: 11 080 Спасибо сказали: 3988 раз ![]() |
а что такое х?
|
|
|
![]()
Сообщение
#15
|
|
![]() допустим, мяў Сообщений: 24 070 Спасибо сказали: 13377 раз ![]() |
исправил.
-------------------- Вокруг столько фильмов, книг, музыки - а природа какая невероятная!
Если тебе скучно жить - ты совсем дурак. (Татьяна Черниговская) |
|
|
![]()
Сообщение
#16
|
|
![]() Яблочный произвол! Сообщений: 11 080 Спасибо сказали: 3988 раз ![]() |
xa=Пi=0∞(x-ki)ai где
aєR ai=[a'i] a'0=a a'i={a'i-1}*k Добавлено ([mergetime]1272979500[/mergetime]): Пi=0∞ - имеется ввиду произведение от 0 до бесконечности |
|
|
![]()
Сообщение
#17
|
|
Member Сообщений: 97 Спасибо сказали: 80 раз ![]() |
не умничай ))
|
|
|
![]()
Сообщение
#18
|
|
![]() Яблочный произвол! Сообщений: 11 080 Спасибо сказали: 3988 раз ![]() |
дык это способ.
Добавлено ([mergetime]1272987048[/mergetime]): можно еще в ряд Тейлора раскладывать в окрестности 1 |
|
|
![]()
Сообщение
#19
|
|
![]() 🐓🐓🐓🐓🐓🐓🐓 Сообщений: 1 845 Спасибо сказали: 1570 раз ![]() |
Как реализовать расширенный алгоритм Евклида
( http://www.cyberguru.ru/cpp-sources/algori...tm-evklida.html ) да так, чтобы Y получился гарантированно отрицательный, а X - положительный. (точнее, оба они получились положительные в формуле ax - by = НОД) -------------------- using namespace fbx;
|
|
|
![]()
Сообщение
#20
|
|
![]() Яблочный произвол! Сообщений: 11 080 Спасибо сказали: 3988 раз ![]() |
а никак. поменять a и b местами. и алгоритмы там кривые.
GCD(a, ![]() ![]() ![]() bx+(a mod ![]() Добавлено ([mergetime]1273488582[/mergetime]): код на с++ Код int gcd(int a,int b,int &x,int &y)
{ if(!b) { x=1; y=0; return a; } int res; res=gcd(b,a%b,y,x); y-=(a/b)*x; return res; } |
|
|
![]() ![]() |
Текстовая версия | Сейчас: 14 August 2025 - 14:27 |
Copyright by Алексей Крючков
![]() Programming by Degtyarev Dmitry |
|