Листать бит в с
В этом коде я должен просить пользователя перевернуть 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;
}