I've been searching for s9(5)v99 but got different information and not really clear. Could someone shows how or the formula to convert. thanks
4 Answers
What you have shown us here is
the PICTURE
clause portion of a COBOL data declaration.
COBOL data declarations are a bit odd and take some getting used to. Here is a link to an introductory tutorial on COBOL data declarations. This should get you started.
The PICture clause you have given in your question is defining a numeric item with the following characteristics:
S
- Leading sign9(5)
- 5 decimal digitsV
- Implied decimal point99
- 2 digits after the implied decimal point
Basically, you are telling the COBOL compiler to define a numeric variable capable of holding
the values -99999.99 through +99999.99. Exactly how the compiler will fulfill this
request depends on the specific USAGE
clause. However, for numeric items containing a
fixed decimal position, the 'normal' USAGE is PACKED-DECIMAL
or COMP-3
(these are just
different names meaning the same thing). This link
provides some introductory information concerning the storage representation of packed decimal data.
Packed decimal data are useful for doing numeric computations where the number of decimal points must remain fixed.
Writing packed decimal data to a report or terminal does not work particularly well. You must
first convert it to a DISPLAY
able format. This involves MOVE
ing the packed decimal value to another
variable with a USAGE DISPLAY
attribute. Suppose your packed decimal variable was called
PACKED-DECIMAL-NBR
and was holding the value -2345.01. You could define a display variable
to hold it as:
01 DISPLAY-NBR PIC +++,++9.99.
then when it comes time to write/display the value contained in PACKED-DECIMAL-NBR
you would
do something like:
MOVE PACKED-DECIMAL-NBR TO DISPLAY-NBR
DISPLAY DISPLAY-NBR
The MOVE
converts the packed-decimal number to a character representation which you can
display in reports or on the terminal. The value -2,345.01
is displayed.

- 16,670
- 2
- 39
- 60
-
@user392973 @John Saunders. Based on your comment to John Saunders, it is possible that the USAGE type your client is looking for is not PACKED-DECIMAL but DISPLAY (better clarify that with your client). If USAGE is DISPLAY, then just allocate an 8 byte string and format the number as indicated in the answer John gave you. If the target environment is an IBM mainframe, the next bit to watch for are code page issues between EBCDIC/ASCII characters sets. – NealB Jul 20 '10 at 16:18
-
If these people want a web service to send them PACKED-DECIMAL or EBCDIC, then they need to wake up and smell the decade. – John Saunders Jul 20 '10 at 16:35
-
@John Saunders. Agreed! There are still some people finding IBM mainframes running COBOL at the center of their universe. It is important to be aware of the kinds of issues you might be running into when working with them. Anybody that specifies a data interchange format based on COBOL picture clauses is not just a few decades behind the times - they are clearly lost. – NealB Jul 20 '10 at 17:12
S in cobol is the definition of a signed numeric field (ie can be positive or negative). So for example S999 is a signed 3 digit numeric (binary). Problem is S is assumed, and in most cobol compilers, the way the sign is marked is by "overpunching" the last character with another character to signify plus or minus. This results, if you look at the field in an ascii browser, you will have a strange character. Ie. MINUS 500 would look something like this 50C or 50} depending on the underlying character and if it were a + or - that had overpunched.

- 21
- 1
-
1Why do you feel S999 is "binary"? It needn't be. S is "implied", not "assumed". USAGE DISPLAY fields are "overpunched", packed-decimal/comp-3 or binary/comp/comp-4/comp-5 are not, as they would not be "punched" in the first place. "50C" would be positive 503, "50}" is -500. If it were a "+" that had been overpunched, then it would be a positive number. – Bill Woodger Jan 29 '13 at 00:03
PIC S9(5)v99
isn't a number format. It's a description of how the data are stored and what it means there. For instance, a number stored as "-0010000" means -100.00.
What exactly are you trying to accomplish? Are you trying to send a decimal
-100.00 to a COBOL program?
PIC -99,999.00
is a number format. It specifies to use a leading minus sign if the number is negative, to use five digits before the decimal place, with a comma between the thousands, a decimal point, then exactly two digits after. A number stored in a PIC S9(5)V99
field might reasonably be moved to a PIC -99,999.00
field.

- 160,644
- 26
- 247
- 397
-
I want to upload a file to a web service. To their specification, the amount field is in format S9(5)V99 – user392973 Jul 20 '10 at 15:38
-
I want to upload a file to a web service. To their specification, the amount field is in format S9(5)V99. The amount field in our sql database is decimal field – user392973 Jul 20 '10 at 15:39
-
@user: they should learn a language other than COBOL. S9(5)V99 is meaningless to anyone other than a COBOL programmer. – John Saunders Jul 20 '10 at 16:34
Public Function CobolToDec(ByVal str As String) As Double
' **********************************************************************
' * Purpose: Converts Cobol numbers into dubble-values in MS format.
' * Author: Mikael Bergstrom
' * Date: 2017-11-06
' * Input: str = Cobolcoded value for amount S9(13)V99(Cobol)
' * Signs are in last byte
' **********************************************************************
Dim strNeg As String
strNeg = "pqrstuvwxy"
' If letter in strNeg then convert to number and negative sign
' p = 0, q = 1, r = 2 osv...
' Two last digits are decimals.
' Ex 00000000001200y = -120,09
' Ex 000000000015000 = 150,00
' Contains negative sign?
If InStr(1, str, "-", vbTextCompare) Then
dectal = CDbl(Trim(str))
CobolToDec = dectal
Else
' ...if not sign -> convert last digit to represetative digit and make hole number negative.
lastbyte = LCase(Right(str, 1))
If Not IsNumeric(lastbyte) Then
If InStr(1, strNeg, lastbyte, vbTextCompare) > 0 Then
dectal = "-" & Left(str, 13) & "," & Mid(str, 14, 1) & CStr(InStr(strNeg, lastbyte) - 1)
Else
' not valid negative sign in strNeg (pqrstuvwxy)
' Set 0 ast last sign as we don?t know and make negative number
dectal = "-" & Left(str, 13) & "," & Mid(str, 14, 1) & "0"
End If
Else
' positive number, just separate the two decimals
dectal = Left(str, 13) & "," & Right(str, 2)
End If
' Convert into double datatype and return result
CobolToDec = CDbl(FormatNumber(dectal, 2, , , vbFalse))
End If
End Function