Program Nub;
 uses crt;
 const k=16;
 type mashslovo=array[1..k] of 0..1;
 var OP1,OP2,S,R:mashslovo;
     CF1,OF1,SF1,ZF1,CF2,OF2,SF2,ZF2:0..1;
     x,y,pk,SZ1,SZ2,SZ3,SZ4,BZ1,BZ2,BZ3,BZ4,max,min,k1,i:longint;

 procedure ADD;
 var i:longint; d:0..3;
 begin
      CF1 := 0;
      ZF1 := 1;
      for i := k1 downto 1 do
      begin
           d := OP1[i] + OP2[i] + CF1;
           S[i] := d mod 2;
           CF1 := d div 2;
           if S[i]=1 then ZF1 :=0
      end;
      SF1 := S[1];
      if (OP1[1]=OP2[1])and(S[1]<>OP1[1]) then OF1 := 1 else OF1 := 0
 end;

 procedure SUB;
 var i:longint; d1:-2..1;
 begin
      CF2 := 0; ZF2 := 1;
      for i := k1 downto 1 do
      begin
           d1 := OP1[i] - OP2[i] - CF2;
           if d1=-1 then
              begin
                   CF2 := 1;
                   R[i] := 1;
              end;
           if d1=-2 then R[i] := 0;
           if d1=0 then
              begin
                   R[i] := 0;
                   CF2 := 0;
              end;
           if d1=1 then R[i] := 1;
           if R[i]=1 then ZF2 :=0
      end;
      SF2 := R[1];
      if (OP1[1]<>OP2[2])and(R[1]=OP2[1]) then OF2 := 1 else OF2 := 0
 end;

 function Numb(OP:mashslovo):longint;
 var i,x,k2:longint;
 begin
      k2 := 1; x := 0;
      for i := k1 downto 1 do
          begin
               x := x + k2 * OP[i];
               k2 := k2 * 2;
          end;
      numb := x
 end;

 begin
      ClrScr;

      Window (0,0,20,3);
      {Вводим и обрабатываем k1}
      writeln('Enter k from [2..16]');
      readln(k1);
      if (k1>16)or(k1<2) then
         begin
              ClrScr;
              TextColor(5+128);
              writeln('Smert programe');
              readln;
              readln;
              exit
         end;

      max := 1;
      min := 1;
      for i := 1 to k1 do
         max := max*2;
      min := Round((max/2))*(-1);
      max := max-1;

      Window (0,3,40,6);
      {Вводим и обрабатываем первое число}
      writeln('Enter first number from [',min,'..',max,']');
      readln(x);
      if (x>max)or(x<min) then
         begin
              ClrScr;
              TextColor(5+128);
              writeln('Smert programe');
              readln;
              readln;
              exit
         end;

      {переводим первое число в двоичный вид}
      if x<0 then
         begin
              pk := 1;
              for i:=1 to k1 do
              pk := pk*2;
              x := pk + x;
         end;
      for i := k1 downto 1 do
          begin
               OP1[i] := x mod 2;
               x := x div 2;
          end;

      Window (0,6,40,9);
      {Вводим и обрабатываем второе число}
      writeln('Enter second number from [',min,'..',max,']');
      readln(y);
      if (y>max)or(y<min) then
      begin
           ClrScr;
           TextColor(5+128);
           writeln('Smert programe');
           readln;
              readln;
           exit
      end;
      {переводим второе число в двоичный вид}
      if y<0 then
         begin
              pk := 1;
              for i:=1 to k1 do
              pk := pk*2;
              y := pk + y;
         end;
      for i := k1 downto 1 do
          begin
               OP2[i] := y mod 2;
               y := y div 2;
          end;

       ADD;
       SUB;

      {Получаем б/зн числа из ОП1 и ОП2}
      BZ1 := Numb(OP1);
      BZ2 := Numb(OP2);
      BZ3 := Numb(S);
      BZ4 := Numb(R);

      {Получаем c/зн числа ОП1, ОП2}
      pk := 1;
      for i:=1 to k1 do
          pk := pk*2;
      if OP1[1]=1 then SZ1 := (-1)*(pk - Numb(OP1)) else SZ1 := Numb(OP1);
      if OP2[1]=1 then SZ2 := (-1)*(pk - Numb(OP2)) else SZ2 := Numb(OP2);
      if S[1]=1 then SZ3 := (-1)*(pk - Numb(S)) else SZ3 := Numb(S);
      if R[1]=1 then SZ4 := (-1)*(pk - Numb(R)) else SZ4 := Numb(R);
      Window (0,9,17,14);
      writeln('Addition');
      for i:=1 to k1 do
      write(OP1[i]);
      writeln;
      for i:=1 to k1 do
      write(OP2[i]);
      writeln;
      for i:=1 to k1 do
      write(S[i]);
      writeln;

      Window (0,14,30,16);
      writeln('CF=',CF1,' OF=',OF1,' SF=',SF1,' ZF=',ZF1);

      Window (0,16,30,19);
      write('Rezult b/zn');
      if CF1=1 then writeln (' false') else writeln(' true');
      write('Rezult s/zn');
      if OF1=1 then writeln(' false') else writeln(' true');

      Window (0,19,20,22);
      writeln('Continuing to work "Enter"');
      writeln('Finish "Esc"');

      Window (17,7,27,11);
      writeln('s/zn');
      write(SZ1);
      writeln;
      write(SZ2);
      writeln;
      write(SZ3);
      writeln;

      Window (27,7,37,11);
      writeln('b/zn');
      write(BZ1);
      writeln;
      write(BZ2);
      writeln;
      write(BZ3);
      writeln;
      
      Window (37,7,54,11);
      writeln('Subtract');
      for i:=1 to k1 do
      write(OP1[i]);
      writeln;
      for i:=1 to k1 do
      write(OP2[i]);
      writeln;
      for i:=1 to k1 do
      write(R[i]);
      writeln;

      Window (37,11,60,12);
      writeln('CF=',CF2,' OF=',OF2,' SF=',SF2,' ZF=',ZF2);

      Window (37,12,60,15);
      write('Rezult b/zn');
      if CF2=1 then writeln (' false') else writeln(' true');
      write('Rezult s/zn');
      if OF2=1 then writeln(' false') else writeln(' true');

      Window (54,7,64,11);
      writeln('s/zn');
      write(SZ1);
      writeln;
      write(SZ2);
      writeln;
      write(SZ4);
      writeln;

      Window (64,7,74,11);
      writeln('b/zn');
      write(BZ1);
      writeln;
      write(BZ2);
      writeln;
      write(BZ4);
      readln;
      readln

 end.
