首先,有来自IBM&
Legstar
从Cobol Copybooks生成Java类。我自己的套餐
JRecord
也可以使用,但它面向文件而不是在线处理。
基本上,字段的最后一个字符包含符号+数字。我猜数据来自主机;因此,对于美国-Ebcdic(CP037/IBM237),最后一位数字将是
0 1 2 3 4 5 6 7 8 9
positive { A B C D E F G H I
negative } J K L M N O P Q R
因此,对于+123,它将是00000012C(C=+3),-123将是00000012 L。
更糟糕的是,在不同的EBCIDIC方言和ASCII中,+0和-0是不同的。因此,您要么需要确切地知道使用的是Ebcidic的哪个版本,要么需要在字节级别进行转换。
这个
来自分区
中的方法
JRecord Conversion
转换是否:
private static int positiveDiff = 'A' - '1';
private static int negativeDiff = 'J' - '1';
private static char positive0EbcdicZoned = '{';
private static char negative0EbcdicZoned = '}';
public static String fromZoned(String numZoned) {
String ret;
String sign = "";
char lastChar, ucLastChar;
if (numZoned == null || ((ret = numZoned.trim()).length() == 0) || ret.equals("-")) {
return "";
}
lastChar = ret.charAt(ret.length() - 1);
ucLastChar = Character.toUpperCase(lastChar);
switch (ucLastChar) {
case 'A': case 'B': case 'C':
case 'D': case 'E': case 'F':
case 'G': case 'H': case 'I':
lastChar = (char) (ucLastChar - positiveDiff);
break;
case 'J': case 'K': case 'L':
case 'M': case 'N': case 'O':
case 'P': case 'Q': case 'R':
sign = "-";
lastChar = (char) (ucLastChar - negativeDiff);
break;
default:
if (lastChar == positive0EbcdicZoned) {
lastChar = '0';
} else if (lastChar == negative0EbcdicZoned) {
lastChar = '0';
sign = "-";
}
}
ret = sign + ret.substring(0, ret.length() - 1) + lastChar;
return ret;
}
但在字节级别更容易实现,应该如下所示(代码未经测试):
private static final byte HIGH_NYBLE = (byte) 0xf0;
private static final byte LOW_NYBLE = (byte) 0x0f;
private static final byte ZONED_POSITIVE_NYBLE_OR = (byte) 0xCF;
private static final byte ZONED_NEGATIVE_NYBLE_OR = (byte) 0xDF;
private static final byte ZONED_NEGATIVE_NYBLE_VALUE = (byte) 0xD0;
signByte = bytes[bytes.length - 1];
negative = false;
if (((byte) (signByte & HIGH_NYBLE)) == ZONED_NEGATIVE_NYBLE_VALUE) {
negative = true;
}
long result = 0;
for (int i = 0; i < bytes.length; i++) {
result = result * 10 + (bytes[i] & LOW_NYBLE);
}
if (negative) {
result = -1 * result;
}