将 COMP-3 压缩十进制字段解释为数值
我正在创建一个 SSIS 包来从一系列抄写本文件中读取解压数据。 我不确定以下字段定义的正确解释,并希望有人知道:
FIELD-NAME-1 PIC S9(15)V9(3) COMP-3.
FIELD-NAME-2 PIC S9(3)V9(8) COMP-3.
FIELD-NAME-3 PIC S9(3)V9(6) COMP-3.
数据以固定宽度文本存储。
上述字段的数据具有以下长度:
FIELD-NAME-1:19
字段名称-2:11
FIELD-NAME-3: 9
我们如何解释小数位和符号?
I am creating an SSIS package to read in unpacked data from a series of copybook files. I am unsure of the correct interpretation of the following field definitions and was hoping someone would know:
FIELD-NAME-1 PIC S9(15)V9(3) COMP-3.
FIELD-NAME-2 PIC S9(3)V9(8) COMP-3.
FIELD-NAME-3 PIC S9(3)V9(6) COMP-3.
The data is stored in fixed width text.
The data for the above fields has the following lengths:
FIELD-NAME-1: 19
FIELD-NAME-2: 11
FIELD-NAME-3: 9
How do we interpret the decimal place and sign?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
通常 COMP-3 字段由 BCD 数字组成,一次打包成两个字节,每个使用半字节(4 位)的数字。 最后一个数字位于最后一个字节的高半字节中。 如果数字为负数,则最后一个字节的低半字节为 13;如果为正数,则最后一个字节的低半字节为其他值(通常为 12)。 小数点是隐含的。
例如,-1.2 在十六进制中看起来像这样,最后的 D 是负号。
12.345 是:
Usually COMP-3 fields consist of BCD digits packed into bytes two at a time, each digit using a nibble (4 bits). The last digit goes in the upper nibble of the last byte. The lower nibble of the last byte has 13 if the number is negative, and something else, (usually 12) if positive. The decimal point is implied.
For example, -1.2 looks like this in hex, the final D is the negative sign.
12.345 is:
COMP-3 字段长度的计算方式为我们需要存储的位数 + 1 除以 2。例如,要存储值为 987 的数字字段,我们需要 3 +1 除以 2 = 2,因此 Comp-3 字段为长度2字节可以存储+999到-999的值作为限制。
15 将存储为 01 5C。 因此,数字的最后四位用于存储数字的符号,即 C 或 D,因此“C”代表正数,“D”代表负数。 每个数字用 4 位来表示自己。
因此,7 位数字需要 7 +1 = 8 / 2 = 4 字节大小。 因此,大小为 4 字节的 comp-3 字段可以存储 +999,9999 到 -999,9999 的数字。
如果出现上述问题,要移动数字的小数部分,则需要定义一个只能存储小数部分的变量,并将值移动到仅保存小数部分的字段。
例如FIELD-NAME-3 PIC S9(3)V9(6) COMP-3。
我们需要定义一个像 DEC-PORTION V9(6) comp-3 这样的小数字段,然后将 FIELD-NAME-3 移动到 DEC-PORTION 以保留值的小数部分。
这样我们就可以将数字的小数部分与完整数字分开。
COMP-3 fields length is calculated as number of digits that we need to store + 1 divided by 2. For example to store an numeric field of value 987 we would required 3 +1 divided by 2 = 2 Hence an Comp-3 field of length 2 bytes can store a value of +999 to -999 as the limit.
15 would stored as 01 5C. So the last four bits of the number is used to store the sign of the number that is C or D so "C" represents the positive number and "D" represents the negative number. And each numeric number takes 4 bits to represents themself.
So an 7 digit numeric number would require 7 +1 = 8 / 2 = 4 byte in size. So the comp-3 field of size 4 bytes can store an numeric digits of +999,9999 to -999,9999 digits.
In case of the above question to move the decimal portion of the number need to define an variable which can store only the decimal portion and move the value to that field which would hold just the decimal portion.
like FIELD-NAME-3 PIC S9(3)V9(6) COMP-3.
we need to define a decimal field like DEC-PORTION V9(6) comp-3 and then move the FIELD-NAME-3 to DEC-PORTION to retain the decimal part of the value.
This way we can have the decimal portion of the number separated from the full number.
我们开始吧:
PIC
是“图片”S9(15)
表示 15 位数字带符号字段:S 表示符号,9 表示数字,(15) 表示长度。V
是小数点位置9(3)
是一个三位数字,
COMP-3
是 BCD,即“二进制解码的十进制”。 该字段的每个 nybble(半字节)都是二进制的十进制值,因此0b01110110(废话)
是“76”。
18位需要9个字节,符号为低位字节的低半字节。
这让我担心,这些应该需要 10 字节。
这是一篇关于它的好文章。
Here we go:
PIC
is "picture"S9(15)
means a 15 digit numeric signed field: S for sign, 9 is numeric, (15) is length.V
is the decimal position9(3)
is a three digit numericand
COMP-3
is BCD, a "binary decoded decimal". Each nybble (half-byte) of the field is a decimal value in binary, so0b01110110
(duh)is "76".
18 digits requires 9 bytes, the sign is the low nybble of the low order byte.
Which worries me, those should require 10 bytes.
Here's a nice article on it.
这是回答您的问题的一些不同尝试。
PIC S9(15)V9(3) COMP-3 在文件中如下所示:
如果值为 -4568248.323,则为:
这对您没有帮助,但可能对其他人有帮助。
解压后,之前的值将如下所示:
该字段小数点前有 15 位(实际上是 16 位),小数点后有 3 位。
尽管它只请求 18 位数字 (15+3),但它会得到 19 位以使其成为带有符号的偶数长度字段(在前面添加一位数字以使其在文件上的长度为 10 个字节)。 最佳实践是始终使打包字段的长度为奇数,以避免这种混乱。
** 最后一个字母表示符号,C & F为正,D为负。 对于您的程序,检查是否为阴性 (D),如果不是,则视为阳性。
** “V”是隐含的小数点。 它不存在于文件中,但 COBOL 知道它在那里用于舍入等。 您需要以编程方式解释它。 文件中没有任何内容可以帮助您识别它的位置或它是否存在。
另外两个字段已经是奇数长度,因此当用符号打包时,它们可以存储在偶数长度的空间中。
如有其他问题,请编辑您的问题或在评论中提问,有人会尽力为您解答。
Here is a little different attempt at answering your questions.
PIC S9(15)V9(3) COMP-3 looks like this in the file:
If the value was -4568248.323, it would be:
This doesn't help you, but may help others.
Unpacked the previous value would look like:
This field has 15 (actually 16) digits before the decimal point and 3 after.
Although it only requests 18 digits (15+3), it gets 19 to make it an even length field with the sign (one digit added to the front to make it 10 bytes long on the file). Best practice is to always make packed fields an odd length to avoid this confusion.
** The last letter denotes the sign, C & F are positive, D is negative. For your program, check for negative (D) and if not, treat as positive.
** The 'V' is an implied decimal point. it doesn't exist on the file, but COBOL knows that it's there for rounding and such. You need to programmatically account for it. There is nothing in the file to help you identify where it is or if it even exists.
The other two fields are already odd lengths, so when packed, with the sign, they can be stored in an even length amount of space.
Any other questions, edit your question or ask in the comments and someone will try to answer them for you.
请参阅 http://jrecord.cvs.sourceforge.net/viewvc/jrecord/jrecord/src/net/sf/JRecord/Common/Conversion.java?revision=1.2&view=markup
有关在 java 中转换压缩十进制的示例(它是 jrecord 项目 jrecord.sf.net 的一部分)
See method getMainframePackedDecimal in http://jrecord.cvs.sourceforge.net/viewvc/jrecord/jrecord/src/net/sf/JRecord/Common/Conversion.java?revision=1.2&view=markup
for an example of converting packed decimal in java (it is part of the jrecord project jrecord.sf.net)