可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm writing a program to convert an integer to 32-bit binary. The problem is with the output - it comes backwards.
#include <stdio.h>
int main() {
long number, binary, num2;
printf("Enter an integer: ");
scanf("%ld", &number);
for (num2 = (number * 2) / 2; num2 > 0; num2 /= 2) {
binary = num2 % 2;
printf("%ld", binary);
}
putchar('\n');
return 0;
}
So if I put '6' it shows as 011 and it has to be 110
Also, how do I output the rest of '0's? So that the whole output in this case would be:
00000000 00000000 00000000 00000110
回答1:
You compute digits starting from the right, which is why your output shows the right-most digit first. Here is a way that starts from the left, using a bitmask, and does not convert your value to unsigned which may change the bits:
#include <stdio.h>
#include <limits.h>
int main()
{
long number;
if ( 1 != scanf("%ld", &number) )
return 1;
// sign bit (cannot use 1L left-shift as that causes UB)
putchar( '0' + (number < 0) );
// value bits
for (long bit = 1L << (CHAR_BIT * sizeof number - 2); bit; bit >>= 1)
putchar( '0' + !!(number & bit) );
putchar('\n');
}
回答2:
It's so much easier to use a recursive function for this:
#include <stdio.h>
#include <stdint.h>
void printInBinary(long num, int bit)
{
if ( bit >= 8*sizeof(num) )
{
return;
}
printInBinary(num/2, bit+1);
printf("%ld", num%2);
if ( bit%8 == 0 )
{
printf(" ");
}
if ( bit == 0 )
{
printf("\n");
}
}
int main()
{
int y = 31;
uint32_t x1 = (1 << y );
uint32_t x2 = (1u << y );
printf("x1: %u\n", x1);
printInBinary(x1, 0);
printf("x2: %u\n", x2);
printInBinary(x2, 0);
}
Output:
x1: 2147483648
00000000 00000000 00000000 00000000 10000000 00000000 00000000 00000000
x2: 2147483648
00000000 00000000 00000000 00000000 10000000 00000000 00000000 00000000
PS If you used uint32_t
for num
instead of long
, you will get the 32 bits of output.
回答3:
If you want to print the binary number, you should print the bits backwards. Watch this:
6 (10):
6 / 2 = 3, rem => 0
3 / 2 = 1, rem => 1
1 / 2 = 0, rem => 1
Hence 6 (2) = 110
You are printing it the forward order which will give you 011. So you should keep the binary bits by putting them in a variable and finally print them back.
Try This
#include <stdio.h>
int main(){
long number, binary, num2;
int i = 0, j;
char num[100];
printf("Enter an integer: ");
scanf("%ld", &number);
while (number != 0){
num[i] = num2 % 2;
number /= 2;
i++;
}
for (j = 0; j < 32; j++) {
if (j > i) {
printf("0");
}
else {
printf("%c", num[i]);
i--
}
}
printf("\n");
return 0;
}
回答4:
Here is a simple portable implementation for 32-bit numbers:
#include <stdio.h>
#include <string.h>
int main() {
long input; // at least 32 bits
unsigned long number;
int i;
printf("Enter an integer: ");
if (scanf("%ld", &input) != 1)
return 1;
/* copy the bit pattern to an unsigned long */
memcpy(&number, &input, sizeof number);
for (i = 32; i-- > 0;) {
if (i > 0 && (i & 7) == 0)
putchar(' ');
putchar('0' + (int)((number >> i) & 1));
}
putchar('\n');
return 0;
}
回答5:
Simply examine the bits in the order in which you want them output. I have used a unsigned long
cast for the shifting, because the result of shifting bits of a signed value into the sign bit is undefined.
#include <stdio.h>
#include <limits.h>
int main() {
long number = 0;
int i;
printf("Enter an integer: ");
scanf("%ld", &number);
for(i=0; i<sizeof(number)*CHAR_BIT; i++) {
if (number < 0)
printf ("1");
else
printf ("0");
if ((i % CHAR_BIT) == CHAR_BIT - 1)
printf (" ");
number = (long)((unsigned long)(number) << 1);
}
printf("\n");
return 0;
}
Program output:
Enter an integer: 6
00000000 00000000 00000000 00000110
回答6:
#include <stdio.h>
int main(){
// Assuming 32 bit architecture.
unsigned long number;
// Initialize a null-terminated char-array
// of zeros (ASCII value 48).
char binary[33] = {[0 ... 31] = 48, [32] = 0};
printf("Enter an integer: ");
scanf("%lu", &number);
for(int i = 0; number > 0; ++i) {
binary[31 - i] = number % 2;
number /= 2;
}
printf("%s\n", binary);
return 0;
}