Question

J'utilise Jon Skeet mise en œuvre EBCDIC .NET pour lire un fichier VSAM téléchargé en mode binaire avec FTP à partir d'un système d'ordinateur central. Il fonctionne très bien pour la lecture / écriture dans cet encodage, mais il n'a rien à lire les valeurs décimales emballé. Mon fichier contient ceux-ci, et je dois les déballer (au prix de plus d'octets, évidemment).

Comment puis-je faire?

Mes champs sont définis comme PIC S9(7)V99 COMP-3.

Était-ce utile?

La solution

Ahh, BCD. Cornez si vous l'avez utilisé dans l'assemblage 6502.

Bien sûr, le meilleur pari est de laisser l'COBOL faire le travail pour vous! L'une de ces possibilités peut aider.

(Possibilité # 1) En supposant que vous avez accès à l'ordinateur central et le code source et le fichier de sortie est pour votre utilisation, modifier le programme pour qu'il ne fait que déplacer la valeur à une déballés simple PIC S9 (7) V99 .

(Possibilité # 2) En supposant qu'il est pas facile, (par exemple, le fichier est entrée pour d'autres MGP, ou ne peut pas changer le code), vous pouvez écrire un autre programme COBOL sur le système qui lit ce fichier et écrit un autre. Coupez et collez la mise en page d'enregistrement du fichier avec le BCD dans le nouveau programme pour les fichiers d'entrée et de sortie. Modifier la version de sortie pour être non-emballés. Lire un dossier, faire un « mouvement correspondant » pour transférer les données et écrire, jusqu'à ce que EOF. Puis transfert que fichier.

(Possibilité # 3) Si vous ne pouvez pas toucher l'ordinateur central, notez la description dans l'article que vous avez lié votre commentaire. BCD est relativement simple. Il pourrait être aussi simple que cela (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

Je l'ai testé avec quelques variations de cet appel:

MsgBox(FromBCD("@" & Chr(13 + 16), 2, 1))

par exemple., Est -40,1. Mais quelques-uns. Ainsi, il pourrait encore se tromper.

Alors si votre comp-3 commence, par exemple, à l'octet 10 de la mise en page d'enregistrement d'entrée, cela résoudre:

dim valu as Decimal = FromBCD(Mid(InputLine,10,5), 7,2))

Prenant note des formules de l'article conversion de données pour le # d'octets à envoyer et le # 9 de avant et après le V.

Stocker le résultat dans une décimale pour éviter les erreurs d'arrondi. Esp si c'est $$$. Float et Double vous causeront douleur! Si vous ne traitez pas, même une chaîne est meilleure.

Bien sûr, il pourrait être plus difficile. Là où je travaille, l'ordinateur central est de 9 bits par octet. Sérieux. Voilà ce qui fait les 2 premières possibilités si saillant. Bien sûr, ce qui les rend vraiment mieux est le fait que le vous peut être un PC que programmeur et c'est une bonne excuse pour obtenir un programmeur mainframe pour faire le travail pour vous! Si vous êtes tellement chanceux d'avoir cette option ...

Paix, -Al

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top