Dec 到 bin 转换器函数向后打印结果
Dec to bin converter function printing result out backwards
作为练习的一部分,我必须重写一个递归函数,使新函数不递归。这两个函数都需要将正十进制整数输入转换为它们的二进制等价物。
这是使用递归的代码:
void convert(int n) { //recursive
if (n > 0) {
convert(n/2);
printf("%d", n%2);
}
return;
}
这是我的代码:
void convert(int n) { //non-recursive
while (n > 0) {
printf("%d", n%2);
n/=2;
}
return;
}
我的代码的问题是,可以理解的是,我的二进制转换被倒着打印出来。比如我输入数字8,我的函数returns0001,如果我输入2,返回01等等
对于仅使用 stdio.h
库的快速修复有什么建议吗?
这是一个非递归版本,它产生与递归版本相同的结果并且不需要数组:
void convert(int n) {
int s;
for (s = 1; n/s/2 > 0; s *= 2)
;
for (; s >= 1; s /= 2) {
printf("%d", (n/s) % 2);
}
}
此版本处理零数和大数(但不处理负数)。
您可以在一个循环中执行此操作:
if(num == 0) {
printf("0\n"); // Check for num being 0.
return;
}
num = num < 0 ? num*-1 : num; // Make sure the number has no sign bit.
char first1Found = 0; // Create a check for the first 1 printed.
for (int i = sizeof(num)*8 - 1; i >= 0 ; --i) {
if (num & (1 << i)) { // If its a 1, print it and set the first1Found bool.
printf("1");
first1Found = 1;
} else if(first1Found) { // If its a 0 only print it if its not a leading 0.
printf("0");
}
}
printf("\n");
注意:我假设类型中有 sizeof
returns 个字节,因此使用了 8。这可能不适用于所有系统和编译器(尽管应该如此)。按照@chux 的建议,一种更便携的方法可能是使用 <limits.h>
中的 CHAR_BIT
。
这里有一个变体,它明确说明了使用位掩码并将掩码的位置从上端向下移动。它的行为就像你的递归版本,因为它不做负数或零。
void convert(int n) {
for(int mask = 1 << (8 * sizeof(n) - 2); mask > 0; mask >>= 1) {
if (mask <= n) {
putchar((n & mask) ? '1' : '0');
}
}
putchar('\n');
}
打印无符号值的未填充二进制表示的可靠方法(能够适合 long unsigned
的任何大小)是:
/** unpadded binary representation of 'v'. */
void binprn (const unsigned long v)
{
if (!v) { putchar ('0'); return; };
size_t sz = sizeof v * CHAR_BIT;
unsigned long rem = 0;
while (sz--)
if ((rem = v >> sz))
putchar ((rem & 1) ? '1' : '0');
}
(CHAR_BIT
(通常是8
)在limits.h
中提供)。您不需要“需要”来使用 limits.h
—— 那正是通常可以找到 CHAR_BIT
的地方。您只需要一个常量,您可以随意称呼它。我一般只用:
/* CHAR_BIT */
#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif
C99 变体 很好的答案,处理所有 + 和 - 值,包括 INT_MIN
.
void convertm(int n) {
if (n < 0) {
putchar('-');
} else {
n = -n;
}
// Build up a negative power-of-2 that meets/exceeds `n`
int npow2;
for (npow2 = -1; n/2 <= npow2 ; npow2 *= 2)
;
// For each negative power-of-2 ...
while (npow2) {
putchar(n / npow2 + '0');
n %= npow2;
npow2 /= 2;
}
puts("");
}
作为练习的一部分,我必须重写一个递归函数,使新函数不递归。这两个函数都需要将正十进制整数输入转换为它们的二进制等价物。
这是使用递归的代码:
void convert(int n) { //recursive
if (n > 0) {
convert(n/2);
printf("%d", n%2);
}
return;
}
这是我的代码:
void convert(int n) { //non-recursive
while (n > 0) {
printf("%d", n%2);
n/=2;
}
return;
}
我的代码的问题是,可以理解的是,我的二进制转换被倒着打印出来。比如我输入数字8,我的函数returns0001,如果我输入2,返回01等等
对于仅使用 stdio.h
库的快速修复有什么建议吗?
这是一个非递归版本,它产生与递归版本相同的结果并且不需要数组:
void convert(int n) {
int s;
for (s = 1; n/s/2 > 0; s *= 2)
;
for (; s >= 1; s /= 2) {
printf("%d", (n/s) % 2);
}
}
此版本处理零数和大数(但不处理负数)。
您可以在一个循环中执行此操作:
if(num == 0) {
printf("0\n"); // Check for num being 0.
return;
}
num = num < 0 ? num*-1 : num; // Make sure the number has no sign bit.
char first1Found = 0; // Create a check for the first 1 printed.
for (int i = sizeof(num)*8 - 1; i >= 0 ; --i) {
if (num & (1 << i)) { // If its a 1, print it and set the first1Found bool.
printf("1");
first1Found = 1;
} else if(first1Found) { // If its a 0 only print it if its not a leading 0.
printf("0");
}
}
printf("\n");
注意:我假设类型中有 sizeof
returns 个字节,因此使用了 8。这可能不适用于所有系统和编译器(尽管应该如此)。按照@chux 的建议,一种更便携的方法可能是使用 <limits.h>
中的 CHAR_BIT
。
这里有一个变体,它明确说明了使用位掩码并将掩码的位置从上端向下移动。它的行为就像你的递归版本,因为它不做负数或零。
void convert(int n) {
for(int mask = 1 << (8 * sizeof(n) - 2); mask > 0; mask >>= 1) {
if (mask <= n) {
putchar((n & mask) ? '1' : '0');
}
}
putchar('\n');
}
打印无符号值的未填充二进制表示的可靠方法(能够适合 long unsigned
的任何大小)是:
/** unpadded binary representation of 'v'. */
void binprn (const unsigned long v)
{
if (!v) { putchar ('0'); return; };
size_t sz = sizeof v * CHAR_BIT;
unsigned long rem = 0;
while (sz--)
if ((rem = v >> sz))
putchar ((rem & 1) ? '1' : '0');
}
(CHAR_BIT
(通常是8
)在limits.h
中提供)。您不需要“需要”来使用 limits.h
—— 那正是通常可以找到 CHAR_BIT
的地方。您只需要一个常量,您可以随意称呼它。我一般只用:
/* CHAR_BIT */
#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif
C99 变体 INT_MIN
.
void convertm(int n) {
if (n < 0) {
putchar('-');
} else {
n = -n;
}
// Build up a negative power-of-2 that meets/exceeds `n`
int npow2;
for (npow2 = -1; n/2 <= npow2 ; npow2 *= 2)
;
// For each negative power-of-2 ...
while (npow2) {
putchar(n / npow2 + '0');
n %= npow2;
npow2 /= 2;
}
puts("");
}