作为练习的一部分,我必须重写一个递归函数,以便新函数不是递归的。这两个函数都需要将正十进制整数输入转换为二进制等效值。
这是使用递归的代码:
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,我的函数返回0001,如果我输入2,则返回01,等等。
有关仅使用stdio.h
库进行快速修复的建议吗?
答案 0 :(得分:4)
这是一个非递归版本,它产生与递归版本相同的结果,不需要数组:
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);
}
}
此版本处理零和大数字(但不是负数)。
答案 1 :(得分:1)
您可以在一个循环中执行此操作:
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
返回一个类型的字节,我使用了8。所有系统和编译器可能都不是这样(尽管应该如此)。一种更便携的方法可能是使用CHAR_BIT
中的<limits.h>
,如@chux所建议的那样。
答案 2 :(得分:0)
这里有一个关于使用位掩码和从上端向下移动掩码位置的变体。它的行为类似于递归版本,因为它不会做负数或零。
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');
}
答案 3 :(得分:0)
打印无符号值(任何能够在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
答案 4 :(得分:0)
@Tom Karzes精确答案的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("");
}