1

我正在尝试创建一种算法,可以将基数为 10 的数字转换为基数为 n 的数字,其中 n 最多为 10。但是,由于某些奇怪的原因,C 中的以下算法在每个基数的某些关键点失败。例如,对于以 2 为底和以 3 为底的转换,所有直到 1023 和 52,487 的数字都可以工作,但超出的数字会产生一些奇怪的负面结果。我不知道为什么会这样;谁能帮我?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int returnint;

int baseconvert(int number,int base) {
    if(number == 0 || base == 10) {
        return returnint;
    }
    returnint = (number % base) + (10 * baseconvert(number / base, base));
    return returnint;
}

int main() {
    fprintf(stdout,"%d\n",baseconvert(1023,2));
    fprintf(stdout,"%d\n",baseconvert(52487,3));
}

编辑:

以下是上述打印语句的打印结果,如果有帮助的话:

1410065408
-2094967296
4

4 回答 4

1

您的算法在数字与基数的范围内非常有限。基数越小,表示它所需的数字就越多。而且由于您以十进制形式存储结果,您将很快浪费可用的数据范围。没有基本数据类型可以保存所有可能输入的结果。例如,最大 31 位十进制数(普通整数,去掉符号位)将导致 31 位输出!

您有几种选择来应对这种情况:

  • 分配一个足够大的堆栈并将数字压入其中。完成后,打印堆栈内容。
  • 立即打印数字而不保存,这将消除分配任何内容的需要。例如:

#include <stdio.h>

void baseconvert(int number,int base) 
{
    if(number > 0) 
    {
        int digit = (number % base);
        baseconvert(number / base, base);
        printf("%d",digit);
    }
    else
    {
        printf("\n");
    }
}

int main() 
{
    baseconvert(1023,2);
    baseconvert(52487,3);
}
于 2014-07-23T18:14:12.300 回答
0

看起来整数值溢出了。例如,以 2 为底的十进制值 1023 是 1111111111。如果它是 4 字节整数,那么在尝试“添加”一位数字时它会溢出(本例中的最大有符号整数为 2147483647)。

由于您的目标似乎是以不同的基数显示数字,因此将数字存储在字符数组中可能更有意义。

于 2014-07-23T17:10:20.970 回答
0

在我所知道的所有处理器上,整数已经以二进制形式存储;这意味着基数 2。这个值可以显示在您想要的任何基数中,您需要做一些工作。printf() 和朋友允许您轻松地以基数 10 (%d) 和基数 16 (%x) 打印。不难想象有一种方法可以将二进制(以 2 为基数)整数值转换为以 n 为基数的字符表示。

我严重怀疑您是否真的打算像您所做的那样更改整数的实际值。就像上面的@ThoAppelsin 所说,袋子里的苹果数量保持不变,不管你选择哪个底座来展示。

通过简单地创建一个表示(用数字)任何基数的整数的方法,您还将解决溢出问题!

于 2014-07-23T18:26:33.240 回答
0

您的结果超出了整数范围。尝试改用字符串。这是依赖字符串来表示数字的伪代码,它可以将数字从任何基数转换为 2 到 36 之间的任何其他基数(使用数字和大写字母):

function ConvertNumber(number, b, d)
begin
    newNumber = ""
    while number <> "0"
        begin
            number = Divide(number, b, d, out remainder)
            newDigit = ValueToDigit(remainder)
            newNumber = Concatenate(newDigit, newNumber)
        end
    if newNumber ="" then
        newNumber = "0"
end

function Divide(number, base, divisor, out remainder)
begin
    remainder = 0
    result = ""
    for i = 0 to Length(number) - 1
        begin
            digitValue = DigitToValue(number[i])
            remainder = base * remainder + digitValue
            newDigitValue = remainder / divisor -- integer division
            remainder = remainder mod divisor
            if newDigitValue > 0 OR result <> "" then
                newDigit = ValueToDigit(newDigitValue)
                result = Concatenate(result, newDigit)
        end
    if result = "" then
        result = "0"
    return result
end

你可以在这篇文章中找到整个数学和实现:转换数字基数

于 2015-06-17T12:44:40.070 回答