我正在发送和接收来自服务器的字符串形式的产品信息,服务器接收和发送COBOLSs9(6)v99格式的产品价格。我无法在java中将给定的小数转换为该格式。COBOL s9(6)V99格式示例:
nvbavucw1#
总体而言
s9(6)V99 sign leading
如果您可以获得Cobol Copybook,为什么不使用其中一个Cobol/Java包呢
01 MY-REC. 03 FIELD-1 PIC S9(6)V99.
没有一种单一的Cobol分区十进制格式,它随编译器和编码方式的不同而不同。要解码Zoned Decimal,您确实需要了解
Zoned Decimal
在这种情况下我猜是的
带区小数:
overpunched
assumed
因此s9(6)V99是一个有符号数,小数点前6位+2位
s9(6)V99
服务器使用的encoding(字符集)确定符号数字的表示方式。对于美国(和英国)Ebcdic,+0/-0是{ / },但对于德国Ebcdic,它们是不同的。对于ASCII服务器,它也是不同的
encoding
{ / }
ebcdic转换代码(注意,仍然需要根据假定的十进制进行调整):
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; }
设置+0/-0字符
+0/-0
public static void setDefaultEbcidicCharacterset(String charset) { if (getHold(charset).isEbcdic) { byte[] b = {(byte) 0xC0, (byte) 0xD0}; String s = new String(b, charset); if (s.length() == 2) { positive0EbcdicZoned = s.charAt(0); negative0EbcdicZoned = s.charAt(1); } } }
导出符号的另一种方法(对于EBCDIC编码)是将符号转换回原始字节:
private static final byte HIGH_NYBLE = (byte) 0xf0; private static final byte ZONED_NEGATIVE_NYBLE_VALUE = (byte) 0xD0; String Sign = ""; byte signByte = signStr.getBytes(encoding)[0]; if (((byte) (signByte & HIGH_NYBLE)) == ZONED_NEGATIVE_NYBLE_VALUE) { sign = "-"; } byte lastDigitBytes = (byte) (signByte | HIGH_NYBLE);
在本例中,它是EBCDIC。对于基于ASCII的代码,它又是不同的。这是JRecord用于Ascii带区十进制的通用转换类:
xjreopfe2#
在我看来,这应该是相当简单的。这是假设,这似乎是从你的例子的情况下,这是一个分区十进制。首先你需要得到数字的符号。简单地检查最后一个字符。如果它是一个非数字,那么它是负数(假设你使用F格式的正数)。一旦你得到了,然后你可以用正确的,等价的数字替换该字符。现在您有了数字的字符串表示形式。现在做
Integer result = Integer.valueOf(theInputString)
然后除以100并重新应用符号。您也可以在调用valueOf之前将符号添加为"-"或"+"。
ibps3vxo3#
让服务器中的cobol将值移动到screen变量中会容易得多,如
77 S-VALUE PIC ------9,99
并导出此变量,该变量易于读取,并且可以解析为Java双精度变量,其中:
Double value = Double.parseDouble(string);
或
Double value = new Double(string);
3条答案
按热度按时间nvbavucw1#
建议
总体而言
s9(6)V99 sign leading
,则在java中处理会容易得多。在您的情况下,这可能不是一个选项Package
如果您可以获得Cobol Copybook,为什么不使用其中一个Cobol/Java包呢
你需要知道的
没有一种单一的Cobol分区十进制格式,它随编译器和编码方式的不同而不同。要解码
Zoned Decimal
,您确实需要了解在这种情况下我猜是的
解释带区小数
带区小数:
overpunched
。assumed
小数位因此
s9(6)V99
是一个有符号数,小数点前6位+2位编码效果
服务器使用的
encoding
(字符集)确定符号数字的表示方式。对于美国(和英国)Ebcdic,+0/-0是{ / }
,但对于德国Ebcdic,它们是不同的。对于ASCII服务器,它也是不同的Java代码
ebcdic转换代码(注意,仍然需要根据假定的十进制进行调整):
设置
+0/-0
字符导出符号的另一种方法(对于EBCDIC编码)是将符号转换回原始字节:
ASCII钴
在本例中,它是EBCDIC。对于基于ASCII的代码,它又是不同的。这是JRecord用于Ascii带区十进制的通用转换类:
xjreopfe2#
在我看来,这应该是相当简单的。这是假设,这似乎是从你的例子的情况下,这是一个分区十进制。
首先你需要得到数字的符号。简单地检查最后一个字符。如果它是一个非数字,那么它是负数(假设你使用F格式的正数)。一旦你得到了,然后你可以用正确的,等价的数字替换该字符。
现在您有了数字的字符串表示形式。
现在做
然后除以100并重新应用符号。您也可以在调用valueOf之前将符号添加为"-"或"+"。
ibps3vxo3#
让服务器中的cobol将值移动到screen变量中会容易得多,如
并导出此变量,该变量易于读取,并且可以解析为Java双精度变量,其中:
或