Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Делфи _ Hugeobj

Автор: Айра 26.01.2007 19:50

Как я и обещала, очередной вопрос...
Мне нужно вычислить факториалы (до 100 хватит), как это сделать уже нашла (спасибо volvo (модуль для работы с длинной арифметикой)). Но я не знаю куда деть hugeobj.pas? без нее ведь не работает...

Объясните пожалуйста! rolleyes.gif

p.s. sorry, но таже проблема со скачанной библиотекой Crt... wink.gif

p.s.2 в Delphi ведь можно все это реализовать...

Автор: Алена 26.01.2007 20:53

Насчет HugeInt - его тоже можно скомпилировать в Дельфи (просто забрось в папку с проектом, и подключи в Uses), но для этого его придется немного поправить:

  1. Procedure Add(Const B: TLargeInt);
    и все подобные, где также используется спецификатор Const - его надо удалить;
  2. В одной из процедур могут быть проблемы с переменной цикла J - оптимизатор может с ней натворить проблем, после цикла переменная может хранить все, что угодно - а этого допустить нельзя, поэтому переделываем цикл For -> While:

    { A := A * B }
    Procedure TLargeInt.Mul(B: TLargeInt);
    Var
    C: TLargeInt;
    i, j: Index; T: Inter;
    Begin
    If GetLen - 1 > maxLen - B.GetLen Then {Overflow('Mul');}
    C.Init(0); C.SetLen(GetLen + B.GetLen - 1);
    For i := 1 To GetLen Do
    Begin
    T := 0;
    j := 1;
    // For j := 1 To B.GetLen Do
    While j <= B.GetLen Do // <--- Вот тут
    Begin
    T := C.Get(i + j - 1) + Inter(Get(i)) * B.Get(j) + T;
    C.Put(i + j - 1, T mod Base); T := T div Base;

    Inc(j); // <--- Не забываем увеличить переменную
    End;

    If T > 0 Then
    Begin
    If i + j - 1 = maxLen Then ErrorMsg(vliOverflow, 'Mul');
    C.Put(i + j, T);
    If i + j > C.GetLen Then C.SetLen(i + j)
    End
    End;

    { In case A=0 and/or B=0 }
    While (C.GetLen > 1) And (C.Get(C.GetLen) = 0) Do C.DecLen;
    Self := C
    End;

Все остальное в принципе должно работать.

Насчет CRT - смотри в http://forum.pascal.net.ru/index.php?showtopic=6361: "Системные функции и WinAPI" -> "Windows" -> "Консольные приложения" -> "CRT для консольного приложения"

Автор: Айра 26.01.2007 21:47

Большое спасибо, Алена!!! Ты снова меня спасаешь! give_rose.gif

Автор: Айра 27.01.2007 1:54

Эх... Все-таки возникла у меня проблемка... wink.gif

procedure TForm6.Button1Click(Sender: TObject);
var f: TLargeInt; n: longint;
begin
n:=StrToInt(edit1.Text);
fact(f, n);
edit2.Text:=IntToStr(f); //эта строка непроходит
end;

Можете объяснить как это исправить?

Автор: Алена 27.01.2007 2:08

Добавить в объект TLargeInt еще один метод (в описание типа тоже, не забудь):

Function TLargeInt.HugeToStr: String;
Var
i: Index; k: Digit; s: String;
begin
result := '';

Str(Base - 1, s); k := Length(s);
result := result + IntToStr(GetLast);
For i := GetLen - 1 DownTo 1 Do Begin
Str(Get(i), s);
While Length(s) < k Do s := '0' + s;
result := result + DigitSep + s;
End
end;
, естественно в Uses у модуля HugeObj прописывается SysUtils (чтобы IntToStr могла работать), и вызывать так:
procedure TForm1.Button4Click(Sender: TObject);
var f: TLargeInt; n: longint;
begin
n:=StrToInt(edit1.Text);
fact(f, n);
edit2.Text:=f.HugeToStr; // Это работает, проверено...
end;

Автор: Айра 27.01.2007 2:47

Спасиибо!, но я похоже что-то не так делаю, т.к. Delphi то на "TLargeInt", то на "HugeToStr" Undeclared identifier'ом обзывается...

У меня объект TLargeInt только в HugeObj'е есть:


Type
TArrItem = 0 .. max;

VLIError = (vliOverflow, vliNegative);

TLargeInt =
Object
Public
Constructor Init(x: LongInt);

Function TLargeInt.HugeToStr: String; // сюда, если я правильно поняла
Function Cmp(B: TLargeInt): Integer;
Function CmpDigit(x: Digit): Integer;
...


Автор: Алена 27.01.2007 2:51

  TLargeInt =
Object
Public
Constructor Init(x: LongInt);


Function HugeToStr: String; // <--- правильно поняла, только ...
Function Cmp(B: TLargeInt): Integer;
Function CmpDigit(x: Digit): Integer;
...


... название класса не надо внутри самого класса дублировать... В реализации - да, но не в описании smile.gif

Автор: Айра 27.01.2007 3:34

Ура! Все работает! Спасибо тебе огромное!!! give_rose.gif

Цитата
название класса не надо внутри самого класса дублировать

wink.gif теперь на всю жизнь запомню...

Но возник последний вопрос: есть ли у Edit'а что-нибудь наподобе AutoSize (числа то не маленькие получилисьsmile.gif ), если нет, то процедуру я сама напишу.

p.s. Эх... Как же плохо быть самоучкой...

Автор: Алена 27.01.2007 3:46

Цитата
есть ли у Edit'а что-нибудь наподобе AutoSize
Почему "наподобие"? Есть же именно AutoSize...

А вообще-то я бы не пользовалась Edit-ом, лучше Memo.

Автор: Айра 27.01.2007 3:57

Я не нашла. В свойствах только вручную задавать предлагалось.
А вот memo - это не мысль, это - идея!
Еще раз спасибо, Алена!

Автор: Гость 23.10.2007 2:01

Очень всё интересно и полезно, но как сделать операцию по модулю длинного числа с длинным?
У меня пока на получилось.