You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将最长9999位的任意进制数(最高36进制)转换为目标进制?

问题描述

需要处理长度可达9999位的超大数字,无法通过常规int类型存储;支持最高36进制,大于9的数字用大写字母A-Z依次表示。已编写初步C语言代码,但对核心的convert函数实现思路模糊,寻求实现指导。现有代码如下:

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

#define LEN 1000

int exp(int expBase, int power) {
    unsigned int i = 1;
    int j;
    for (j = 0; j < power; j++)
        i *= expBase;
    return i;
}

void convert(char *num, int base1, int base2, int length) {
    char numC[LEN];
    int i;
}

int getNum(char *num) {
    int i = 0;
    char c;
    while ((c = fgetc(stdin)) != ' ') {
        num[i] = c;
        i++;
    }
    return i;
}

int main() {
    char num[LEN];
    int n, base1, base2, length;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        length = getNum(num);
        scanf("%d %d", &base1, &base2);
        convert(num, base1, base2, length);
    }
    return 0;
}

注:代码为初版未测试,错误不影响核心需求,重点求实现思路。


实现思路与代码建议

核心逻辑

由于数字长度远超常规整型范围,必须用数组模拟大整数运算,推荐两种实现路径:


路径1:先转十进制大整数,再转目标进制

分两步完成转换,逻辑直观易调试:

步骤1:原进制字符转十进制大整数数组

  1. 先实现字符转数值的辅助函数:
    int char_to_val(char c) {
        if (c >= '0' && c <= '9') return c - '0';
        else if (c >= 'A' && c <= 'Z') return 10 + (c - 'A');
        return -1; // 非法字符标记
    }
    
  2. 用数组存储十进制大整数(低位在前,方便后续除法操作):
    • 初始化足够大的数组(如int dec[10000] = {0};),记录有效长度dec_len。
    • 遍历输入字符,对数组执行dec = dec * base1 + 当前位数值,模拟大数乘法与加法:
      int dec[10000] = {0};
      int dec_len = 0;
      // 初始化第一位
      dec[dec_len++] = char_to_val(num[0]);
      for (int i = 1; i < length; i++) {
          int val = char_to_val(num[i]);
          int carry = 0;
          // 数组整体乘base1
          for (int j = 0; j < dec_len; j++) {
              int temp = dec[j] * base1 + carry;
              dec[j] = temp % 10;
              carry = temp / 10;
          }
          // 处理乘法进位
          while (carry > 0) {
              dec[dec_len++] = carry % 10;
              carry /= 10;
          }
          // 加上当前位数值
          carry = val;
          int j = 0;
          while (carry > 0 && j < dec_len) {
              int temp = dec[j] + carry;
              dec[j] = temp % 10;
              carry = temp / 10;
              j++;
          }
          while (carry > 0) {
              dec[dec_len++] = carry % 10;
              carry /= 10;
          }
      }
      

步骤2:十进制大整数转目标进制

用除基取余法,不断将数组除以base2,收集余数后倒序输出:

  1. 实现数值转字符的辅助函数:
    char val_to_char(int val) {
        if (val >= 0 && val <= 9) return '0' + val;
        else if (val >= 10 && val <= 35) return 'A' + (val - 10);
        return '?'; // 非法数值标记
    }
    
  2. 执行除基取余:
    char result[10000];
    int res_len = 0;
    while (dec_len > 0) {
        int remainder = 0;
        // 模拟大数除以base2,商保留在原数组
        for (int j = dec_len - 1; j >= 0; j--) {
            int temp = remainder * 10 + dec[j];
            dec[j] = temp / base2;
            remainder = temp % base2;
        }
        // 移除高位无效0
        while (dec_len > 0 && dec[dec_len - 1] == 0) {
            dec_len--;
        }
        // 记录余数
        result[res_len++] = val_to_char(remainder);
    }
    // 倒序输出结果
    for (int i = res_len - 1; i >= 0; i--) {
        printf("%c", result[i]);
    }
    printf("\n");
    

路径2:直接对原进制数执行除基取余(更高效)

跳过中间十进制转换,直接对原进制数值数组执行除基取余,减少运算量:

  1. 先将输入字符转成原进制数值数组:
    int src[10000];
    int src_len = length;
    for (int i = 0; i < length; i++) {
        src[i] = char_to_val(num[i]);
    }
    
  2. 循环执行除基取余:
    char result[10000];
    int res_len = 0;
    while (src_len > 0) {
        int remainder = 0;
        // 从高位到低位做除法
        for (int i = 0; i < src_len; i++) {
            int temp = remainder * base1 + src[i];
            src[i] = temp / base2;
            remainder = temp % base2;
        }
        // 移除高位无效0
        while (src_len > 0 && src[0] == 0) {
            for (int i = 0; i < src_len - 1; i++) {
                src[i] = src[i + 1];
            }
            src_len--;
        }
        result[res_len++] = val_to_char(remainder);
    }
    // 倒序输出结果
    for (int i = res_len - 1; i >= 0; i--) {
        printf("%c", result[i]);
    }
    printf("\n");
    

原代码的修正建议

  1. 删除无用的exp函数:该函数会因指数过大直接溢出,完全无法处理大数场景。
  2. 扩容长度限制:原LEN=1000不足以存储9999位数字,建议改为#define MAX_LEN 10000。
  3. 修复getNum函数:补充数组越界检查与字符串结束符,处理换行符场景:
    int getNum(char *num, int max_len) {
        int i = 0;
        char c;
        while ((c = fgetc(stdin)) != EOF && c != ' ' && c != '\n') {
            if (i < max_len - 1) { // 留一位存储字符串结束符
                num[i++] = c;
            }
        }
        num[i] = '\0';
        return i;
    }
    

内容的提问来源于stack exchange,提问作者Someone Someone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 15:37:13