将COMP-3压缩十进制字段解释为数字值

5
我正在创建一个SSIS包,以读取一系列copybook文件中的未打包数据。我不确定以下字段定义的正确解释,并希望有人能知道:
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 FIELD-NAME-2:11 FIELD-NAME-3:9
我不确定如何解释小数点和符号。
任何帮助都将不胜感激。
顺祝商祺, Ham
5个回答

4

这里是对你问题的另一种回答。

PIC S9(15)V9(3) COMP-3 在文件中的样子是这样的:

    00 00 00 00 00 00 00 00 00 0F

如果值为-4568248.323,它将是:
    00 00 00 00 04 56 82 48 32 3D

这不会对你有所帮助,但可能会帮助其他人。 解包前的值如下:

F0 F0 F0 F0 F0 F0 F0 F0 F0 F4 F5 F6 F8 F2 F4 F8 F3 F2 D3 (or F3 as the last byte, therefore losing the sign)

这个字段在小数点前有15(实际上是16)位数字,在小数点后有3位。

虽然只要求18位数字(15+3),但为了使它成为一个长度偶数的字段并带有符号(在前面添加一个数字以使其在文件上为10个字节长),需要19位。最佳实践是始终将紧缩字段设为奇数长度,以避免混淆。

** 最后一个字符表示符号,C和F是正数,D是负数。对于您的程序,请检查是否为负数(D), 如果不是,则视为正数。

** “V”是隐含的小数点。它不存在于文件中,但COBOL知道它存在于四舍五入等方面。您需要编程考虑它。文件中没有任何东西可以帮助您确定它在哪里或是否存在。

其他两个字段已经是奇数长度,因此,带符号时,它们可以存储在偶数长度的空间中。

如果有其他问题,请编辑您的问题或在评论中提问,会有人尝试为您解答。


4
请参考此链接中的getMainframePackedDecimal方法,该方法展示了在Java中转换压缩十进制数的示例(它是jrecord项目jrecord.sf.net的一部分)。

3
通常,COMP-3字段由BCD数字打包成两个字节,每个数字使用一个半字节(4位)。最后一个数字放在最后一个字节的上半字节中。如果数字为负数,则最后一个字节的下半字节为13,如果为正数,则为其他值(通常是12)。小数点是隐含的。
例如,-1.2在十六进制中如下所示,最后的D表示负号。
   01 2D

12.345是:
   12 34 5C

2

COMP-3字段的长度计算为我们需要存储的数字位数加1再除以2。例如,要存储值为987的数字字段,我们需要3 + 1除以2 = 2个字节的Comp-3字段。因此,长度为2个字节的Comp-3字段可以存储+999到-999的值作为极限。

15将被存储为01 5C。因此,数字的最后四位用于存储数字的符号,即C或D,因此“C”表示正数,“D”表示负数。每个数字需要4位来表示。

因此,7位数字需要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中以保留值的小数部分。

这样,我们就可以将数字的小数部分与完整数字分离。


2

下面开始:

PIC是"picture"
S9(15)表示一个15位数值型有符号字段:S代表符号,9代表数字,(15)为长度。 V是小数点的位置 9(3)是一个三位数值型

而COMP-3是BCD编码的十进制。该字段的每个半字节(nybble)都是二进制中的十进制值,因此

0b01110110(duh)

就是“76”。

18位数字需要9个字节,符号是低位字节的低半字节。

这让我担心,这些应该需要10个字节。

这里有一篇很好的文章


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接