![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#6
|
|||
|
|||
![]() Код:
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 |