Как мне конвертировать VB Double в COBOL COMP-3? - PullRequest
1 голос
/ 11 февраля 2009

Кто-нибудь здесь знает, как преобразовать VB Double в Cobol S9 (15) V99 Comp-3 тип данных?

1 Ответ

5 голосов
/ 11 февраля 2009

Если это не нужно делать в одной и той же программе, мне кажется, было бы проще найти общий формат, понятный как 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
...