06.02.2009, 23:15
|
Прохожий
|
|
Регистрация: 30.01.2009
Сообщения: 2
Репутация: 10
|
|
Код:
program LongSum;{$APPTYPE CONSOLE}uses SysUtils;
{
Программа предназначина дла складывания чисел в пределах
+-10^30000 с учётом знака.
}
type
TByte = -9..9;
TLongExt = Record
sign: boolean;(*Положительность false - "-" true - "+" *)
(* Mantissa *)
UnitM :Array of TByte; {Целая мантисса}
CountU:Integer;{Кол-во разрядов цел}
FracM :Array of TByte; {Дробная мантисса}
CountF:Integer;{Кол-во разрядов дроб}
end;
Var A, B,{Входные данные} C{Выходные данные}:TLongExt;
q:integer;
(* =-=-=- Процедуры -=-=-= *)
procedure ReadEXT(var A:TLongExt);
var
i:integer;
S:String;
begin
Readln(s);A.sign:=(s[1]='+');
delete(s,1,1);i:=1;
While not((s[i]='.')or(s[i]=',')) do inc(i);
Setlength(A.UnitM,i-1);{-2}
A.CountU:=i-1;{-2}
For i:=0 to A.CountU-1 do
A.UnitM[i]:=StrToInt(s[A.CountU-i]);
delete(s,1,A.CountU+1);
A.CountF:=Length(S);
SetLength(A.FracM,A.CountF);
For i:=0 to A.CountF-1 do
A.FracM[i]:=StrToInt(S[i+1]);
end;
procedure WriteEXT(var A:TLongExt);
var q:Integer;
begin
if A.sign then Write('+')else Write('-');
for q:=A.CountU-1 downto 0 do
Write(A.UnitM[q]);
Write('.');
for q:=0 to A.CountF-1 do Write(A.FracM[q]);
WriteLN;
end;
procedure Align(var A, B:TLongExt);
begin
If A.CountF<>B.CountF then if A.CountF>B.CountF then
begin
B.CountF:=A.CountF;
setlength(B.FracM,B.CountF);
end
else begin
A.CountF:=B.CountF;
setlength(A.FracM,A.CountF);
end;
If A.CountU<>B.CountU then if A.CountU>B.CountU then
begin
B.CountU:=A.CountU;
setlength(B.UnitM,B.CountU);
end
else begin
A.CountU:=B.CountU;
setlength(A.UnitM,A.CountU);
end;
end;
{===== Собственно сумма =====}
procedure Summ(var A, B, C:TLongExt);
Var q:integer; // Какая-то рабочая переменная
Oct:TByte; // Остаток, без него хоть тресни
function RF(const A:TLongExt; Index:Integer):integer;
begin // Выдает разряд Index с нужным знаком
If A.sign then Result:=A.FracM[Index]
else Result:=A.FracM[Index]*(-1);
end;
function RU(const A:TLongExt; Index:Integer):integer;
begin
If A.sign then Result:=A.UnitM[Index]
else Result:=A.UnitM[Index]*(-1);
end;
begin // Начало сумма
C.sign:=true;// По умолчанию пусть будет "+"
Align(A,B); // Выравнивание
SetLength(C.FracM,A.CountF);
C.CountF:=A.CountF; Oct:=0; // Первичные установки
for q:= C.CountF-1 downto 0 do
begin // Суммирование мантиссы дробной части
Oct:=Oct+RF(A,q)+RF(B,q);
if oct<0 then begin
C.FracM[q]:= (Oct mod 10)*(-1);
C.sign:=False;
end
else C.FracM[q]:= Oct mod 10;
Oct:= Oct div 10;
end;
C.CountU:=A.CountU;
SetLength(C.UnitM,C.CountU);
for q:= 0 to C.CountU-1 do
begin // Суммирование мантиссы целой части
Oct:=Oct+RU(A,q)+RU(B,q);
if oct<0 then
begin //Остаток отрицательный в одном случае когда всё число отрицательно
C.UnitM[q]:= (Oct mod 10)*(-1);
C.sign:=False;
end
else C.UnitM[q]:= Oct mod 10;
Oct:= Oct div 10;
end;
end;// Конец сумма
begin AssignFile(Input,'LongSum.in');Reset(Input);
{Считываем данные}
ReadEXT(A);
ReadEXT(B);
CloseFile(Input);//Нас учили уберать за собой
Summ(A,B,C);
AssignFile(Output,'LongSum.out'); Rewrite(Output);
WriteEXT(C);
CloseFile(Output);//Нас учили уберать за собой
end.
Если честно то это не очень то и сложно, если умеешь складывать отрицательные числа, то это и есть разность.
Надеюсь организовать произведение сам сможешь. Если нет почитай Меньшикова, он извращался и не так. Я про Олимпиадные задачи.
Ф.Меньшиков-Оллимпиадные задачи по программирыванию
hty007
__________________
hty007
|