Auspacken EBCDIC Verpackt Dezimalzahlen (COMP-3) in einer ASCII-Konvertierung
Frage
Ich bin mit Jon Skeet EBCDIC Implementierung in .NET eine VSAM-Datei heruntergeladen lesen im Binärmodus mit FTP von einem Mainframe-System. Es funktioniert sehr gut für das Lesen / in dieser Codierung zu schreiben, aber es hat nichts mit gepacktem Dezimalwerte zu lesen. Meine Datei enthält diese, und ich brauche sie zu entpacken (auf Kosten von mehr Bytes, natürlich).
Wie kann ich das tun?
Meine Felder werden als PIC S9(7)V99 COMP-3.
definiert
Lösung
Ahh, BCD. Honk, wenn verwendet man es in 6502 Montage.
Natürlich ist die beste Wette für Sie die COBOL-MOVE den Job zu lassen! Eine dieser Möglichkeiten helfen kann.
(Möglichkeit # 1) Unter der Annahme, tun Sie den Zugriff auf den Mainframe haben und den Quellcode und die Ausgabedatei ist nur für Ihren Gebrauch, ändern Sie das Programm, so dass es nur verschiebt den Wert in einer Ebene ausgepackt PIC S9 (7) V99 .
(Möglichkeit # 2) Unter der Annahme, es ist nicht so einfach, (zum Beispiel Dateieingabe für andere PGMs ist, oder kann nicht den Code ändern), können Sie einen anderen COBOL-Programm auf dem System schreiben, die diese Datei liest und schreibt eine andere. Schneiden Sie den Dateisatzaufbau mit dem BCD in das neue Programm für Ein- und Ausgabedateien einfügen. Ändern Sie die Ausgangsversion als nicht verpackt. Lesen Sie einen Datensatz, machen einen ‚bewegen‘ entspricht die Daten zu übertragen, und schreiben, bis EOF. Dann übertragen , die Datei.
(Möglichkeit # 3) Wenn Sie nicht den Mainframe berühren können, notieren Sie sich die Beschreibung im Artikel, den Sie in Ihrem Kommentar verknüpft. BCD ist relativ einfach. Es könnte so einfach wie diese (vb.net):
Private Function FromBCD(ByVal BCD As String, ByVal intsz As Integer, ByVal decsz As Integer) As Decimal
Dim PicLen As Integer = intsz + decsz
Dim result As Decimal = 0
Dim val As Integer = Asc(Mid(BCD, 1, 1))
Do While PicLen > 0
result *= 10D
result += val \ 16
PicLen -= 1
If PicLen > 0 Then
result *= 10D
result += val Mod 16
PicLen -= 1
BCD = Mid(BCD, 2)
End If
val = Asc(Mid(BCD, 1, 1))
Loop
If val Mod 16 = &HD& Then
result = -result
End If
Return result / CDec(10 ^ decsz)
End Function
Ich habe es getestet mit einigen Variationen dieses Aufrufs:
MsgBox(FromBCD("@" & Chr(13 + 16), 2, 1))
z. B., ist -40,1. Aber nur ein paar. So ist es immer noch falsch sein könnte.
Also dann, wenn Ihre comp-3 beginnt, sagen wir, bei Byte 10 des Eingangssatzaufbau, das es zu lösen wäre:
dim valu as Decimal = FromBCD(Mid(InputLine,10,5), 7,2))
in Anbetracht der Formeln aus der Datenumwandlungs Artikel für die Anzahl der Bytes in senden, und die # 9 der vor und nach dem V.
Speichern Sie das Ergebnis in einem Dezimal Rundungsfehler zu vermeiden. Esp wenn es $$$. Float & Double führen, dass Sie Trauer! Wenn Sie es nicht verarbeiten, auch ein String ist besser.
natürlich ist es könnte härter sein. Wo ich arbeite, ist die Mainframe-9 Bit pro Byte. Schwerwiegende. Das ist, was die ersten zwei Möglichkeiten so ausgeprägten macht. Natürlich, was macht sie wirklich besser ist die Tatsache, die Sie ein PC sein kann, nur Programmierer und das ist eine gute Ausrede, einen Mainframe-Programmierer erhalten die Arbeit für Sie zu tun! Wenn Sie sind so glücklich, dass die Option haben ...
Peace, -Al