С программой, чтобы найти комплимент двоим - PullRequest
0 голосов
/ 19 мая 2018

Я наткнулся на C-код в книге, чтобы найти дополнение к двоичному числу.Я не был знаком с понятием дополнения двоичного числа к единице и двум, поэтому я провел тщательное исследование и теперь немного понял примерно то же самое.Но у меня все еще есть некоторые сомнения относительно того, как работает код.Код выглядит следующим образом (комментарии не были в исходном коде и были добавлены мной, чтобы я мог исправить их, если он неправильный) -

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
  char a[16]; /*declaring an array to hold the binary number string*/
  int i, j, k, len; /*len is the length of the string*/
  printf ("Enter a binary number: ");
  gets (a); /*reads the input string*/
  len= strlen(a); /*calculates length of string*/
  for (k=0; a[k]!='\0';k++) /*to check if its a valid binary number or not*/
  {
    if (a[k] != '0' && a[k]!='1')
    {
      printf ("\nIncorrect Binary format...this program will quit");
      exit(0);
    }
  }
  for (i=len-1; a[i]!='1'; i--) /* An empty for loop*/
  ;
  for (j=i-1; j>=0; j--) /*checks from right to left if the bit is 0 or 1*/
  {
    if (a[j]=='1')
    a[j]= '0'; /*if the bit is 1, its converted to 0*/
    else
    a[j]= '1'; /*if the bit is 0, its converted to 1*/
  }
  printf ("\n2's compliment = %s", a); 
}

Код работает абсолютно нормально, но у меня естьсомневается как.

Во-первых, я не совсем понимаю, что делает пустой цикл for.Считается ли это до тех пор, пока мы не встретим первый ноль с правой стороны?

Во-вторых, в третьем и последнем цикле for, мы просто переворачиваем значение каждого бита от 1 до 0 и от 0 до 1. Но мысделать это для дополнения одного, а не дополнения двух, верно?Нам нужно добавить 1 к дополнению к одному, чтобы найти дополнение к двум.Код, похоже, нигде не делает этого.Как это работает тогда?

Просьба прояснить, заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 19 мая 2018

Обычно для вычисления дополнения к двум мы меняем все 1 на 0 и все 0 на 1, а затем добавляем 1.

Давайте посмотрим на дополнение к двум 172 или двоичный 10101100:

10101100
01010011      /* change all 0's to 1's and 1's to 0's */
01010100      /* add one */

Обратите внимание, что когда мы добавили 1, мы изменили некоторые из 1 обратно на 0.Фактически, все, что было 0 на правом краю исходного числа, осталось 0. И самые правые 1 в исходном числе остались равными 1. И только 1 и 0 слева от самого правого 1 были заменены.

И вот что делает загадочный цикл в оригинальной программе.Он сканирует справа, пропуская 0, пока не находит первую 1, и это только цифры слева от этой точки, которые он на самом деле меняет местами.Переменная i в конечном итоге удерживает позицию крайней правой 1, а затем следующий цикл, тот, который на самом деле выполняет обмен, начинается с j = i - 1.

Еще одна вещь: извините за этои, возможно, вы уже знаете это, но вам действительно не следует использовать функцию gets(), даже в небольшой тестовой программе.Это действительно ужасная, опасная функция.

0 голосов
/ 19 мая 2018

Во-первых, я не совсем понимаю, что делает пустой цикл for.

Нужно найти самый правый 1 и присвоить его i.

Во-вторых, в третьем и последнем цикле for мы просто переворачиваем значение каждого бита от 1 до 0 и от 0 до 1.

Это переворачивает все биты, начинаяindex i-1.

Я изучил хитрость в моем курсе микропроцессоров.Это то, что начинайте читать биты справа налево, пока не увидите первый бит, который 1.Не переворачивай это.После этого переверните все биты.

Давайте попробуем, 10110 -> 01010

  • Начать справа.
  • Читать 0, это не 1. Продолжайте,
  • Чтение 1, да, мы получаем первый бит, который 1.Не переворачивайте его.
  • Прочитайте 1, переверните его.Теперь это 0.
  • Чтение 0, переверните его.Теперь это 1.
  • Чтение 1, переверните его.Теперь это 0.

Мы получаем 01010

Логика программы именно то, что я упоминаю.

...