Вопрос № 166315: Здравствуйте. Нужна помощь в создании программы, т.к. в интернете я ничего дельного не нашёл на Pascal'е, а программу необходимо написать именно на нём: Необходимо составить программу, которая выполняет перевод из десятичной системы счислен...
Вопрос № 166.315
Здравствуйте. Нужна помощь в создании программы, т.к. в интернете я ничего дельного не нашёл на Pascal'е, а программу необходимо написать именно на нём: Необходимо составить программу, которая выполняет перевод из десятичной системы счисления в двоичную, выполняет над числами сложение или вычитание(в двоичной системе) с дополнительным кодом и переводит полученный результат обратно в десятичную систему счисления. Форма представления исходной записи и результатов: целые числа со знаком. Задача
не из простых, согласен, но обещаю что в долгу не останусь.
Отвечает: Бизин Михаил Анатольевич
Здравствуйте, Нестеров Артём Валерьевич! Код в приложении.
Пример работы: Enter D1: 200 200 = 11001000 Enter D2: 150 150 = 10010110 11001000 + 10010110 = 101011110 = 350 11001000 - 10010110 = 110010 = 50
и ещё: Enter D1: 0 0 = 0 Enter D2: 1 1 = 1 0 + 1 = 1 = 1 0 - 1 = 11111111111111111111111111111111 = -1 - для FreePascal:
Код:
program q166146;
const BITS = 32; //Размерность чисел
function IntToBin(dec: longint): string; var i: integer; begin if dec=0 then begin IntToBin:='0'; Exit; end; SetLength(IntToBin,BITS); for i:=BITS downto 1 do begin IntToBin[i]:=Chr((dec and 1)+48); dec:=dec shr 1; end; Delete(IntToBin,1,Pos('1'
,IntToBin)-1); //Убрать впередистоящие нули end;
function BinToInt(bin: string): longint; var i: integer; begin BinToInt:=0; For i:=1 to Length(bin) do begin BinToInt:=BinToInt shl 1; //Сдвиг всех битов влево if bin[i]='1' then BinToInt:=BinToInt or 1; //Если встретилась 1, то вставить её в число end; end;
function SumBits(b1,b2: char; var c: byte): char; //c - бит переноса var Sum: byte; begin Sum:=Ord(b1)-48+Ord(b2)-48+c; SumBits:=Chr(Sum
mod 2 + 48); c:=Sum div 2; //бит переноса end;
{ ---------- Сложение -------------- } function BinsAdd(bin1,bin2: string): string; var i: integer; Perenos: byte; begin { Для сложения и вычитания нужно выровнить все строки } for i:=1 to BITS-Length(bin1) do bin1:='0'+bin1; for i:=1 to BITS-Length(bin2) do bin2:='0'+bin2; SetLength(BinsAdd,BITS); Perenos:=0; { Цикл сложения } for i
:=BITS downto 1 do BinsAdd[i]:=SumBits(bin1[i], bin2[i], Perenos); Delete(BinsAdd,1,Pos('1',BinsAdd)-1); //Убрать впередистоящие нули end;
{ ---------- Вычитание ------------- } { Вычитание делается инверсией вычитаемого, потом сложением, потом + 1} { c = b - a = b + inv(a) + 1 } function BinsSub(bin1,bin2: string): string; //Возвращает bin1-bin2 var i: integer; Perenos: byte; begin { Для сложения и вычитания нужно выровнить все строки } for i:=1
to BITS-Length(bin1) do bin1:='0'+bin1; for i:=1 to BITS-Length(bin2) do bin2:='0'+bin2; SetLength(BinsSub,BITS); for i:=1 to BITS do //Цикл инверсии if bin2[i]='0' then bin2[i]:='1' else bin2[i]:='0'; Perenos:=1; //Сразу добавим 1 { Цикл сложения } for i:=BITS downto 1 do BinsSub[i]:=SumBits(bin1[i], bin2[i], Perenos); Delete(BinsSub,1,Pos('1',BinsSub)-1); //Убрать впередисто
ящие нули end;
function IntToBin(dec: longint): string; var i: int
eger; res: string; begin if dec=0 then begin IntToBin:='0'; Exit; end; SetLength(res,BITS); for i:=BITS downto 1 do begin res[i]:=Chr((dec and 1)+48); dec:=dec shr 1; end; Delete(res,1,Pos('1',res)-1); //Убрать впередистоящие нули IntToBin:=res; end;
function BinToInt(bin: string): longint; var i: integer; res: longint; begin res:=0; For i:=1 to Length(bin) do begin res:=res shl 1; //Сдвиг всех битов
влево if bin[i]='1' then res:=res or 1; //Если встретилась 1, то вставить её в число end; BinToInt:=res; end;
function SumBits(b1,b2: char; var c: byte): char; //c - бит переноса var Sum: byte; begin Sum:=Ord(b1)-48+Ord(b2)-48+c; SumBits:=Chr(Sum mod 2 + 48); c:=Sum div 2; //бит переноса end;
{ ---------- Сложение -------------- } function BinsAdd(bin1,bin2: string): string; var i: integer; P
erenos: byte; res: string; begin { Для сложения и вычитания нужно выровнить все строки } for i:=1 to BITS-Length(bin1) do bin1:='0'+bin1; for i:=1 to BITS-Length(bin2) do bin2:='0'+bin2; SetLength(res,BITS); Perenos:=0; { Цикл сложения } for i:=BITS downto 1 do res[i]:=SumBits(bin1[i], bin2[i], Perenos); Delete(res,1,Pos('1',res)-1); //Убрать впередистоящие нули BinsAdd:=res; end;
{ ---------- Вычитание -------------
} { Вычитание делается инверсией вычитаемого, потом сложением, потом + 1} { c = b - a = b + inv(a) + 1 } function BinsSub(bin1,bin2: string): string; //Возвращает bin1-bin2 var i: integer; Perenos: byte; res: string; begin { Для сложения и вычитания нужно выровнить все строки } for i:=1 to BITS-Length(bin1) do bin1:='0'+bin1; for i:=1 to BITS-Length(bin2) do bin2:='0'+bin2; SetLength(res,BITS); for
i:=1 to BITS do //Цикл инверсии if bin2[i]='0' then bin2[i]:='1' else bin2[i]:='0'; Perenos:=1; //Сразу добавим 1 { Цикл сложения } for i:=BITS downto 1 do res[i]:=SumBits(bin1[i], bin2[i], Perenos); Delete(res,1,Pos('1',res)-1); //Убрать впередистоящие нули BinsSub:=res; end;
Второй вариант кода перенесён из мини-форума.
--------
∙ Отредактировал: sir Henry, Академик
∙ Дата редактирования: 03.05.2009, 05:41 (время московское)
type TDecimal=LongInt; { Тип который будет приводиться к TBinaryNumber } TBinary=0..1; { Диапазон двоичных значений } const CHighBound=sizeof(TDecimal)*8-1;{ Верхний
индекс } type TBounds=0..CHighBound; { Диапазон индексов } { Объект двоичное число } TBinaryNumber=object public constructor Init(num:TDecimal); { Конструктор } function ToLongInt:LongInt; { Преобразование к LongInt } function ToString:String; { преобразование к String } private binArray:array[TBounds] of TBinary; { Здесь будем хранить число } end;
constructor TBinaryNumber.I
nit(num:TDecimal); var i:TBounds; begin { Разложим число на биты } for i := 0 to CHighBound do begin binArray[i]:=num and 1; num:=num shr 1; end; end;
{ Сложение двух чисел } procedure BinaryNumberAdd(num1,num2:TBinaryNumber;var res:TBinaryNumber); var carry:TBinary; i:TBounds; tmp:Integer; begin carry:=0; { Перенос } for i := 0 to CHighBound do begin tmp:=num1.binArray[i]+num2.binArray[i]+carry; res.binArray[i]:=tmp and 1; carry:=tmp
shr 1; end; end;
{ Вычитание } procedure BinaryNumberSub(num1,num2:TBinaryNumber;var res:TBinaryNumber); var carry:TBinary; i:TBounds; tmp:Integer; begin carry:=1; for i := 0 to CHighBound do begin tmp:=num1.binArray[i]+((not num2.binArray[i]) and 1)+carry; res.binArray[i]:=tmp and 1; carry:=tmp shr 1; end; end;
function TBinaryNumber.ToLongInt:LongInt; var i:TBounds; res:Lo
ngInt; begin res:=0; for i := CHighBound downto 0 do res:=(res shl 1) or binArray[i]; ToLongInt:=res; end;
function TBinaryNumber.ToString:String; var res,tmp:String; i:TBounds; begin res:=''; { Пропускаем ведущие нули } i:=CHighBound; while i>0 do begin if binArray[i]<>0 then break; Dec(i); end; { Остальное выводим } Inc(i); while i>0 do begin Dec(i); str(binArray[i],tmp); res:=res+tmp; end; ToString:=res; end;
var Bnum1,Bnum2,Bnum3:TBinaryNumber; num1,num2:LongInt; begin Write('num1='); ReadLn(num1); Bnum1.Init(num1); Write('num2='); ReadLn(num2); Bnum2.Init(num2); BinaryNumberAdd(Bnum1,Bnum2,Bnum3); WriteLn('num1+num2=',Bnum1.ToString,'+',Bnum2.ToString,'=',Bnum3.ToString,'=',Bnum3.ToLongInt); BinaryNumberSub(Bnum1,Bnum2,Bnum3); WriteLn(&
#39;num1-num2=',Bnum1.ToString,'-',Bnum2.ToString,'=',Bnum3.ToString,'=',Bnum3.ToLongInt); ReadLn; end.
* Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи.
(полный список тарифов)
** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
*** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.