c 整数转二进制数
c integer to binary number
如果有人能帮助我,我将非常高兴...
我应该编写一个程序,在不使用循环的情况下以二进制表示形式打印一个整数。它还需要以 32 位表示形式打印出数字。对于小数字(例如 256 仍然有效),下面的代码工作正常。对于大数字,我没有得到预期的输出。
有人知道我该如何解决这个问题吗?
非常感谢!
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
void
print_reverse(uint32_t value)
{
if (value % 10 == 0) {
if (value == 0) {
printf("1");
return;
} else {
printf("0");
print_reverse(value / 10);
}
} else {
if (value == 1) {
return;
} else {
printf("1");
print_reverse((value - 1) / 10);
}
}
return;
}
int
print_binary1(uint32_t value, uint32_t binary1, int zeros1)
{
int rest, binary, zeros;
if (value == 0) {
zeros = zeros1;
printf("%0*d", 32 - zeros, 0);
return binary1;
} else {
rest = value % 2;
if (rest >= 1) {
binary = binary1 * 10 + 1;
zeros = zeros1 + 1;
return print_binary1((value - 1) / 2, binary, zeros);
} else {
binary = binary1 * 10;
zeros = zeros1 + 1;
return print_binary1(value / 2, binary, zeros);
}
}
}
void
print_binary(uint32_t value)
{
printf("%" PRIu32, value);
if (value == 0) {
printf(" = 0b00000000000000000000000000000001");
} else {
printf(" = 0b");
int binary = print_binary1(value, 1, 0);
print_reverse(binary);
}
}
int
main(void)
{
uint32_t value;
printf("value: ");
if (scanf("%" SCNu32, &value) != 1) {
fprintf(stderr,
"ERROR: While reading the 'uint32_t' value an error occurred!");
return EXIT_FAILURE;
}
printf("\n");
print_binary(value);
printf("\n");
return EXIT_SUCCESS;
}
首先,除非您拥有几乎同一行代码的 32 个版本,否则不可能使用循环。
比如题中的代码使用了递归来实现循环。 (其实任何循环都可以用递归来实现。)但是还是在循环(重复执行相同的代码)。
在隐藏循环的同时实现您想要的效果的最简单方法是使用 snprintf
。
其余部分回答了为什么代码不适用于更大的数字。
看起来这会产生我 previously called "decimal-coded binary" (in reference to binary-coded decimal) 的结果,其中十进制表示的每个数字代表一个位。例如,它将十三(1101 基数 2)转换为一千一百零一(1101 基数 10)。
如果是这样,程序支持的最大输入是 1,1111,1111(基数 2),因为 10,0000,0000(基数 10)不适合 uint32_t
。换句话说,32 位输出支持 floor(log10(2^32-1)) = 9 位输入。表示程序支持编号从0到511,但不能超出。
通过切换到 64 位输出,您可以支持 floor(log10(2^64-1)) = 19 位输入,这仍然不足以满足您的需求。
你需要一种不同的方法。
“无循环”是一个愚蠢的约束。如果它是一个编程练习,它可能是有意义的,如果建议是使用一些替代循环,比如递归或循环展开,但这些实际上只是戴着假胡子并以明显编造的口音说话的循环。你需要输出32个字符,你只需要看32位就可以很容易地做到这一点。
无论如何,这是一种无需任何循环的方法,因为我只是展开了循环。 (我不会写 32 条语句,所以我稍微作弊并使用 table)。
// a table for 4-bit numbers to get us started...
char *bits[] = {
"0000",
"0001",
"0010",
"0011",
"0100",
"0101",
"0110",
"0111",
"1000",
"1001",
"1010",
"1011",
"1100",
"1101",
"1110",
"1111",
};
// brute force, which is essentially loop unrolling
void print_bits_brute(uint32_t i)
{
#define B(offset) bits[(i >> offset) & 0xf]
printf("0b%s%s%s%s%s%s%s%s\n",
B(28), B(24), B(20), B(16), B(12), B(8), B(4), B(0));
#undef B
}
展开发生在 print_bits_brute()
中,如您所见,如果只使用一个循环,这会容易得多。这样的循环可能如下所示:
void print_bits_loop(uint32_t i)
{
printf("0b");
for (int b = 28; b >= 0; b -= 4)
{
printf("%s", bits[(i >> b) & 0xf]);
}
printf("\n");
}
它做同样的事情。如果通过展开循环可以获得一些速度,编译器知道如何将循环中的常量转换为适当的东西,因此展开循环可能没有任何好处。
如果你必须递归地做,那很容易。它是另一个名称的循环。好吧,不完全是,因为这段代码不是尾递归的,但它已经足够接近了。
// b must be a power of two here...
void print_bits_b(uint32_t i, int b)
{
if (b == 4)
{
printf("%s", bits[i & 0xf]);
}
else
{
b >>= 1;
print_bits_b(i >> b, b);
print_bits_b(i, b);
}
}
void print_bits_recursive(uint32_t i)
{
printf("0b");
print_bits_b(i, 32);
printf("\n");
}
一个32位整数可以拆分成两个16位整数。这些 16 位整数可以拆分为四个 8 位整数,它们又可以拆分为八个 4 位整数。那些我们可以直接用 table.
处理的
如果有人能帮助我,我将非常高兴...
我应该编写一个程序,在不使用循环的情况下以二进制表示形式打印一个整数。它还需要以 32 位表示形式打印出数字。对于小数字(例如 256 仍然有效),下面的代码工作正常。对于大数字,我没有得到预期的输出。
有人知道我该如何解决这个问题吗?
非常感谢!
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
void
print_reverse(uint32_t value)
{
if (value % 10 == 0) {
if (value == 0) {
printf("1");
return;
} else {
printf("0");
print_reverse(value / 10);
}
} else {
if (value == 1) {
return;
} else {
printf("1");
print_reverse((value - 1) / 10);
}
}
return;
}
int
print_binary1(uint32_t value, uint32_t binary1, int zeros1)
{
int rest, binary, zeros;
if (value == 0) {
zeros = zeros1;
printf("%0*d", 32 - zeros, 0);
return binary1;
} else {
rest = value % 2;
if (rest >= 1) {
binary = binary1 * 10 + 1;
zeros = zeros1 + 1;
return print_binary1((value - 1) / 2, binary, zeros);
} else {
binary = binary1 * 10;
zeros = zeros1 + 1;
return print_binary1(value / 2, binary, zeros);
}
}
}
void
print_binary(uint32_t value)
{
printf("%" PRIu32, value);
if (value == 0) {
printf(" = 0b00000000000000000000000000000001");
} else {
printf(" = 0b");
int binary = print_binary1(value, 1, 0);
print_reverse(binary);
}
}
int
main(void)
{
uint32_t value;
printf("value: ");
if (scanf("%" SCNu32, &value) != 1) {
fprintf(stderr,
"ERROR: While reading the 'uint32_t' value an error occurred!");
return EXIT_FAILURE;
}
printf("\n");
print_binary(value);
printf("\n");
return EXIT_SUCCESS;
}
首先,除非您拥有几乎同一行代码的 32 个版本,否则不可能使用循环。
比如题中的代码使用了递归来实现循环。 (其实任何循环都可以用递归来实现。)但是还是在循环(重复执行相同的代码)。
在隐藏循环的同时实现您想要的效果的最简单方法是使用 snprintf
。
其余部分回答了为什么代码不适用于更大的数字。
看起来这会产生我 previously called "decimal-coded binary" (in reference to binary-coded decimal) 的结果,其中十进制表示的每个数字代表一个位。例如,它将十三(1101 基数 2)转换为一千一百零一(1101 基数 10)。
如果是这样,程序支持的最大输入是 1,1111,1111(基数 2),因为 10,0000,0000(基数 10)不适合 uint32_t
。换句话说,32 位输出支持 floor(log10(2^32-1)) = 9 位输入。表示程序支持编号从0到511,但不能超出。
通过切换到 64 位输出,您可以支持 floor(log10(2^64-1)) = 19 位输入,这仍然不足以满足您的需求。
你需要一种不同的方法。
“无循环”是一个愚蠢的约束。如果它是一个编程练习,它可能是有意义的,如果建议是使用一些替代循环,比如递归或循环展开,但这些实际上只是戴着假胡子并以明显编造的口音说话的循环。你需要输出32个字符,你只需要看32位就可以很容易地做到这一点。
无论如何,这是一种无需任何循环的方法,因为我只是展开了循环。 (我不会写 32 条语句,所以我稍微作弊并使用 table)。
// a table for 4-bit numbers to get us started...
char *bits[] = {
"0000",
"0001",
"0010",
"0011",
"0100",
"0101",
"0110",
"0111",
"1000",
"1001",
"1010",
"1011",
"1100",
"1101",
"1110",
"1111",
};
// brute force, which is essentially loop unrolling
void print_bits_brute(uint32_t i)
{
#define B(offset) bits[(i >> offset) & 0xf]
printf("0b%s%s%s%s%s%s%s%s\n",
B(28), B(24), B(20), B(16), B(12), B(8), B(4), B(0));
#undef B
}
展开发生在 print_bits_brute()
中,如您所见,如果只使用一个循环,这会容易得多。这样的循环可能如下所示:
void print_bits_loop(uint32_t i)
{
printf("0b");
for (int b = 28; b >= 0; b -= 4)
{
printf("%s", bits[(i >> b) & 0xf]);
}
printf("\n");
}
它做同样的事情。如果通过展开循环可以获得一些速度,编译器知道如何将循环中的常量转换为适当的东西,因此展开循环可能没有任何好处。
如果你必须递归地做,那很容易。它是另一个名称的循环。好吧,不完全是,因为这段代码不是尾递归的,但它已经足够接近了。
// b must be a power of two here...
void print_bits_b(uint32_t i, int b)
{
if (b == 4)
{
printf("%s", bits[i & 0xf]);
}
else
{
b >>= 1;
print_bits_b(i >> b, b);
print_bits_b(i, b);
}
}
void print_bits_recursive(uint32_t i)
{
printf("0b");
print_bits_b(i, 32);
printf("\n");
}
一个32位整数可以拆分成两个16位整数。这些 16 位整数可以拆分为四个 8 位整数,它们又可以拆分为八个 4 位整数。那些我们可以直接用 table.
处理的