Показать сообщение отдельно
  #5  
Старый 06.03.2008, 00:49
Navi1982 Navi1982 вне форума
Прохожий
 
Регистрация: 28.01.2008
Сообщения: 12
Репутация: 10
По умолчанию

Вобщем принялся сам реализовывать эти функции...

Для начала принял некоторые правила:
1. Операции делаю над десятичными числами.
2. Храню числа в динамическом массиве (элементы типа byte) - каждая цифра (0..9) занимает один элемент массива и по принцыпу: младший разряд по младшему адресу.
3. Последний элемент всегда хранит значение знака + или -. Реализовал через константы sgPlus, sgMinus.
4. Операции намерен делать столбиком. Проще пока не придумал. Пока есть тока функция ZAdd складывающая два массива без знака. Знак будет учитыватся в функции SZAdd где будет происходить коррекция и вызыватся ZAdd или ZSub.
5. Число получаю с переменной типа String. Реализовал через функции StrToZ и обратную ей ZToStr.

Ниже привожу код с пояснениями:
константы знаков в последнем элементе:
Код:
Const
  sgPlus  = 100; //<=> +
  sgMinus = 101; //<=> -
для уменьшения писанины и заморочек компилятора:
Код:
type
  TZ = array of byte;
функции конвертирования из текста в число и обратно:
Код:
Function StrToZ(s:string):TZ;
{Ссначала проверяет наличие знака. Если отсувствует, значит добавляет "+" по умолчанию.
Все остальные знаки считает цифрами. Другие знаки принимает за "0"}
var
 num:TZ;
 i,j,len:Integer;
begin
 case s[1] of
 '-': begin len:=length(s); SetLength(num,len); num[len-1]:=sgMinus; end;
 '+': begin len:=length(s); SetLength(num,len); num[len-1]:=sgPlus; end;
 else begin len:=length(s)+1; SetLength(num,len); num[len-1]:=sgPlus; end;
 end;
 i:=2-(len-length(s)); j:=len-2;
 while i <= length(s) do
 begin
   case s[i] of
    '0': num[j]:=0;
    '1': num[j]:=1;
    '2': num[j]:=2;
    '3': num[j]:=3;
    '4': num[j]:=4;
    '5': num[j]:=5;
    '6': num[j]:=6;
    '7': num[j]:=7;
    '8': num[j]:=8;
    '9': num[j]:=9;
   else
    num[j]:=0;
   end;
   i:=i+1; j:=j-1;
 end;
StrToZ:=num;
end;
Код:
Function ZToStr(num:TZ):String;
var
 s:String;
 j,len:Integer;
begin
 s:='';
 len:=length(num);
 j:=len-1;
 while j >= 0 do
 begin
   case num[j] of
    0: s:=s+'0';
    1: s:=s+'1';
    2: s:=s+'2';
    3: s:=s+'3';
    4: s:=s+'4';
    5: s:=s+'5';
    6: s:=s+'6';
    7: s:=s+'7';
    8: s:=s+'8';
    9: s:=s+'9';
    sgMinus: s:=s+'-';
    sgPlus : s:=s+''; //s:=s+'+';
   end;
   j:=j-1;
 end;
ZToStr:=s;
end;
Для выравнивания 2 массивов под максимальное количество знаков путём добавления нулей:
Код:
Procedure AdjustZ(n1,n2:TZ);
Var
 sign1,sign2:byte;
 i,len1,len2:Integer;
begin
 len1:=length(n1);
 sign1:=n1[len1-1];
 len2:=length(n2);
 sign2:=n2[len2-1];
 if len1<len2 then
 begin
  SetLength(n1,len2);
  n1[len2-1]:=sign1; //return sign back
 end;
 if len2<len1 then
 begin
  SetLength(n2,len1);
  n2[len1-1]:=sign2; //return sign back
 end;
end;
Для удаления лишних нулей:
Код:
Function SimplifyZ(num:TZ):TZ;
Var
 sign:byte;
 i,len:Integer;
begin
 len:=length(num);
 sign:=num[len-1];
 i:=len-2;
 while num[i]=0 do
 begin
  i:=i-1;
 end;
 len:=i+2;
 SetLength(num,len);
 num[len-1]:=sign;
SimplifyZ:=num;
end;
Функция сложения двух массивов, результат помещаем в третий, т.е. возращается функцией... Знак здесь не учитывается!
Код:
Function ZAdd(n1,n2:TZ):TZ;
Var
 r:TZ;
 t1,t2,t,mem:Shortint;
 i,len:integer;
begin
 AdjustZ(n1,n2);
 len:=length(n1);
 SetLength(r,len);
 i:=0; mem:=0;
 while i <= len-2 do
 begin
  t1:=n1[i]; t2:=n2[i];
  t:=t1+t2+mem;
  r[i]:=t mod 10;
  mem:=t div 10;
  i:=i+1;
 end;
 while mem>0 do
 begin
  SetLength(r,len+1);
  t:=mem;
  r[i]:=t mod 10;
  mem:=t div 10;
  i:=i+1;
 end;
 r[high(r)]:=sgPlus;
ZAdd:=r;
end;

помагите реализовать функцию вычитания. Лучше в столбик, чтобы понятней было. А раз столбиком, то я понимаю, что надо отнимать меньшее значение от большего. Допустим, я напишу функцию сравнения... А дальше как? Алгоритм пожалуста. Код уже сам напишу или свой дайте.

Заранее благодарен!
Ответить с цитированием