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

求JavaScript实现密集BCD转十进制函数(支持3位及以上数字)

密集BCD转十进制的JavaScript实现(反向工程版)

需求概述

现有一个将十进制转换为密集BCD(Packed BCD)的JavaScript函数dec_to_densely,需要对其进行反向工程,实现一个可将密集BCD转换为十进制的函数,要求支持3位及以上十进制数字的转换。

原十进制转密集BCD函数代码

function dec_to_densely(x, packed){
    const holder = packed.split("");
    let densely_packed = new Array(10);
    let merge = new Array(10000);

    if (x.length % 3 != 0) {
        if (x.length % 3 == 1){
            for (let i = 0; i < 8; i++){
                holder.unshift(0);
            }
        } else {
            for (let i = 0; i < 4; i++){
                holder.unshift(0);
            }
        }
    }

    while (holder.length > 0) {
        densely_packed[5] = holder[7];
        densely_packed[9] = holder[11];

        //000
        if (holder[0] == '0' && holder[4] == '0' && holder[8] == '0') {
            for (let i = 0; i < 3; i++){
                densely_packed[i] = holder[i + 1];
            }
            for (let i = 3; i < 5; i++){
                densely_packed[i] = holder[i + 2];
            }
            densely_packed[6] = '0';
            for (let i = 7; i < 10; i++){
                densely_packed[i] = holder[i + 2];
            }
        }
        //001
        else if (holder[0] == '0' && holder[4] == '0' && holder[8] == '1') {
            for (let i = 0; i < 3; i++){
                densely_packed[i] = holder[i + 1];
            }
            for (let i = 3; i < 5; i++){
                densely_packed[i] = holder[i + 2];
            }
            densely_packed[6] = '1';
            densely_packed[7] = '0';
            densely_packed[8] = '0';
        }
        //010
        else if (holder[0] == '0' && holder[4] == '1' && holder[8] == '0') {
            for (let i = 0; i < 3; i++){
                densely_packed[i] = holder[i + 1];
            }
            densely_packed[3] = holder[9];
            densely_packed[4] = holder[10];
            densely_packed[6] = '1';
            densely_packed[7] = '0';
            densely_packed[8] = '1';
        }
        //011
        else if (holder[0] == '0' && holder[4] == '1' && holder[8] == '1') {
            for (let i = 0; i < 3; i++){
                densely_packed[i] = holder[i + 1];
            }
            densely_packed[3] = '1';
            densely_packed[4] = '0';
            densely_packed[6] = '1';
            densely_packed[7] = '1';
            densely_packed[8] = '1';
        }
        //100
        else if (holder[0] == '1' && holder[4] == '0' && holder[8] == '0') {
            densely_packed[0] = holder[9];
            densely_packed[1] = holder[10];
            densely_packed[2] = holder[3];
            densely_packed[3] = holder[5];
            densely_packed[4] = holder[6];
            densely_packed[6] = '1';
            densely_packed[7] = '1';
            densely_packed[8] = '0';
        }
        //101
        else if (holder[0] == '1' && holder[4] == '0' && holder[8] == '1') {
            densely_packed[0] = holder[5];
            densely_packed[1] = holder[6];
            densely_packed[2] = holder[3];
            densely_packed[3] = '0';
            densely_packed[4] = '1';
            densely_packed[6] = '1';
            densely_packed[7] = '1';
            densely_packed[8] = '1';
        }
        //110
        else if (holder[0] == '1' && holder[4] == '1' && holder[8] == '0') {
            densely_packed[0] = holder[9];
            densely_packed[1] = holder[10];
            densely_packed[2] = holder[3];
            densely_packed[3] = '0';
            densely_packed[4] = '0';
            densely_packed[6] = '1';
            densely_packed[7] = '1';
            densely_packed[8] = '1';
        }
        //111
        else if (holder[0] == '1' && holder[4] == '1' && holder[8] == '1') {
            densely_packed[0] = '0';
            densely_packed[1] = '0';
            densely_packed[2] = holder[3];
            densely_packed[3] = '1';
            densely_packed[4] = '1';
            densely_packed[6] = '1';
            densely_packed[7] = '1';
            densely_packed[8] = '1';
        }

        merge = merge.concat(densely_packed);

        for (let i = 0; i < 12; i++){
            holder.shift()
        }
    }

    let dpacked = merge.join("");
    return packed;
}

反向实现:密集BCD转十进制函数

function densely_to_dec(denselyPackedStr, originalDecLength) {
    // 按每10位拆分密集BCD(原函数每组生成10位)
    const chunks = [];
    let temp = denselyPackedStr.split('');
    while (temp.length > 0) {
        chunks.push(temp.splice(0, 10));
    }

    let unpacked = [];

    // 反向处理每个10位的密集BCD块
    chunks.forEach(chunk => {
        const holder = new Array(12);
        holder[7] = chunk[5];
        holder[11] = chunk[9];

        // 根据原函数的8种分支反向推导原始holder值
        switch (`${chunk[6]}${chunk[7]}${chunk[8]}`) {
            case '000':
                // 对应原函数000分支
                for (let i = 0; i < 3; i++) holder[i+1] = chunk[i];
                for (let i = 3; i <5; i++) holder[i+2] = chunk[i];
                for (let i =7; i<10; i++) holder[i+2] = chunk[i];
                holder[0] = '0';
                holder[4] = '0';
                holder[8] = '0';
                break;
            case '100':
                // 对应原函数001分支
                for (let i =0; i<3; i++) holder[i+1] = chunk[i];
                for (let i=3; i<5; i++) holder[i+2] = chunk[i];
                holder[0] = '0';
                holder[4] = '0';
                holder[8] = '1';
                break;
            case '101':
                // 对应原函数010分支
                for (let i=0; i<3; i++) holder[i+1] = chunk[i];
                holder[9] = chunk[3];
                holder[10] = chunk[4];
                holder[0] = '0';
                holder[4] = '1';
                holder[8] = '0';
                break;
            case '111':
                // 先判断是否是011分支
                if (chunk[3] === '1' && chunk[4] === '0') {
                    for (let i=0; i<3; i++) holder[i+1] = chunk[i];
                    holder[0] = '0';
                    holder[4] = '1';
                    holder[8] = '1';
                } 
                // 101分支
                else if (chunk[3] === '0' && chunk[4] === '1') {
                    holder[5] = chunk[0];
                    holder[6] = chunk[1];
                    holder[3] = chunk[2];
                    holder[0] = '1';
                    holder[4] = '0';
                    holder[8] = '1';
                }
                // 110分支
                else if (chunk[3] === '0' && chunk[4] === '0') {
                    holder[9] = chunk[0];
                    holder[10] = chunk[1];
                    holder[3] = chunk[2];
                    holder[0] = '1';
                    holder[4] = '1';
                    holder[8] = '0';
                }
                // 111分支
                else if (chunk[3] === '1' && chunk[4] === '1') {
                    holder[3] = chunk[2];
                    holder[0] = '1';
                    holder[4] = '1';
                    holder[8] = '1';
                }
                break;
            case '110':
                // 对应原函数100分支
                holder[9] = chunk[0];
                holder[10] = chunk[1];
                holder[3] = chunk[2];
                holder[5] = chunk[3];
                holder[6] = chunk[4];
                holder[0] = '1';
                holder[4] = '0';
                holder[8] = '0';
                break;
        }

        // 将holder中的有效位加入结果
        unpacked = unpacked.concat(holder.filter(bit => bit !== undefined));
    });

    // 根据原始十进制长度去掉前导补的0
    let leadingZerosToRemove = 0;
    if (originalDecLength %3 ===1) leadingZerosToRemove =8;
    else if (originalDecLength %3 ===2) leadingZerosToRemove =4;

    if (leadingZerosToRemove >0) {
        unpacked.splice(0, leadingZerosToRemove);
    }

    // 将BCD位转换为十进制数字(每4位对应一个十进制数)
    let decStr = '';
    for (let i=0; i<unpacked.length; i+=4) {
        const bcdDigit = unpacked.slice(i, i+4).join('');
        decStr += parseInt(bcdDigit, 2).toString();
    }

    // 去掉可能的前导零(如果原始数没有前导零的话)
    return decStr.replace(/^0+/, '') || '0';
}

函数说明

  1. 分组处理:原函数每12位BCD生成10位密集BCD,反向函数先将输入的密集BCD按每10位拆分处理。
  2. 分支反向推导:根据原函数的8种分支条件(由标识位组合判断),反向推导出原始的BCD位数据。
  3. 去除补位零:原函数会根据十进制长度补前导零(1位补8个,2位补4个),反向函数需要根据原始十进制长度去掉这些补位零。
  4. BCD转十进制:将还原后的BCD数据按每4位一组转换为十进制数字,拼接成最终结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 22:34:53