C: заменить бит в int в указанной позиции c, используя битовые операторы - PullRequest
0 голосов
/ 03 февраля 2020

У меня есть программа C ниже, которая заменит указанный бит числа из другого числа. Пример:

Let first no whose bit is to be replaced is:
7 //0000 0111

Second no from whom bit is to be replaced
8 //0000 1000

Specified position: 3 (0-indxed)

Converted number will be 15

C Код:

#include <stdio.h>

int main()
{
  int first,second,pos;

  printf("enter first & second no:\n");
  scanf("%d %d",&first,&second);

  printf("enter specified position(0-indexed)\n");
  scanf("%d",&pos);

  //collect corresponding bit of second no
  int temp=(second>>pos)&1;

  //if bit at specified position is 1
    if(temp==1){
      temp=temp<<pos;
      first|=temp;
      }
     else{ //if bit at specified position is 0
      int flag=255;//FF, all bit set to 1(considering 8 bit numbers)
      temp=1<<pos;
      //this set only the specified position bit 0 others 1
      flag=flag^temp;
      first&=flag;
     }

printf("converted no %d\n",first);

return 0;

}

К счастью, все это отлично работает для 8-битных целых чисел. Моя проблема в том, что мне нужна программа для работы с 32-битными целыми числами (положительные целые числа меньше 3 миллиардов) Всякий раз, когда я использую большие числа, такие как 2 миллиарда, он не выводит правильное преобразованное число. Как я могу исправить эту проблему?

Ответы [ 2 ]

1 голос
/ 03 февраля 2020

Эта строка

int flag = 255;   //FF, all bit set to 1 (considering 8 bit numbers)

Делает ваш код неспособным обрабатывать число больше 255, для которого требуется хранить более 8 бит.

С учетом 32-битного int (распространено в архитектурах общего назначения) и представление с двумя дополнениями (не обязательное для стандарта, но довольно распространенное), вы можете использовать функцию, подобную следующей ( здесь , пример использования):

int copy_bit(int dest, int source, int pos)
{    
    assert(0 <= pos  &&  pos < (int)(CHAR_BIT * sizeof(int)));

    // Calculate the bit mask
    unsigned mask = 1u << pos;

    // Clear the bit in the destination
    unsigned tmp = (unsigned)dest & ~mask;

    // Set the bit from the source
    tmp |= (unsigned)source & mask;

    return (int)tmp;
}
0 голосов
/ 03 февраля 2020

Это потому, что вы используете int. Максимальное значение 32-значного int со знаком: 2 ^ 31 -1 Для решения проблемы следует использовать unsigned int. 32-битное целое число без знака имеет максимальное значение: 2 ^ 32. Тогда вы можете просто перевернуть логи c так:

first = first & ((0x1u<<pos) & second)
...