| 
| 
 | Вопрос # 3 759/ вопрос открыт / | 
 |  Доброго времени суток, уважаемые эксперты!Попалась задачка, думал легкая, однако повозился значительно, может и для вас покажется интересной.
 Задача проста найти факториал 2010.
 Все известные типы чисел неподдерживают такое количество символов. В голову пришло считать разрядно т.е:
 если 1ый разряд, состоящий из 9ти символов, переполняется то переполняемую единицу переношу во второй разряд  и т.д
 I1:=I1*I;
 if I1 div 1000000000>0 then
 begin
 I2:= I2*I+(I1 div 1000000000);
 I1:=I1 mod 1000000000;
 if I2 div 100000000>0 then ...
 все это внутри цикла i:=0 to 2010, I1..I12 -12 9ти разрядных(в моем случае) числел. Алгоритм вроде вернуый но после 40! заходит в 0 хотя предел в 12*9 символов не пройден, ошибок в нем нет(все повторяется подобно).
 Подумал, может тут помогут, да и вообще заинтересует эта задача=) Спасибо.
 З.Ы второй алгоритм выглядет более компактно но почему то условие игнорируется даже при True значении, тут надеюсь подскажите мой косяк в процедуре.
 Приложение:Переключить в обычный режим procedure TForm3.Button1Click(Sender: TObject);varI1,I2,I3,I4,I5,I6,I7,I8,I9,I10,I11,I12:int64;I,S:integer;St:string;beginI1:=1;I2:=0;I3:=0;I4:=0;I5:=0;I6:=0;I7:=0;I8:=0;I9:=0;I10:=0;I11:=0;I12:=0;for i := 1 to 2022 do  begin    I1:=I1*I;     if I1 div 1000000000>0 then       begin       I2:= I2*I+(I1 div 1000000000);       I1:=I1 mod 1000000000;       if I2 div 100000000>0 then        begin       I3:= I3*I+(I2 div 1000000000);         I2:=I2 mod 1000000000;        if I3 div 100000000>0 then        begin        I4:= I4*I+(I3 div 1000000000);         I3:=I3 mod 1000000000;        if I4 div 100000000>0 then        begin        I5:= I5*I+(I4 div 1000000000);          I4:=I4 mod 1000000000;        if I5 div 100000000>0 then        begin        I6:= I6*I+(I5 div 1000000000);         I5:=I5 mod 1000000000;        if I6 div 100000000>0 then        begin        I7:= I7*I+(I6 div 1000000000);         I6:=I6 mod 1000000000;        if I7 div 100000000>0 then        begin        I8:= I8*I+(I7 div 1000000000);         I7:=I7 mod 1000000000;        if I8 div 100000000>0 then        begin        I9:= I9*I+(I8 div 1000000000);          I8:=I8 mod 1000000000;        if I9 div 100000000>0 then        begin        I10:= I10*I+(I10 div 1000000000);         I9:=I9 mod 1000000000;        if I10 div 100000000>0 then        begin        I11:= I11*I+(I10 div 1000000000);         I10:=I10 mod 1000000000;        if I11 div 100000000>0 then        I12:= I12*I+(I11 div 1000000000);           I11:=I11 mod 1000000000;        end;        end;        end;        end;        end;        end;        end;        end;       end;       Edit1.Text:=Inttostr(I1);       Edit2.Text:=Inttostr(I2);       Edit3.Text:=Inttostr(I3);       Edit4.Text:=Inttostr(I4);       Edit5.Text:=Inttostr(I5);       Edit6.Text:=Inttostr(I6);       Edit7.Text:=Inttostr(I7);       Edit8.Text:=Inttostr(I8);       Edit9.Text:=Inttostr(I9);       Edit10.Text:=Inttostr(I10);       Edit11.Text:=Inttostr(I11);       Edit12.Text:=Inttostr(I12);       memo1.Lines.Add(Edit6.Text+Edit5.Text+Edit4.Text+Edit3.Text+Edit2.Text+Edit1.Text);       end;  end;  procedure TForm3.TryAnother;varT:array [1..11] of integer;i,x,tc:integer;str:string;beginT[1]:=1;for x := 2 to 11 do  begin    T[x]:=0;  end;for i := 1 to 20 do begin for tc := 0 to 10 do     T[1]:=T[1]*I;       if (T[tc] div 1000000000)>0 then       begin       T[TC+1]:= T[tc+1]*I+(T[TC] div 1000000000);       T[Tc]:=T[tc] mod 1000000000;       end; end;for x := 0 to 11 dobeginStr:=str+(inttostr(T[11-x]));memo1.Text:=str;end;
|  |   Вопрос задал: TeM (статус: Посетитель)Вопрос отправлен: 11 февраля 2010, 22:01
 Состояние вопроса: открыт, ответов: 1.
 |  Ответ #1. Отвечает эксперт: min@y™ Вот тебе решение: модуль для работы с большими числами.
 Цитата: Это модуль для работы с очень большими числами без потери точности. Модуль даёт возможность манипулирования с 10000 и более значащими цифрами в числах. В модуле реализованы сложение, вычитание, умножение, деление, возведение в целую степень и факториал. Все функции в качестве аргументов принимают длинные строки и результат выдают тоже в виде строки.
 
 
|  | Ответ отправил: min@y™ (статус: Доктор наук)Время отправки: 12 февраля 2010, 08:25
 Оценка за ответ: 4
 Комментарий к оценке: Недумал что эта тема есть в FAQ, спс |  
 Мини-форум вопросаВсего сообщений: 3; последнее сообщение — 12 февраля 2010, 10:53; участников в обсуждении: 3. 
|   | Мережников Андрей (статус: Абитуриент), 12 февраля 2010, 05:45 [#1]:решение этой задачи рассматривалось в журнале "Квант" году этак в 1988. Для хранения больших чисел использовались строковые переменные. |  
|   | Егор (статус: 10-ый класс), 12 февраля 2010, 06:21 [#2]: Цитата (TeM): I1,I2,I3,I4,I5,I6,I7,I8,I9,I10,I11,I12:int64;в те далёкие-далёкие времена, когда люди ещё не изобрели массивы......
 I1:=1;
 I2:=0;
 I3:=0;
 I4:=0;
 I5:=0;
 I6:=0;
 I7:=0;
 I8:=0;
 I9:=0;
 I10:=0;
 I11:=0;
 I12:=0;
 
 или навеяно моим ответом на вопрос вопрос 3718?
 Опасайтесь багов в приведенном выше коде; я только доказал корректность, но не запускал его.— Donald E. Knuth.
 |  
|   | TeM (статус: Посетитель), 12 февраля 2010, 10:53 [#3]:Егор, первый алгоритм расписан полностью чтобы проследить наличие всевоззможных ошибок, если посмотреть второй алгоритм, то в нем видна и работа с массивом и решение "нагруженности" кода. Андрей, в 1988 году небыло у меня журналов вообще=)Хранить в строковых переменных конечно можно, но как же потом с ними работать если длина числового значения всеравно лимитирована(только если по частям из строки выбирать числа и их перемножать замещая ответом умноженные величины?).
 Min@y™, спасибо, сейчас попробую разобраться.
 |  Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |