COBOL file dump...

M

MPF

Alas, I surrender...

In a file from a COBOL dump, which is in ASCII, one of the fields is defined
as S9(9) V99 Value +0.
The value in this location is 0000018922D, which according to the author of
the source, translates to 00000189224.

How can this be translated via .Net? I've tried StreamReader and trying to
convert everything to bytes, but I end up with the same value (0000018922D).


Thanks In Advance.

Morgan
 
G

Ger

This is the representation of a so called "packed decimal" field with the
sign (+ or -) in the last nibble. In Cobol terms a COMP-3 field. In a
packed decimal field each decimal digit is stored in a nibble (4-bits, half
byte). The sign is C or F if positive, D if negative.
So in your example the value in de field is -189.22.
Here is a URL with a fairly good explanation:
http://digilander.libero.it/foxes/Packed_Decimal.htm

Hope this helps,
/Ger
 
C

Cor Ligthert

MPF,

This should be easy to translate, the only problem is to know the
representation that is used while converted to ASCII for +0 and -0

In this sequence is A +1 (which is punched card code 12 + 1) in EBCDIC
and J is -1 however what is -0. (which is punched card code 11 + 1) in
EBCDIC

With that last position is told that the whole field is plus or minus.

Therefore a routine is quiet easy however what is that +0 and -0 translated
to in your situation.

Cor
 
O

One Handed Man \( OHM - Terry Burns \)

You are showing your age here Cor ( Punched Cards and EBCDIC - Extended
Binary-Coded Decimal Interchange Code / Mainframes / IBM Etc )


LOL

--

OHM ( Terry Burns )
. . . One-Handed-Man . . .
If U Need My Email ,Ask Me

Time flies when you don't know what you're doing
 
C

Cor Ligthert

Terry

Search for Ligthert on Google, than you can see me in the first and second
link, so why hiding it.

Cor
 
Z

Zack Sessions

MPF said:
Alas, I surrender...

In a file from a COBOL dump, which is in ASCII, one of the fields is defined
as S9(9) V99 Value +0.
The value in this location is 0000018922D, which according to the author of
the source, translates to 00000189224.

How can this be translated via .Net? I've tried StreamReader and trying to
convert everything to bytes, but I end up with the same value (0000018922D).

It's been a long time, but I seem to remember that COBOL stored a
signed display value with a sign by tuning the uppermost bit on on the
rightmost character if the value was negative. So from that point of
view it appears to me the value should be -189225. At any rate, there
should be someway you can do a bitwise OR to strip off the upper bit
on the last character.
 
S

Stephany Young

Hmmmmmmmmmm ....

It seems that a few peoples have forgotten their COBOL Core skills :)

It's nothing to do with BCD or Packed Decimal.

It's to do with the declaration for the sign.

Because there is no sign declaraction on the field (S9(9)V99 VALUE 0), the
compiler (or the program) defaults come in to play. It would appear that the
compiler (or program) default is SIGN OVERPUNCHED TRAILING.

This means that the high nibble of the last byte has been 'overpunched' with
the sign indicator.

One option would be to ask the COBOL programmer to change the definition for
the 'dump' file so that the field is defined as S9(9)V99 SIGN SEPERATE
TRAILING VALUE 0. If he can do that for you then the output will be
00000189224+ or 00000189224- as appropriate.

If that is not an option then you need to read the value (11 characters) as
a string then change the last character and set the sign as per the
following:

If the last character is '{' or 'A' thru 'I' then the value is positive.

If the last character is '}' or 'J' thru 'R' then the value is negative.

If the last character is '{' or '}' then replace it with '0'.

If the last character is 'A' or 'J' then replace it with '1'.

If the last character is 'B' or 'K' then replace it with '2'.

If the last character is 'C' or 'L' then replace it with '3'.

If the last character is 'D' or 'M' then replace it with '4'.

If the last character is 'E' or 'N' then replace it with '5'.

If the last character is 'F' or 'O' then replace it with '6'.

If the last character is 'G' or 'P' then replace it with '7'.

If the last character is 'H' or 'Q' then replace it with '8'.

If the last character is 'I' or 'R' then replace it with '9'.

FYI,
the EDCDIC values for characters '0' thru '9' are 0xF0 thru 0xF9
respectively
the EDCDIC values for characters '{' thru 'I' are 0xC0 thru 0xC9
respectively
the EDCDIC values for characters '}' thru 'R' are 0xD0 thru 0xD9
respectively
Notice the correlation.
For overpunched signs (trailing) the last byte is overpunched with the
corresponding character from the 'C' column for a positive value or the 'D'
column for a negative value.
For overpunched signs (leading) it is the first byte that is overpunched.
If the sign was leading your value in the dumpfile would read '{0000189224'.
 
M

MPF

Thanks to all who offered suggestions.

Since I'm not dealing with a true EBCDIC file(sorry for not mentioning if
that played a role in your response), at least at this assumption, I'm
thinking Stephany's suggestion will apply for my scenario based on my review
of the data.

I'm sure if I hit a Comp-3 field, I'll be back to the drawing board and
bitwise OR'ing once and for all.

The following function in VB -should- handle the conversions, at least with
my data.

Thanks again to everyone!

Morgan

Function ConvertCharToInt(ByVal Val As String) As Integer

Select Case Val

Case "{"

Return 0

Case "}"

Return -0

Case "A"

Return 1

Case "B"

Return 2

Case "C"

Return 3

Case "D"

Return 4

Case "E"

Return 5

Case "F"

Return 6

Case "G"

Return 7

Case "H"

Return 8

Case "I"

Return 9

Case "J"

Return -1

Case "K"

Return -2

Case "L"

Return -3

Case "M"

Return -4

Case "N"

Return -5

Case "O"

Return -6

Case "P"

Return -7

Case "Q"

Return -8

Case "R"

Return -9

End Select

End Function
 
M

MPF

Thanks , Stephany.

Early on I came to an uneducated guess of A=1, B=2, but wasn't comfortable
moving forward with that assumption. I'm thinking that when I went over this
with the author of the file, they mave have been insulted that it would be
that easy to translate. Alas ;).

Thanks Again.
 
C

Cor Ligthert

"Stephany Young"
Hmmmmmmmmmm ....
It seems that a few peoples have forgotten their COBOL Core skills :)

Pardon, I thought that I had given almost the same answer as you, the only
thing I was not sure of that MPF had to look for was the character for the
zeros, because than can be translatted in every EBCDIC to ASCII way in a
different way. That it is with you {} is not a default, maybe a lost of your
EBCDIC COBOL skills, because those signs are not the representant for the
same in EBCDIC place. That means Hex C0 and D0 in EBCDIC. Where C=zero plus
and D= zero minus.

With a one to one transaltion this would result in for the C0 the @ Sign
however that exist in EBCDIC as 7C and therefore there should be taken non
existing EBCDIC characters. What is in your case the {} however as far as I
know for sure not a default.

Therefore I asked to MDF was in what are the EBCDIC C0 (+0) and D0 (-0)
translated, because that depends on the converter.

Than the procedure is easy to do.

First copy the string except the last postiton,
If the last character not is the equivalent for -0 you can set the the
boolean IsMinus
For +0 and - 0 concatenate as a char "0" to the made string.
If not than for the values from A to R you can do a subtract in the byte
with 16 to get the last character which you can do for the J to R as well
with the value 25.
Concatenate that value as ASCW to the string.

Than when the it is minus subtract the string from an integer with the value
zero and otherwise make from it an integer.

That is all,

So what is this different from my previous message?

Cor
 
C

Cor Ligthert

MPF,

That will as far as I can see not work, that makes a string however you can
not use that last possition as a value.

See my response to the message from Stephany.

Cor
 
S

Stephany Young

Close but no cigar.

The sign applies to the whole value not just the last character.

First you need to to translate the last character disregarding the sign.

After that you need to apply the sign to the whole result.
If the character is '{' or 'A' thru 'I' the result is positive.
If the character is '}' or 'J' thru 'R' the result is negative.

Try

Function ConvertStringToDecimal(ByVal Val As String, ByVal Places as
Integer) As Decimal

Dim _s as String = Val.SubString(0, Val.Length - 1)

Select Case Val.SubString(Val.Length - 1)
Case "{", "}"
_s &= "0"
Case "A", "J"
_s &= "1"
Case "B", "K"
_s &= "2"
Case "C", "L"
_s &= "3"
Case "D", "M"
_s &= "4"
Case "E", "N"
_s &= "5"
Case "F", "O"
_s &= "6"
Case "G", "P"
_s &= "7"
Case "H", "Q"
_s &= "8"
Case "I", "R"
_s &= "9"
End Select

Select Case Val.SubString(Val.Length - 1)
Case "{", "A" To "I"
If Places = 0 Then
Return Decimal.Parse
Else
Return Decimal.Parse / (10 ^ Places)
End If
Case "}", "J" To "R"
If Places = 0 Then
Return -(Decimal.Parse)
Else
Return -(Decimal.Parse / (10 ^ Places))
End If
End Select

End Function

Of course, if you wish, you can do it mathmatically.
ASCII "{" = 123 (subtract 75 to get '"0")
ASCII "}" = 125 (subtract 77 to get '"0")
ASCII "A" thru "I" = 65 thru 73 (subtract 16 to get "1" thru "9")
ASCII "J" thru "R" = 74 thru 82 (subtract 15 to get "1" thru "9")
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top