VB DoubleからCobol S9(15)V99 Comp-3への変換方法を知っている人はいますか
回答:
回答№1は5同じプログラムで実行する必要がない場合は、両方のVBで共通の形式を見つけるほうが簡単です。 そして COBOLは理解できます。
それはテキストでしょう。つまり、最も簡単な解決策は、数字を「3.14159」というテキストとしてファイルに書き出し、それをCOBOLコードにその形式で読み込ませることです。 MOVE
それを COMP-3
フィールド?
それが不可能であれば、 COMP-3
かなり単純なBCDタイプです。とにかく数値を文字列に変換してから、一度に2文字ずつバイト配列にします。
S9(15)V99では、次のものを格納するために18ニブル(ニブルは4ビット、または半オクテット)が必要です。
- 整数ビット(15ニブル)
- 小数ビット(2ニブル)
- サイン(1ニブル)
小数点以下のスペースは必要ありません。 V
暗黙の10進数であり、実際のものではありません。
だから数 3.14
バイトとして表現されます。
00 00 00 00 00 00 00 31 4C
唯一のトリッキーなビットは、その最後のサインニブルです(C
ポジティブ D
否定のために)。
これが、Excel VBAで作成したコードです。makeComp3()関数は、本物のVBプログラムに簡単に転送できるはずです。
マクロテストプログラムは値を出力します 0
, 49
そして 76
これは16進数です 00
, 31
そして 4C
(それぞれ00314C
は +3.14
)。
最初のステップ(すべての宣言の後)は、倍精度を関連する10の累乗で乗算してから整数に変換することによって、暗黙の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