【问题标题】:Algorithm to convert a String of decimal digits to BCD将十进制数字字符串转换为 BCD 的算法
【发布时间】:2015-01-21 22:01:18
【问题描述】:

我正在寻找一种将字符串转换为等效 BCD 的方法。我使用 Java,但这确实不是语言的问题。我正在尝试逐步了解如何将字符串转换为 BCD。

例如,假设我有以下字符串;

"0200" (This string has four ASCII characters, if we were in java this string had been contained in a byte[4] where byte[0] = 48, byte[1] = 50, byte[2] = 48 and byte[3] = 48)

在 BCD 中(根据此页面:http://es.wikipedia.org/wiki/Decimal_codificado_en_binario):

0 = 0000
2 = 0010
0 = 0000
0 = 0000

好的,我认为转换是正确的,但我必须将其保存在一个字节 [2] 中。我应该怎么做?之后,我必须读取 BCD 并将其转换为原始字符串“0200”,但首先我必须将 String 解析为 BCD。

【问题讨论】:

  • 每个字节有两个 BCD 数字。一个在高 4 位,一个在低 4 位。因此,使用 BCD 时,四个十进制数字完全适合两个字节。
  • @genisage 该字符串只有 0 到 9 之间的数字。
  • 提示:您需要使用按位运算符,例如 shift 和 or。
  • @markspace 是的,但是我如何将这四个 BCD 数字保存到一个字节 [2] 中?
  • 把它分解成更小的部分。如何将两个数字放入一个字节,以及如何将两个字节放入byte[2].

标签: java arrays string bcd


【解决方案1】:

找到一个实用程序类来为您执行此操作。肯定有人为 Java 编写了 BCD 转换实用程序。

给你。我用谷歌搜索了“BCD Java”并得到了this as the first result。在此处复制代码以供将来参考。

public class BCD {

    /*
     * long number to bcd byte array e.g. 123 --> (0000) 0001 0010 0011
     * e.g. 12 ---> 0001 0010
     */
    public static byte[] DecToBCDArray(long num) {
        int digits = 0;

        long temp = num;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }

        int byteLen = digits % 2 == 0 ? digits / 2 : (digits + 1) / 2;
        boolean isOdd = digits % 2 != 0;

        byte bcd[] = new byte[byteLen];

        for (int i = 0; i < digits; i++) {
            byte tmp = (byte) (num % 10);

            if (i == digits - 1 && isOdd)
                bcd[i / 2] = tmp;
            else if (i % 2 == 0)
                bcd[i / 2] = tmp;
            else {
                byte foo = (byte) (tmp << 4);
                bcd[i / 2] |= foo;
            }

            num /= 10;
        }

        for (int i = 0; i < byteLen / 2; i++) {
            byte tmp = bcd[i];
            bcd[i] = bcd[byteLen - i - 1];
            bcd[byteLen - i - 1] = tmp;
        }

        return bcd;
    }

    public static String BCDtoString(byte bcd) {
        StringBuffer sb = new StringBuffer();

        byte high = (byte) (bcd & 0xf0);
        high >>>= (byte) 4; 
        high = (byte) (high & 0x0f);
        byte low = (byte) (bcd & 0x0f);

        sb.append(high);
        sb.append(low);

        return sb.toString();
    }

    public static String BCDtoString(byte[] bcd) {

        StringBuffer sb = new StringBuffer();

        for (int i = 0; i < bcd.length; i++) {
            sb.append(BCDtoString(bcd[i]));
        }

        return sb.toString();
    }
}

还有这个问题:Java code or lib to decode a binary-coded decimal (BCD) from a String

【讨论】:

  • 感谢您的回答@gknicker,但进一步我试图了解我必须做什么的代码
  • 哈哈,我很高兴我早已被遗忘的要点 sn-p 偷偷溜到了 SO。为了方便,我只是包含了一个主要的测试方法来响应 gist 文件中的评论。
  • 如果提供的位数为 3 或 5 或 7,则此代码会生成前导零,如果数字除以 2,则效果很好。是否需要前导零?为什么?是否有一个版本可以生成不带前导零的 BCD 字节数组,无论是否提供 3 位或 4 位数字作为输入?
【解决方案2】:

第一步是将字符串解析为 int,以便获得它的数值。然后,使用除法和模数得到单个数字,并使用移位和加法(或移位和或)将每对数字打包成一个字节。

或者,您可以将字符串的每个字符单独解析为一个 int,并避免使用除法和模数来获取数字,但我更愿意预先解析整个字符串,以便您立即发现字符串是否为无效的。 (如果你得到一个 NumberFormatException,或者如果值小于 0 或大于 9999 则它是无效的。)

最后,一旦你组装了两个单独的字节,你就可以将它们放入byte[2].

【讨论】:

    【解决方案3】:

    您可以使用以下内容:

    //Convert BCD String to byte array
    public static byte[] String2Bcd(java.lang.String bcdString) {
    
        byte[] binBcd = new byte[bcdString.length() / 2];
    
        for (int i = 0; i < binBcd.length; i++) {
            String sByte = bcdString.substring(i*2, i*2+2);
            binBcd[i] = Byte.parseByte(sByte, 16);
        }
        return binBcd;
    }
    

    【讨论】:

    • 您的代码错误。结果不是 BCD。 Byte.parseByte(sByte) 不解析十六进制而是十进制。 Byte.parseByte(sByte, 16) 应该修复它。
    【解决方案4】:

    你可以试试下面的代码:

    public static byte[] hex2Bytes(String str) {
        byte[] b = new byte[str.length() / 2];
        int j = 0;
        for (int i = 0; i < b.length; i++) {
            char c0 = str.charAt(j++);
            char c1 = str.charAt(j++);
            b[i] = ((byte) (parse(c0) << 4 | parse(c1)));
        }
        return b;
    }
    

    【讨论】:

    • 请避免只给出答案,并为您的答案提供适当的解释。
    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-09
    • 2015-11-29
    • 2014-12-04
    • 1970-01-01
    相关资源
    最近更新 更多