• Добро пожаловать на компьютерный форум Tehnari.ru. Здесь разбираемся с проблемами ПК и ноутбуков: Windows, драйверы, «железо», сборка и апгрейд, софт и безопасность. Форум работает много лет, сейчас он переехал на новый движок, но старые темы и аккаунты мы постарались сохранить максимально аккуратно.

    Форум не связан с магазинами и сервисами – мы ничего не продаём и не даём «рекламу под видом совета». Отвечают обычные участники и модераторы, которые следят за порядком и качеством подсказок.

    Если вы у нас впервые, загляните на страницу о форуме и правила – там коротко описано, как задать вопрос так, чтобы быстро получить ответ. Чтобы создавать темы и писать сообщения, сначала зарегистрируйтесь, а затем войдите под своим логином.

    Не знаете, с чего начать? Создайте тему с описанием проблемы – подскажем и при необходимости перенесём её в подходящий раздел.
    Задать вопрос Новые сообщения Как правильно спросить
    Если пришли по старой ссылке со старого Tehnari.ru – вы на нужном месте, просто продолжайте обсуждение.

Сложить двоичные числа в Pascal

Asya_inter

Новые
Регистрация
12 Янв 2015
Сообщения
71
Реакции
0
Баллы
0
Сложить двоичные числа в Pascal

Как это сделать не знаю. Но думаю, что нужно складыват число 3 раза. Подскажите, вот задача:Даны натуральное число n, целые числа a0, ..., an такие, что каждое ai равно нулю или единице и an ≠ 0. Последовательность a0, ..., an задает двоичное предстовление некоторого целого числа p = an2n + ... + a12 + a0. Получить последовательность нулей и едениц задающую двоичное представление числа 3p
 
Как это сделать не знаю. Но думаю, что нужно складыват число 3 раза.
Вовсе не обязательно. Можно обойтись сложением двух чисел, одно из которых - исходное, второе - исходное, умноженное на 10. Вот так (здесь десятичная форма служит только для контроля и наглядности):
Код:
Var
 n,i:byte;
 M,M1,T:LongInt;

Function Bin2Dec(b:Longint):Integer;
var
 Q,r:Integer;
 B1:Longint;
begin
 B1:=b;
 Q:=B1 mod 10;
 B1:=B1 div 10;
 r:=1;
 repeat
  r:=r*2;
  Q:=Q+(B1 mod 10)*r;
  B1:=B1 div 10;
 until B1=0;
 Bin2Dec:=Q;
end;

Function Sum2Bin(b1,b2:LongInt):LongInt;
var
 b1a,b2a,b3,r:LongInt;
 c1,c2,c3,d:Byte;
begin
 b1a:=b1;
 b2a:=b2;
 b3:=0;
 r:=1;
 d:=0;
 repeat
  c1:=b1a mod 10;
  c2:=b2a mod 10;
  if (c1+c2+d=0) or (c1+c2+d=1) then
   begin
    c3:=c1+c2+d;
    d:=0;
   end
  else
  if (c1+c2+d)=2 then
   begin
    c3:=0;
    d:=1;
   end
  else
   begin
    c3:=1;
    d:=1;
   end;
  b3:=b3+c3*r;
  r:=r*10;
  b1a:=b1a div 10;
  b2a:=b2a div 10;
 until (b1a=0) and (b2a=0);
 b3:=b3+d*r;
 Sum2Bin:=b3;
end;

Begin
 Write('n (<=8) = ');
 Readln(n);
 Randomize;
 T:=1;
 for i:=1 to n-1 do
  begin
   M:=M+Random(2)*T;
   T:=T*10;
  end;
 M:=M+T;
 M1:=M*10;
 Writeln(' M Binary: ',M);
 Writeln(' M Decimal: ',Bin2Dec(M));
 Writeln('3M Binary: ',Sum2Bin(M,M1));
 Writeln('3M Decimal: ',Bin2Dec(Sum2Bin(M,M1)));
 Readln
End.
ВНИМАНИЕ, ВАЖНО!
Программа писалась и отлаживалась в нормальном Паскале (Free, Turbo). Если у Вас этот зловонный АВС (у себя подобной гадости не держу), то следует:
1. Спереди присобачить Program Tralala;
2. Всюду LongInt заменить на Integer.
 
Vladimir_S, спасибо, что решили. Но я вот всё разбираюсь, а что-то не совсем понимаю, почему второе число мы умножаем на 10, что от этого происходит? (наверное это очень глупые вопросы, но я хочу во всём этом разбираться и понимать).
 
Vladimir_S, спасибо, что решили. Но я вот всё разбираюсь, а что-то не совсем понимаю, почему второе число мы умножаем на 10, что от этого происходит? (наверное это очень глупые вопросы, но я хочу во всём этом разбираться и понимать).
Понимаете, числа-то двоичные, но записываем и храним мы их, как десятичные. Например, есть двоичное число 111 (7). Какой двоичный вид будет иметь это число, если мы умножим его на 2? В десятичной системе, ясное дело, 7*2=14. А в двоичной? В двоичной умножение на 2 - это всё равно, что в десятичной - на 10, т.е. все цифры нужно сдвинуть влево и приписать 0. В результате получаем 1110, т.е. те же 14.
В задаче речь идет об умножении на 3 - это аналог умножения на одиннадцать в десятичной системе. На этом и строится алгоритм: сперва умножаем на 2, т.е. сдвигаем все цифры влево и приписываем 0, а потом к этому прибавляем (в двоичной арифметике) само исходное число. Ну а как проще всего объяснить компьютеру, что нужно сдвинуть все разряды влево и справа присобачить ноль? А умножить на 10.
 
Vladimir_S, ещё раз спасибо! Всё понятно теперь.
 
Извините, а можете ещё прокомментировать значения переменных, если вам не трудно?
 
Извините, а можете ещё прокомментировать значения переменных, если вам не трудно?
Да не трудно, пожалуйста.

1. В основной программе:

n - разрядность (количество знаков) двоичного числа
i - переменная цикла
М - само число. Формируется методом случайной генерации нулей и единиц от младшего разряда до (n-1)-го. В старший (n-й) разряд всегда записывается 1.
Т - счетчик разрядов
М1 - результат сдвига влево всех разрядов числа М на один и приписывания справа нуля. В двоичной записи соответствует умножению числа М на два. Для "внутреннего употребления" М1=М*10.

2. В функции Bin2Dec (преобразование двоичного числа в десятичное):

b, B1 - преобразуемое двоичное число
Q - очередная значащая цифра (0 или 1), начиная с младшего разряда
r - двоичный вес очередного разряда
D - лишний идентификатор. Убрал.

3. В функции двоичного сложения Sum2Bin:

b1,b2 (b1a,b2a) - складываемые двоичные числа
b3 - формируемая двоичная сумма
r - десятичный вес разряда
с1, с2, с3 - цифры (0 или 1) в очередном разряде складываемых чисел и суммы.
d - переносимая в следующий разряд цифра.
 
Vladimir_S, Здравствуйте! Я вчера сдавала данную задачу и мне сказали, чтобы сделать её более просто, чтобы можно было ввести любое по размеру двоичное число и сделать всё с помощью функции и не переводить 3 в десятичную систему счисления. Я кое-что написала (не знаю правильно ли), но не могу разобраться как посчитать число p. Вы может знаете как это сделать? подскажите пожалуйста!


program nomer_589(c);

function um(const s: string): longint;
var
i: integer;
r: longint;
begin
r := 0;
for i := 1 to length(s) do
begin
if (s = '1') or (s = '0') then
r := r * 2 + (ord(s) - ord('0'))
else begin
um := -i;
exit;
end;
end;
um := r
end;

function umnogenie(dec: longint): string;
begin
if dec = 0 then umnogenie := ''
else
if odd(dec) then
umnogenie := umnogenie( dec div 2) + '1'
else
umnogenie := umnogenie(dec div 2) + '0';
end;

const
t = 3;

var
s: string;
d1: longint;

begin

Write('введите первое двоичное число: '); ReadLn(s);
d1 := um(s);
WriteLn('Произведение равно ', umnogenie( d1 * t ));
Readln
end.
 
задача 589

Вот задача эта, а то может у меня непонятно написано.
 

Вложения

  • pKBAi9BZm18.webp
    pKBAi9BZm18.webp
    32 KB · Просмотры: 281
Vladimir_S, Здравствуйте! Я вчера сдавала данную задачу и мне сказали, чтобы сделать её более просто, чтобы можно было ввести любое по размеру двоичное число и сделать всё с помощью функции и не переводить 3 в десятичную систему счисления.
Через строки? И это называется "более просто"?!! Ну-ну...
Я кое-что написала (не знаю правильно ли), но не могу разобраться как посчитать число p. Вы может знаете как это сделать? подскажите пожалуйста!
Хорошо, посмотрю. Где-то через час.
 
Вот задача эта, а то может у меня непонятно написано.
Стоп! Но это же совсем другая задача! Так что же Вам нужно: умножение на 3 или прибавление/вычитание единицы?
А, нет, виноват - увидел! Всё надо. Разделительная линия сбила.
 
Нужно под буквой "с" - то есть 3p
 
Спасибо! Буду очень благодарна, если поможете!
Постараюсь.
Два вопроса.
1. Я вижу, что Вы используете формат Longint. Но, насколько я знаю, в этом... ну, в общем, в АВС такого формата нет. Следует ли из этого, что Вы можете пользоваться и нормальным Паскалем? Это было бы здорово.
2. Вероятно, чтобы ублажить Ваших преподов, нужно вовсе отказаться от каких-либо десятичных операций, а работать только со строками. Так?
 
Vladimir_S,
1) У меня pascalABC.NET и там всё работает;
2) Да, сказали всё в двоичной, но число 3 не переводить.
 
1) У меня pascalABC.NET и там всё работает;
О, Боже - этого только не хватало! В общем, у меня Dos Free Pascal, в нем и работаю, других нет.
2) Да, сказали всё в двоичной, но число 3 не переводить.
Ну, этого я совсем не понимаю.
А вообще - посмотрел я Ваш код, и засомневался - зачем Вам помощь? Уж если Вы так виртуозно владеете рекурсивными функциями... Нет, правда - в чем проблема?
Могу посоветовать решать задачу так: написать функцию двоичного сложения любых двоичных чисел, представляемых, как строки. И результат тоже в виде строки.
С помощью этой функции сложить два числа: исходное и полученное путём сдвига всех разрядов влево и приписывания в крайнюю правую позицию нуля.
Сможете?
 
Vladimir_S, что вы? Я бы не смогла это сама сделать( я только учусь)! Просто на сайте нашла функцию умножения и немного переделала ( но она ведь верно работает??) ... А Dos Free Pascal я пыталась установить через сайт, но не вышло и поэтому так и работаю с этим. А просто в ту программу нельзя разве ту вычислительную формулу для P подставить? ... А функцию сложения так быстро мне не написать... так как уже завтра всё нужно.
 
Ну вот Вам такой вариант.
Пояснения:
1. Поскольку в задании не требуется показывать десятичные эквиваленты чисел, это и не делается: идет работа только с двоичными числами.
2. Функция Sum дает (в строковой форме) сумму любых положительных двоичных чисел, заданных опять же в виде строк.
Код:
Var
 p:String;

Function Sum(D1,D2:String):String;
Var
 D1a,D2a,D3a,D3,Q:String;
 L,i,d,c1,c2,c3:Byte;
 Code:Integer;
Begin
 If Length(D1)>Length(D2) then
  begin
   L:=Length(D1);
   D1a:=D1;
   D2a:='';
   for i:=1 to (Length(D1)-Length(D2)) do D2a:=D2a+'0';
   for i:=(Length(D1)-Length(D2))+1 to Length(D1) do D2a:=D2a+D2[i-(Length(D1)-Length(D2))];
  end
 else
  begin
   L:=Length(D2);
   D2a:=D2;
   D1a:='';
   for i:=1 to (Length(D2)-Length(D1)) do D1a:=D1a+'0';
   for i:=(Length(D2)-Length(D1))+1 to Length(D2) do D1a:=D1a+D1[i-(Length(D2)-Length(D1))];
  end;
 D3a:='';
 d:=0;
 for i:=L downto 1 do
  begin
   Val(D1a[i],c1,Code);
   Val(D2a[i],c2,Code);
   if (c1+c2+d)<=1 then
    begin
     c3:=c1+c2+d;
     d:=0;
    end
   else
   if (c1+c2+d)=2 then
    begin
     c3:=0;
     d:=1;
    end
   else
   if c1+c2+d=3 then
    begin
     c3:=1;
     d:=1;
    end;
   Str(c3,Q);
   D3a:=D3a+Q;
  end;
 if d=1 then D3a:=D3a+'1';
 D3:='';
 for i:=1 to Length(D3a) do
  D3:=D3+D3a[Length(D3a)-i+1];
 Sum:=D3;
end;

Begin
 Write(' p: ');
 Readln(p);
 Writeln('3p: ',Sum(p,p+'0'));
 Readln
End.
 
Огромное вам спасибо!! Сейчас буду разбираться для полного понимания решения!
 
Назад
Сверху