我一直在编写一个代码,可以将给定的数字(十进制)转换为从2到16的任何其他基数。
显然,我遇到了函数base_conversion_it
(它代表迭代)反向打印值的问题。
我不能使用数组和指针,互联网上的每个人似乎都这样解决这个问题。我的作业要求制作一个迭代函数和一个递归函数(我这样做了,并且成功了)。
void base_conversion_it(unsigned int n, unsigned int b) {
if (n > 0) {
//bases between 2 and 16
if (b >= 2 && b <= 16) {
int r; //r = remainder
int q = 1; //quotient
int num; //saves the remainder
while (q != 0) {
r = n % b;
printf("%X", r);
q = n / b;
n = q;
}
}
}
}
从单位数字开始转换。
也许从最高位开始呢?
// It's Undefined Behaviour if `b` is outside the range [2...16]
void base_conversion_it(unsigned int n, unsigned int b) {
unsigned highestbase = 1;
while (highestbase * b <= n) highestbase *= b; //possible wrap around and infinite loop
while (highestbase) {
printf("%X", n / highestbase);
n %= highestbase;
highestbase /= b;
}
printf("n");
}
抱歉错过了迭代。
char digits[] = "0123456789ABCDEFGHIJKLMNOP";
void print(unsigned long long val, unsigned base)
{
unsigned long long mask = base;
while(val / mask >= base) mask *= base;
do
{
printf("%c", digits[val / mask]);
val %= mask;
mask /= base;
}while(val);
}
int main(void)
{
print(45654756453, 10); printf("n");
print(45654756453, 16); printf("n");
print(45654756453, 24); printf("n");
print(45654756453, 2); printf("n");
}
https://godbolt.org/z/W3fGnnhYs
递归:
char digits[] = "0123456789ABCDEF";
void print(unsigned long long val, unsigned base)
{
if(base <= 16 && base > 1)
{
if(val >= base) print(val / base, base);
printf("%c", digits[val % base]);
}
}
https://godbolt.org/z/84hYocnjv
如果您不能使用数组(包括字符串)或递归,那么我认为您需要以最重要的第一顺序计算输出数字。这比以相反的顺序计算它们并反转结果有点不自然,但可以这样做:
-
使用循环查找
n
的最高非零基数b
位的位值。例如,检查n
除以b
的连续幂的结果,直到结果为0,然后后退一步。 -
在单独的循环中,从发现的最高有效位开始,逐个读取
n
的b
位。对于每个数字- 用
n
的当前值除以当前数字的位值pv
得到一个数字值 - 用
n % pv
代替n
要小心,一直到位置值1,而不是在
n
变为0时停止。 - 用