Как я могу конвертировать 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
Другие вопросы по тегам