Вобщем принялся сам реализовывать эти функции...
Для начала принял некоторые правила:
1. Операции делаю над десятичными числами.
2. Храню числа в динамическом массиве (элементы типа byte) - каждая цифра (0..9) занимает один элемент массива и по принцыпу: младший разряд по младшему адресу.
3. Последний элемент всегда хранит значение знака + или -. Реализовал через константы sgPlus, sgMinus.
4. Операции намерен делать столбиком. Проще пока не придумал. Пока есть тока функция ZAdd складывающая два массива без знака. Знак будет учитыватся в функции SZAdd где будет происходить коррекция и вызыватся ZAdd или ZSub.
5. Число получаю с переменной типа String. Реализовал через функции StrToZ и обратную ей ZToStr.
Ниже привожу код с пояснениями:
константы знаков в последнем элементе:
Код:
Const
sgPlus = 100; //<=> +
sgMinus = 101; //<=> -
для уменьшения писанины и заморочек компилятора:
функции конвертирования из текста в число и обратно:
Код:
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;
помагите реализовать функцию вычитания. Лучше в столбик, чтобы понятней было. А раз столбиком, то я понимаю, что надо отнимать меньшее значение от большего. Допустим, я напишу функцию сравнения... А дальше как? Алгоритм пожалуста. Код уже сам напишу или свой дайте.
Заранее благодарен!