在ASCII转换中解压缩EBCDIC压缩十进制(COMP-3)

时间:2010-03-01 14:27:00

标签: c# .net ascii ebcdic comp-3

我正在使用Jon Skeet's EBCDIC implementation in .NET来读取从大型机系统使用FTP以二进制模式下载的VSAM文件。它在这种编码中非常适合读/写,但它没有任何东西可以读取压缩十进制值。我的文件包含这些,我需要解压缩它们(显然需要花费更多的字节)。

我该怎么做?

我的字段定义为PIC S9(7)V99 COMP-3.

2 个答案:

答案 0 :(得分:3)

啊,BCD。如果您在6502装配中使用它,请致词。

当然,最好的办法是让COBOL MOVE为您完成工作!其中一种可能性可能有所帮助。

(可能性#1)假设您确实可以访问大型机和源代码,并且输出文件仅供您使用,请修改程序,使其仅将值移动到普通的未打包PIC S9(7)V99 。

(可能性#2)假设它并不那么容易(例如,文件是为其他pgms输入的,或者不能更改代码),您可以在系统上编写另一个COBOL程序来读取该文件并写入另一个文件。使用BCD将文件记录布局剪切并粘贴到输入和输出文件的新程序中。将输出版本修改为非打包。读取记录,执行“移动相应”以传输数据,然后写入,直到eof。然后转移那个文件。

(可能性#3)如果您无法触摸大型机,请记下您在评论中链接的文章中的说明。 BCD相对简单。 可能就像这样(vb.net):

Private Function FromBCD(ByVal BCD As String, ByVal intsz As Integer, ByVal decsz As Integer) As Decimal
    Dim PicLen As Integer = intsz + decsz
    Dim result As Decimal = 0
    Dim val As Integer = Asc(Mid(BCD, 1, 1))
    Do While PicLen > 0
        result *= 10D
        result += val \ 16
        PicLen -= 1
        If PicLen > 0 Then
            result *= 10D
            result += val Mod 16
            PicLen -= 1
            BCD = Mid(BCD, 2)
        End If
        val = Asc(Mid(BCD, 1, 1))
    Loop
    If val Mod 16 = &HD& Then
        result = -result
    End If
    Return result / CDec(10 ^ decsz)
End Function

我通过此调用的一些变体对其进行了测试:

MsgBox(FromBCD("@" & Chr(13 + 16), 2, 1))

,例如-40.1。但只是少数几个。所以它可能仍然是错误的。

那么如果你的comp-3开始,比如说,在输入记录布局的第10个字节,这将解决它:

dim valu as Decimal = FromBCD(Mid(InputLine,10,5), 7,2))

注意数据转换文章中要发送的字节数的公式,以及V之前和之后的9的#。

将结果存储在十进制中以避免舍入错误。 Esp,如果它是$$$。浮动&双重会让你悲伤!如果你没有处理它,即使字符串更好。

当然可能更难。我工作的地方,主机是每字节9位。严重。这就是前两种可能性如此突出的原因。当然,真正让他们变得更好的事实是你可能是一个只有PC的程序员,这是让大型机程序员为你工作的一个很好的借口!如果你很幸运有这个选择......

和平 -Al

答案 1 :(得分:0)

我使用此扩展方法进行压缩十进制 (BCD) 转换:

    ReactDOM.createPortal(
      <div id="formHome">
          <form onSubmit={handleSubmit}>
             ...// all the fields
          </form>
      </div>
      document.getElementById('app_root')
   )