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

问题描述 投票:0回答:5

我正在创建一个 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.

数据以固定宽度文本存储。
上述字段的数据具有以下长度:

字段名称-1:19
字段名称-2:11
字段名称-3:9

我们如何解释小数位和符号?

ssis cobol comp-3
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),但它会得到 19,使其成为带有符号的偶数长度字段(在前面添加一位数字,使其在文件上的长度为 10 个字节)。最佳实践是始终使打包字段的长度为奇数,以避免这种混乱。

** 最后一个字母表示符号,C、F 为正,D 为负。对于您的计划,检查是否为阴性 (D),如果不是,则视为阳性。

** “V”是隐含的小数点。它不存在于文件中,但 COBOL 知道它在那里用于舍入等。您需要以编程方式解释它。文件中没有任何内容可以帮助您确定它在哪里或是否存在。

另外两个字段已经是奇数长度,因此当用符号打包时,它们可以存储在偶数长度的空间中。

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


4
投票

参见方法 getMainframePackedDecimal 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 的一部分)


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字节的可以存储+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以保留值的小数部分。

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


2
投票

我们开始吧:

PIC
是“图片”
S9(15)
表示 15 位数字带符号字段:S 表示符号,9 是数字,(15) 是长度。
V
是小数点位置
9(3)
是一个三位数数字

COMP-3
是BCD,即“二进制解码的十进制”。该字段的每个 nybble(半字节)都是二进制的十进制值,所以

0b01110110
(废话)

是“76”。

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

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

这是一篇关于它的好文章

© www.soinside.com 2019 - 2024. All rights reserved.