Как я могу конвертировать VB Double в COBOL COMP-3?
Кто-нибудь здесь знает, как преобразовать VB Double в Cobol S9(15)V99 Comp-3 тип данных?
1 ответ
Если это не нужно делать в одной и той же программе, мне кажется, было бы легче найти общий формат, понятный как VB, так и COBOL.
Это был бы текст. Другими словами, самое простое решение может состоять в том, чтобы записать число в файл в виде текста "3.14159" и сделать так, чтобы код COBOL считал его в этом формате и MOVE
это к COMP-3
поле?
Если это невозможно, COMP-3
это довольно простой тип BCD. Я бы в любом случае преобразовал число в строку, а затем взял бы по два символа за раз в байтовый массив.
Для S9(15)V99 требуется 18 nybble (nybble - 4 бита или половина октета) для хранения:
- целочисленный бит (пятнадцать nybbles).
- дробный бит (два куска).
- знак (один клочок).
Для десятичной точки не требуется места, так как V
подразумеваемое десятичное число, а не реальное.
Итак, число 3.14
будет представлен в виде байтов:
00 00 00 00 00 00 00 31 4C
Единственный хитрый момент - последний знак nybble (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