Листать бит в с

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

int main(int argc, char *argv[]) {
   int32_t num = 0;
   int bitC = 0;
   int number;
   char cont;
   do {
      printf("Enter a number between 1 and 1000\n");
      do {
         scanf("   %d", &num);
         if(num < 0 || num > 1000) {
            printf("Error: Number MUST be between 1 and 1000.\n");
            //printf("Please re-enter number.\n");
         }
      } while(num < 0 || num > 1000);
      printf("Choose a bit, between 0 and 31, to flip\n");
      do {
         scanf("   %d", &bitC);
         if(bitC < 0 || bitC > 31) {
            printf("Error: bit MUST be between 0 and 31\n");
            //printf("Please re-enter bit to change.\n");
         }
      } while(bitC <0 || bitC > 31);
      printf("Number before bit flip was %d\n", num);
      //num ^= (-bitC ^ num)&(1 << bitC);
      num ^= (1UL << bitC);
      printf("New number is: %d\n", num);
      printf("Would you like to shift another bit?\n");
      printf("Enter y to continue or n to quit\n");
      scanf("   %s", &cont);
   } while(cont == 'y');
   return 0;
}

2 ответа

Решение

Вы используете подписанные целые в программе прямо сейчас. Но реальная проблема заключается в том, что когда вы печатаете f, вы используете% d, что заставляет printf оценить аргумент (помните, что printf понятия не имеет, что это на самом деле, это просто значение в стеке) как int со знаком, даже если значение, переданное в printf, было без знака. Используйте% u.

Вот версия опубликованного кода, которая аккуратно компилируется и не имеет логики и недостатков данных, присущих опубликованному коду OP.

Он также правильно выводит сообщения об ошибках в stderr скорее, чем stdout и с этими сообщениями об ошибках указана причина, по которой ОС считает, что произошла ошибка.

#include <stdio.h>    // scanf(), printf(), fprintf(), perror()
#include <stdlib.h>   // exit(), EXIT_FAILURE
#include <inttypes.h> // uint32_t


int main( void )
{

   uint32_t num  = 0;
   uint32_t bitC = 0;
   char cont     = 'y';

   do
   {
      printf("Enter a number in the range 1...1000\n");

      do
      {
         if( 1 != scanf("%u", &num) )
         {
             perror( "scanf for number failed" );
             exit( EXIT_FAILURE );
         }

         // implied else, scanf successful

         // the 'num' is to check != 0
         if( !num || 1000 < num )
         {
            printf("Error: Number MUST be in range 1...1000.\n");
         }

         else
         {
             break;
         }

      } while(1);

      printf("Choose a bit, in range 0...31, to flip\n");

      do
      {
         if( 1 != scanf("%u", &bitC) )
         {
             perror( "scanf for bit number failed" );
             exit( EXIT_FAILURE );
         }

         // implied else, scanf successful

         if( bitC > 31 )
         {
            fprintf( stderr, "Error: bit must be in range 0...31\n" );
         }

         else
         {
             break;
         }

      } while(1);

      printf("Number before bit flip was %u\n", num);

      num ^= (1U << bitC);

      printf("New number is: %u\n", num);

      printf("Would you like to shift another bit?\n");
      printf("Enter y to continue or n to quit\n");

      if( 1 != scanf(" %c", &cont) )
      {
          perror( "scanf for continuing failed" );
          exit( EXIT_FAILURE );
      }

   } while('y' == cont || 'Y' == cont );
   return 0;
}
Другие вопросы по тегам