首页 > 解决方案 > 如何在 C 中巧妙地将 32 位以上的数字(38 位)转换为 32 位系统上的字符串

问题描述

如果可用的最大数据格式是 32 位,您将如何将 38 位数字转换为字符串?

需要十进制表示,需要字符串以便将数字保存到 csv 文件中。

问题是“原样”完整的,无需在其他地方寻找问题的感知真实意图。

标签: c

解决方案


这应该行得通。它使用静态数组来存储结果,因此如果您不希望它们被下一次调用破坏,则需要安排将它们复制到其他地方。

算法很简单。它只是使用长除法将数字反复除以 10,并在每次迭代时使用余数来构建文本输出。我假设输入由大端顺序的 5 个字节数组组成。您可以通过更改 的值轻松地将其更改为使用更大的数字BIG_WORD_LENGTH。我还应该指出,这个函数根本不适用于负数。当 n 达到零时,您可以通过退出主循环来加快速度。

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

#define BIG_WORD_LENGTH 5

// Length of output is at most ceil(BIG_WORD_LENGTH * log(256) / log(10))
// The following is a slight overestimate, but close enough
#define BIG_WORD_STRLEN (3 + (BIG_WORD_LENGTH) * 5 / 2)

typedef uint8_t big_word[BIG_WORD_LENGTH];

char *big_word_2_str(big_word num) {
    // Make a local copy of the number
    big_word n;
    for (int i=0; i<BIG_WORD_LENGTH; i++) {
        n[i] = num[i];
    }

    // Result goes here
    static char result[BIG_WORD_STRLEN];
    int p = BIG_WORD_STRLEN-1;
    result[p--] = '\0';

    // Calculate digits in base 10
    for (int i=1; i<BIG_WORD_STRLEN; i++) {
        int x, tmp = 0;
        for (int j=0; j<BIG_WORD_LENGTH; j++) {
            x = n[j];
            x += tmp << 8;
            tmp = x % 10;
            n[j] = x / 10;
        }
        result[p--] = '0' + tmp;
    }

    // Trim leading zeros
    while (++p < BIG_WORD_STRLEN-2 && result[p] == '0');

    return result + p;
}


// Test:
int main() {
    // 0x492559f64f = 314159265359
    big_word x = { 0x49, 0x25, 0x59, 0xf6, 0x4f };
    puts(big_word_2_str(x));
    return 0;
}

推荐阅读