Форум программистов, компьютерный форум, киберфорум
Наши страницы
Pascal (Паскаль)
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.88/8: Рейтинг темы: голосов - 8, средняя оценка - 4.88
IOFEE
0 / 0 / 1
Регистрация: 06.04.2015
Сообщений: 5
1

Умножение двоичных чисел в дополнительном коде

06.04.2015, 21:38. Просмотров 1610. Ответов 11
Метки нет (Все метки)

Нужно написать программу для умножения двоичных чисел в дополнительном коде, чтобы каждое действие выводилось на экран(или отдельный файл).
Может, у кого-то есть эта программка или возможно написать?

Есть программа с делением в обратном коде, но как под умножение переделать понятия не имею..
Кликните здесь для просмотра всего текста

Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
type string17 = string[17];
 
function abs(x : smallint) : smallint;
begin
  if (x < 0) then x := (not x) + 1;
  abs := x;
end;
 
 
function CharToInt (c : char) : smallint;
begin
  CharToInt := ord(c) - ord('0');
end;
 
function ReadNum() : smallint;
var i, x, posStart, sign : smallint;
                     str : string;
begin
  readln(str);
  
  posStart := 1;
  sign := 1;
  
  if ((str[1] = '-') or (str[1] = '+')) then
  begin
    posStart := 2;
    if (str[1] = '-') then sign := -1;
  end;
 
  x := 0;
  for i := posStart to Length(str) do
    x := x*10 + CharToInt(str[i]);
 
  ReadNum := x * sign;
end;
 
 
function LongToBin (n : smallint; directCode : boolean) : string17;
var s : string17;
    i : byte;
begin
  s:='0|111111111111111';
  
  if (n < 0) then
  begin
    s[1]:='1';
    if (directCode) then n:= abs(n);
  end;
 
  for i:= 17 downto 3 do
  begin
    if (n = (n shr 1 shl 1)) then s[i] := '0';
    n := n shr 1;
  end;
  
  LongToBin := s;
end;
 
procedure Overflow (var R : smallint; Rlast : smallint);
begin
  if ((R >= 0) and ((Rlast < 0) or ((Rlast>=0) and (R<Rlast))))
    then R := R+1;
end;
 
 
var A,B,Bn, R,Z, Rlast : smallint;
                    ex : boolean;
 
begin
  writeln('Input numbers A/B:');
  write('A = '); A := ReadNum();
  write('B = '); B := ReadNum();
  
  writeln('Result recorded in file "out.txt"');
  
  assign(output, 'out.txt'); rewrite(output);
 
  writeln('A = ', A);
  writeln('B = ', B);
  
  if (B = 0) then
  begin
    writeln(#13#10, 'Error: B=0');
    exit;
  end;
 
  writeln(#13#10, 'Прямой код:');
  writeln(' A = ', LongToBin(A, true) );
  writeln(' B = ', LongToBin(B, true) );
  
  writeln(#13#10, 'Обратный код:');
  if (A < 0) then A := not abs(A);
  if (B < 0) then B := not abs(B);
  writeln(' A = ', LongToBin(A, false));
  writeln(' B = ', LongToBin(B, false));
 
  Bn := not B;
  writeln('-B = ', LongToBin(Bn, false));
 
  writeln(#13#10, 'Деление A на B без восстановления остатка:');
 
  Z := 0;  writeln('Z = ', LongToBin(Z, false));
  R := A;
  ex := false;
  while (not ex) do
  begin
    write('R = ', LongToBin(R, false));
    Rlast:=R;
    if (A xor B >= 0) then begin R := R+Bn; writeln('  R := R-B',#13#10,'  + ', LongToBin(Bn, false)); end
                      else begin R := R+B;  writeln('  R := R+B',#13#10,'  + ', LongToBin(B,  false)); end;
    Overflow(R, Rlast);
    write('  = ', LongToBin(R, false));
 
    if ((not R) = 0) then
    begin
      Z := Z+1;
      writeln('  R ~ 0 --> Z := Z+1 | Z = ', LongToBin(Z, false));
      ex := true;
    end
    else
    if (Rlast xor R >= 0) then
    begin
      Z := Z+1;
      if (R < 0) then write('  R < 0') else write('  R >= 0');
      writeln(' --> Z := Z+1 | Z = ', LongToBin(Z, false));
    end
    else
      ex := true;
  end;
  
  writeln(#13#10, 'Результат:');
  writeln('Z = ', LongToBin(Z, false));
 
  if (A xor B < 0) then
  begin
    Z := not Z;
    writeln(#13#10, 'Результат с корректировками:');  
    writeln('Z = ', LongToBin(Z, false) );
    Z := Z+1;
  end;
 
  writeln(#13#10, 'Результат в прямом коде:');
  writeln('Z = ', LongToBin(Z, true) );
 
  writeln(#13#10, 'Результат в десятичной системе счисления:');
  writeln('Z = ', Z, ' (частное)');
end.
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.04.2015, 21:38
Ответы с готовыми решениями:

Умножение двух двоичных чисел
Помогите создать подпрограмму для умножения двух чисел в двоичной системе!(паскаль)

Сложение и вычитание двух целых чисел в дополнительном коде
Составьте программу представления в двоичном виде (ввод и вывод в виде 8 нулей и единиц для каждого...

Сложение вычитание в двоичном дополнительном коде
Люди помогите плизззззз.Мне нужна прога на паскале.Тема:Сложение вычитание в двоичном...

Перевести числа из шестнадцатеричной записи в семеричную в обратном или дополнительном коде
Помогите пожалуйста..Уже несколько дней сижу и ничего не выходит..:wall: Исходный файл содержит...

Деление двоичных чисел столбиком
Всем доброго времени суток! Пытаюсь реализовать алгоритм деления двоичных чисел столбиком на...

11
IOFEE
0 / 0 / 1
Регистрация: 06.04.2015
Сообщений: 5
06.04.2015, 21:45  [ТС] 2
пример выполненной программы деления:
Код
A = 54
B = 33

Прямой код:
A=0|000000000110110
B=0|000000000100001

Обратный код:
A=0|000000000110110
B=0|000000000100001
-B=1|111111111011110

Деление A на B без восстановления остатка:
Z=0|000000000000000
R=0|000000000110110 R:=R-B
 +1|111111111011110
 =0|000000000010101 R>=0-->Z:=Z+1|Z=0|000000000000001
R=0|000000000010101 R:=R-B
 +1|111111111011110
 =1|111111111110011
Результат:
Z=0|000000000000001

Результат в прямом коде:
Z=0|000000000000001

Результат в десятичной системе счисления:
Z=1(частное)
0
ФедосеевПавел
Модератор
4854 / 2658 / 1065
Регистрация: 01.02.2015
Сообщений: 8,669
Записей в блоге: 1
07.04.2015, 07:51 3
Когда-то делал на форуме для Olven с выводом результата в файл.
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
program mult;
 
var
  f: Text;
 
  procedure StrToInt(s: string; var a: longint);
  var
    i: integer;
    Sign: boolean;
    start: integer;
    code: word;
    d: longint;
  begin
    Sign := (s[1] = '-');
    if Sign then
      start := 2
    else
      start := 1;
    a := 0;
    for i := start to Length(s) do
    begin
      Val(s[i], d, code);
      if code <> 0 then
        exit;
      a := a * 10 + d;
    end;
    {если число должно быть отрицательным - переводим в дополнительный код}
  {способ преобразования взят из "http://ru.wikipedia.org/wiki/Дополнительный_код_(представление_числа)"
   и адаптирован к 32 битному типу LongInt}
    if Sign then
      a := ((not a) or $80000000) + 1;
  end;
 
  procedure IntToBin(a: longint; var s: string);
  var
    i: integer;
    Mask: longint;
  begin
  {$ifopt R+} {временно отключим контроль переполнения}
    {$R-}
    {$define ReqSet_OptR}
  {$endif}
    s := '';
    Mask := $80000000;
    for i := 1 to 8 * SizeOf(a) do
    begin
      if (Mask and a) <> 0 then
        s := s + '1'
      else
        s := s + '0';
      Mask := Mask shr 1;
    end;
  {$ifdef ReqSet_OptR}
    {$R+}
    {$undef ReqSet_OptR}
  {$endif}
  end;
 
  procedure Mul(a, b: longint; var Res: longint);
  var
    i: integer;
    Mask: longint;
    s: string;
  begin
    IntToBin(a, s);
    WriteLn(f, s);
    WriteLn(f, 'x');
    IntToBin(b, s);
    WriteLn(f, s);
    WriteLn(f, '--------------------------------');
    Res  := 0;
    Mask := 1;
    for i := 1 to 8 * SizeOf(b) do
    begin
    {$Q-}
    {$ifopt R+} {временно отключим контроль переполнения}
      {$R-}
      {$define ReqSet_OptR}
    {$endif}
      if (Mask and b) <> 0 then
      begin
        Res := Res + a;
        IntToBin(a, s);
        WriteLn(f, s);
      end
      else
      begin
        IntToBin(0, s);
        WriteLn(f, s);
      end;
      a := a shl 1;
      Mask := Mask shl 1;
    {$ifdef ReqSet_OptR}
      {$R+}
      {$undef ReqSet_OptR}
    {$endif}
    end;
    WriteLn(f, '--------------------------------');
    IntToBin(Res, s);
    WriteLn(f, s);
  end;
 
var
  c1, c2, c3: longint;
  s: string;
begin
  WriteLn('Enter 1st number: ');
  ReadLn(s);
  StrToInt(s, c1);
  WriteLn('Enter 2nd number: ');
  ReadLn(s);
  StrToInt(s, c2);
 
  Assign(f, 'Log.txt');
  Rewrite(f);
 
  WriteLn(f, c1, '*', c2);
 
  Mul(c1, c2, c3);
 
  WriteLn(f, 'Result: ', c3);
  WriteLn(f, 'Etalon: ', c1 * c2);
  Close(f);
end.
лог работы
-10*-23
11111111111111111111111111110110
x
11111111111111111111111111101001
--------------------------------
11111111111111111111111111110110
00000000000000000000000000000000
00000000000000000000000000000000
11111111111111111111111110110000
00000000000000000000000000000000
11111111111111111111111011000000
11111111111111111111110110000000
11111111111111111111101100000000
11111111111111111111011000000000
11111111111111111110110000000000
11111111111111111101100000000000
11111111111111111011000000000000
11111111111111110110000000000000
11111111111111101100000000000000
11111111111111011000000000000000
11111111111110110000000000000000
11111111111101100000000000000000
11111111111011000000000000000000
11111111110110000000000000000000
11111111101100000000000000000000
11111111011000000000000000000000
11111110110000000000000000000000
11111101100000000000000000000000
11111011000000000000000000000000
11110110000000000000000000000000
11101100000000000000000000000000
11011000000000000000000000000000
10110000000000000000000000000000
01100000000000000000000000000000
11000000000000000000000000000000
10000000000000000000000000000000
00000000000000000000000000000000
--------------------------------
00000000000000000000000011100110
Result: 230
Etalon: 230
Если что не так - переделай самостоятельно.
1
IOFEE
0 / 0 / 1
Регистрация: 06.04.2015
Сообщений: 5
12.04.2015, 19:24  [ТС] 4
ФедосеевПавел, Не подскажешь, как это исправить?
Умножение двоичных чисел в дополнительном коде
0
12.04.2015, 19:24
ФедосеевПавел
Модератор
4854 / 2658 / 1065
Регистрация: 01.02.2015
Сообщений: 8,669
Записей в блоге: 1
12.04.2015, 21:34 5
А какая готовая функция перевода символа или строки в число присутствует у PABC.NET?
Можно попробовать написать свою Val
Pascal
1
2
3
4
5
6
7
8
9
10
  procedure Val(c: char; var Digit: longint; var ErrCode: word);
  begin
    if c in ['0'..'9'] then
    begin
      ErrCode := 0;
      Digit := Ord(c) - Ord('0');
    end
    else
      ErrCode := 1;
  end;
Я её проверил на WDE (online PABC.NET compiler) - работает.
0
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
28247 / 18806 / 7403
Регистрация: 22.10.2011
Сообщений: 32,905
Записей в блоге: 6
12.04.2015, 23:24 6
StrToInt в PABC.NET уже готовый, не надо его переписывать
1
Володымир
0 / 0 / 0
Регистрация: 17.03.2017
Сообщений: 12
07.05.2017, 15:36 7
ФедосеевПавел, Большое спасибо что сделал эту программу) Но к сожалению я не могу ее проверить, так как там есть ошибочка. Как ее исправить? Напиши пожалуйста!
0
Миниатюры
Умножение двоичных чисел в дополнительном коде  
ZX Spectrum-128
Модератор
Эксперт Pascal/Delphi
4941 / 3459 / 4049
Регистрация: 05.06.2014
Сообщений: 17,379
07.05.2017, 20:23 8
Безо всяких изменений работает в fpc.

Вариант для pabc.net ниже:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
program mult;
 
var
  f: Text;
 
procedure StrToInt(s: string; var a: longint);
var
  i: integer;
  Sign: boolean;
  start: integer;
  code: integer;
  d: longint;
begin
  Sign := (s[1] = '-');
  if Sign then
    start := 2
  else
    start := 1;
  a := 0;
  for i := start to Length(s) do
  begin
    Val(s[i], d, code);
    if code <> 0 then
      exit;
    a := a * 10 + d;
  end;
    {если число должно быть отрицательным - переводим в дополнительный код}
  {способ преобразования взят из "http://ru.wikipedia.org/wiki/Дополнительный_код_(представление_числа)"
   и адаптирован к 32 битному типу LongInt}
  if Sign then
    a := ((not a) or $80000000) + 1;
end;
 
procedure IntToBin(a: longint; var s: string);
var
  i: integer;
  Mask: longint;
begin
  (*  {$ifopt R+} {временно отключим контроль переполнения}
      {$R-}
      {$define ReqSet_OptR}
    {$endif}*)
  s := '';
  Mask := $80000000;
  for i := 1 to 8 * sizeof(string) do
  begin
    if (Mask and a) <> 0 then
      s := s + '1'
    else
      s := s + '0';
    Mask := Mask shr 1;
  end;
  {$ifdef ReqSet_OptR}
  {$R+}
  {$undef ReqSet_OptR}
  {$endif}
end;
 
procedure Mul(a, b: longint; var Res: longint);
var
  i: integer;
  Mask: longint;
  s: string;
begin
  IntToBin(a, s);
  WriteLn(f, s);
  WriteLn(f, 'x');
  IntToBin(b, s);
  WriteLn(f, s);
  WriteLn(f, '--------------------------------');
  Res := 0;
  Mask := 1;
  for i := 1 to 8 * sizeof(longint) do
  begin
    (*    {$Q-}
        {$ifopt R+} {временно отключим контроль переполнения}
          {$R-}
          {$define ReqSet_OptR}
        {$endif}*)
    if (Mask and b) <> 0 then
    begin
      Res := Res + a;
      IntToBin(a, s);
      WriteLn(f, s);
    end
      else
    begin
      IntToBin(0, s);
      WriteLn(f, s);
    end;
    a := a shl 1;
    Mask := Mask shl 1;
    (*   {$ifdef ReqSet_OptR}
    {$R+}
    {$undef ReqSet_OptR}
    {$endif}*)
  end;
  WriteLn(f, '--------------------------------');
  IntToBin(Res, s);
  WriteLn(f, s);
end;
 
var
  c1, c2, c3: longint;
  s: string;
 
begin
  WriteLn('Enter 1st number: ');
  ReadLn(s);
  StrToInt(s, c1);
  WriteLn('Enter 2nd number: ');
  ReadLn(s);
  StrToInt(s, c2);
  
  Assign(f, 'Log.txt');
  Rewrite(f);
  
  WriteLn(f, c1, '*', c2);
  
  Mul(c1, c2, c3);
  
  WriteLn(f, 'Result: ', c3);
  WriteLn(f, 'Etalon: ', c1 * c2);
  Close(f);
end.
1
Володымир
0 / 0 / 0
Регистрация: 17.03.2017
Сообщений: 12
07.05.2017, 22:46 9
ZX Spectrum-128, спасибо за отзывчивость, но к сожалению выводит всё, кроме ответа. А так хочется, чтобы всё получилось)
0
Володымир
0 / 0 / 0
Регистрация: 17.03.2017
Сообщений: 12
07.05.2017, 23:19 10
ZX Spectrum-128, а вот что показывает Log-файл.
Код
-10*-23
1111111111111111111111111111111111111111111111111111111111111111
x
1111111111111111111111111111111111111111111111111111111111111111
--------------------------------
1111111111111111111111111111111111111111111111111111111111111111
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
1111111111111111111111111111111111111111111111111111111111111111
0000000000000000000000000000000000000000000000000000000000000000
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
0111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
0000000000000000000000000000000000000000000000000000000000000000
--------------------------------
0000000000000000000000001111111111111111111111111111111111111111 
Result: 230 
Etalon: 230
Я даже вбил такие же числа как в примере выше, но у нас только Result и Etalon совпадает, а ход действий и сами умножаемые числа в двоичном виде в Log-файле у меня совершенно другие. Мне так нужно чтобы заработало. Помоги плиз, потрать минутку)
0
ФедосеевПавел
Модератор
4854 / 2658 / 1065
Регистрация: 01.02.2015
Сообщений: 8,669
Записей в блоге: 1
07.05.2017, 23:41 11
Володымир, посмотрите справку на числовые типы в PABC.NET. Вам нужно заменить longint на целочисленный знаковый 32-битный тип.
Я-то программу составлял под Turbo/Free Pascal, в которых longint однозначно 32-бита. А в PABC.NET - похоже, 64 бита.
Может быть есть тип int32 или sint32.
0
Володымир
0 / 0 / 0
Регистрация: 17.03.2017
Сообщений: 12
08.05.2017, 00:14 12
ФедосеевПавел, ZX Spectrum-128, Большое спасибо вам ребята! Действительно, на FreePascal всё работает, вы меня спасли)
0
08.05.2017, 00:14
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.05.2017, 00:14

Сложение (вычитание) двоичных чисел в дополнительном коде
Сложение (вычитание) двоичных чисел в дополнительном коде и сделать проверку введенных чисел....

Сложение (вычитание) двоичных чисел в дополнительном коде
Сложение (вычитание) двоичных чисел в дополнительном коде.Можно не писать нахождение...

Сложение (вычитание) двоичных чисел в обратном коде
Сложение (вычитание) двоичных чисел в обратном коде.Можно не писать нахождение обратного кода


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.