アンパックEBCDICはASCII変換における小数(COMP-3)パック
質問
私は、VSAMファイルのダウンロードを読み取るために、.NET の中でジョンスキートのEBCDIC実装を使用していますメインフレームシステムからFTPのバイナリモードです。それは、このエンコーディングで書き込み/読み込みのために非常によく動作しますが、それはパック10進値を読み取るには何もありません。私のファイルには、これらが含まれている、と私は(明らかに、より多くのバイトのコストで)それらを解凍する必要があります。
私はこれを行うことができますどのように?
私のフィールドはPIC S9(7)V99 COMP-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ビットです。深刻な。それは顕著なので、最初の2つの可能性を作るものです。もちろん本当にそれらをよりよく作ることはあなたが唯一のプログラマPCかもしれ事実であり、これはあなたのために仕事をするために、メインフレームのプログラマを得るための素晴らしい言い訳です!あなたがそのオプションを持つことがとても幸運であれば...
平和、 -al