Если это не нужно делать в одной и той же программе, мне кажется, было бы проще найти общий формат, понятный как VB , так и COBOL.
Это был бы текст. Другими словами, простейшим решением может быть запись числа в файл в виде текста «3.14159» и чтение кода COBOL в этом формате и MOVE
в поле COMP-3
?
Если это невозможно, COMP-3
- это довольно простой тип BCD. Я бы в любом случае преобразовал число в строку, а затем взял бы по два символа за раз в байтовый массив.
S9 (15) V99 требует 18 nybbles (nybble - 4 бита или половина октета) для хранения:
- целочисленный бит (пятнадцать nybbles).
- дробный бит (два такта).
- знак (один клочок).
Для десятичной точки не требуется пробела, поскольку V
является подразумеваемым десятичным числом, а не вещественным.
Таким образом, число 3.14
будет представлено в байтах:
00 00 00 00 00 00 00 31 4C
Единственный хитрый бит - последний знак (C
для положительного и D
для отрицательного).
Вот фрагмент кода, который я написал в Excel VBA (к сожалению, на этом компьютере не установлен VB), который показывает вам, как это сделать. Функция makeComp3 () должна быть легко перенесена в настоящую программу VB.
Программа тестирования макроса выводит значения 0
, 49
и 76
, которые являются шестнадцатеричными 00
, 31
и 4C
соответственно (00314C
равно +3.14
).
Первый шаг (после всех объявлений) состоит в том, чтобы сделать двойное число подразумеваемым десятичным числом, умножив его на соответствующую степень десяти, а затем превратив в целое число:
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
Затем мы обрабатываем эту строку по две цифры за раз, и каждая пара объединяется в выходной nybble. Последний шаг - обработка последней цифры вместе со знаком:
' 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