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

二进制字符串转十进制函数超出32位后结果异常求助

二进制字符串转十进制:超长串溢出问题解决

你的问题核心在于固定长度整数类型的位数限制导致溢出。size_t的长度依赖系统:32位系统下是32位,64位系统下是64位。当二进制字符串长度超过对应位数时,r << 1操作会触发无符号整数溢出——根据C标准,无符号溢出会按2^N(N为类型位数)取余,最终得到的是截断后的值,并非完整的十进制结果。

下面是几种针对性的解决方案:

方案1:用更大的标准整数类型(适配≤64位二进制串)

如果你的二进制串长度不超过64位,可以改用unsigned long long类型(C99及以上标准支持),它的位数至少是64位,能覆盖更长的二进制串:

#include <stdio.h>

unsigned long long strBinaryToDecimal(char* s)
{
    char c;
    char *p = s;
    unsigned long long r = 0;

    while (p && *p)
    {
        c = *p++;
        if (c == '0') {
            r = (r << 1);
        } else if (c == '1') {
            r = (r << 1) + 1;
        } else {
            break;
        }
    }
    return r;
}

int main(void)
{
    char reading[33] = "100110011001100110011001100110011";
    printf("Binary: %s\n", reading);
    printf("Decimal: %llu\n", strBinaryToDecimal(reading));
    return 0;
}

注意:这种方法最多处理64位二进制串,超过后仍会溢出。

方案2:字符串模拟十进制运算(支持任意长度二进制串)

要处理任意长度的二进制串,必须用字符串存储十进制结果,模拟手工计算逻辑:每读取一位二进制,就将当前十进制结果乘2,再加上当前位的0或1。

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

// 二进制字符串转十进制字符串,结果存入dec_str(需提前分配足够空间)
void strBinaryToDecimalStr(char* s, char* dec_str)
{
    // 初始化十进制字符串为"0"
    strcpy(dec_str, "0");
    char *p = s;
    int dec_len = 1;

    while (p && *p)
    {
        int bit = *p++ - '0';
        if (bit != 0 && bit != 1) break;

        // 步骤1:十进制数乘2
        int carry = 0;
        for (int i = dec_len - 1; i >= 0; i--)
        {
            int val = (dec_str[i] - '0') * 2 + carry;
            dec_str[i] = (val % 10) + '0';
            carry = val / 10;
        }
        // 处理乘法进位
        if (carry != 0)
        {
            memmove(dec_str + 1, dec_str, dec_len);
            dec_str[0] = carry + '0';
            dec_len++;
        }

        // 步骤2:加上当前二进制位的值
        if (bit == 1)
        {
            carry = 1;
            for (int i = dec_len - 1; i >= 0 && carry; i--)
            {
                int val = (dec_str[i] - '0') + carry;
                dec_str[i] = (val % 10) + '0';
                carry = val / 10;
            }
            // 处理加法进位
            if (carry != 0)
            {
                memmove(dec_str + 1, dec_str, dec_len);
                dec_str[0] = carry + '0';
                dec_len++;
            }
        }
    }
}

int main(void)
{
    char reading[100] = "1001100110011001100110011001100111110000";
    char dec_str[200] = {0}; // 分配足够大的存储空间

    strBinaryToDecimalStr(reading, dec_str);
    printf("Binary: %s\n", reading);
    printf("Decimal: %s\n", dec_str);
    return 0;
}

该方法支持任意长度的二进制串,只要提前为dec_str分配足够的空间即可。

方案3:使用标准库函数(适配≤ULLONG_MAX的二进制串)

C标准库的strtoull函数可以直接将二进制字符串转为unsigned long long,还能检测溢出:

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

int main(void)
{
    char reading[33] = "100110011001100110011001100110011";
    char *endptr;
    errno = 0;
    unsigned long long val = strtoull(reading, &endptr, 2);

    if (errno == ERANGE)
    {
        printf("二进制字符串超出unsigned long long的范围\n");
    }
    else if (*endptr != '\0')
    {
        printf("二进制字符串包含无效字符\n");
    }
    else
    {
        printf("Binary: %s\n", reading);
        printf("Decimal: %llu\n", val);
    }
    return 0;
}

当二进制串超过unsigned long long的最大值时,errno会被设为ERANGE,可据此处理溢出场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 23:25:14