VB Double を Cobol S9(15)V99 Comp-3 データ型に変換する方法を知っている人はいますか?
1 に答える
同じプログラムで行う必要がない場合は、VBとCOBOL の両方が理解できる共通の形式を見つける方が簡単だと思います。
それはテキストでしょう。つまり、最も簡単な解決策は、数値をテキスト "3.14159" としてファイルに書き出し、COBOL コードにその形式で読み込んでMOVE
、COMP-3
フィールドに入力することです。
それが不可能な場合COMP-3
は、かなり単純な BCD タイプです。とにかく数値を文字列に変換してから、一度に2文字ずつバイト配列に変換します。
S9(15)V99 では、以下を格納するために 18 ニブル (ニブルは 4 ビット、つまりオクテットの半分) が必要です。
- 整数ビット (15 ニブル)。
- 小数ビット (2 ニブル)。
- 記号 (1 つのニブル)。
V
aは実数ではなく暗黙の小数であるため、小数点にスペースは必要ありません。
したがって、数値3.14
はバイトとして表されます。
00 00 00 00 00 00 00 31 4C
唯一のトリッキーなビットは、最後の符号ニブル (C
正とD
負の場合) です。
これは、Excel VBA で作成したコードの一部です (残念ながら、このマシンには VB がインストールされていません)。makeComp3() 関数は、実際の VB プログラムに簡単に移植できます。
マクロ テスト プログラムは、値0
、49
およびを出力します。これらの値は、それぞれ76
16 進数および(です) です。00
31
4C
00314C
+3.14
最初のステップ (すべての宣言の後) は、double に関連する 10 のべき乗を掛けてから整数に変換することにより、double を暗黙の 10 進数にすることです。
Option Explicit
' makeComp3. '
' inp is the double to convert. '
' sz is the minimum final size (with sign). '
' frac is the number of fractional places. '
Function makeComp3(inp As Double, sz As Integer, frac As Integer) As String
Dim inpshifted As Double
Dim outstr As String
Dim outbcd As String
Dim i As Integer
Dim outval As Integer
Dim zero As Integer
zero = Asc("0")
' Make implied decimal. '
inpshifted = Abs(inp)
While frac > 0
inpshifted = inpshifted * 10
frac = frac - 1
Wend
inpshifted = Int(inpshifted)
次に、処理を簡単にするために、正しいサイズの文字列にします。
' Get as string and expand to correct size. '
outstr = CStr(inpshifted)
While Len(outstr) < sz - 1
outstr = "0" & outstr
Wend
If Len(outstr) Mod 2 = 0 Then
outstr = "0" & outstr
End If
次に、その文字列を一度に 2 桁ずつ処理し、各ペアを組み合わせて出力ニブルにします。最後のステップは、符号とともに最後の数字を処理することです。
' Process each nybble pair bar the last. '
outbcd = ""
For i = 1 To Len(outstr) - 2 Step 2
outval = (Asc(Mid(outstr, i)) - zero) * 16
outval = outval + Asc(Mid(outstr, i + 1)) - zero
outbcd = outbcd & Chr(outval)
Next i
' Process final nybble including the sign. '
outval = (Asc(Right(outstr, 1)) - zero) * 16 + 12
If inp < 0 Then
outval = outval + 1
End If
makeComp3 = outbcd & Chr(outval)
End Function
これは単なるテスト ハーネスですが、おそらくさらにいくつかのテスト ケースを使用することもできます :-)
Sub Macro1()
Dim i As Integer
Dim cobol As String
cobol = makeComp3(3.14159, 6, 2)
For i = 1 To Len(cobol)
MsgBox CStr(Asc(Mid(cobol, i)))
Next i
End Sub