Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

PICTURE clause 4

Status
Not open for further replies.

tubiron

MIS
Apr 24, 2003
5
US
Can someone explain why a field defined with this
02 C-AMOUNT PIC S9(6)V99.

shows up with wierd character. This should be numeric
but I'm getting something like this: 0000732{
in the field.

thanks

 
That value you are seeing is a good value.

When you define a field the way you have, S9(6)V99, the sign is stored in the zone portion of the rightmost byte. That curly bracket you're seeing is the character that includes the sign.

The value you have is 0000732{
In hex that is F0 F0 F0 F0 F7 F3 F2 C0

When you have a positive or negative number in the signed field, the last character will not print as a number. For example, if that last character is a positive 1, that's a hex C1 which prints as an 'A'. The value would look like 000073A.

FYI: Positive numbers have a 'C' in the sign position
Negative numbers have a 'D' in the sign position
Unsigned numbers would have an 'F' in the sign position
 
Guess you would want to have
Code:
 SIGN LEADING SEPARATE
to have it look like any 'normal' number with the sign in front of the number, or
Code:
 ..TRAILING..
for who needs that?

HTH
TonHu
 
Thanks. This was very helpful. I actually got the output file with a layout, and tried to open with a text editor. Is there an easy way to make a conversion of that particular field outside of Cobol.
 
No. This format is peculiar to COBOL (and Assembler). On other platforms, such as INTEL, the details are different (the numbers might be coded in ascii), but the general idea is the same.
 
tubiron writes: Is there an easy way to make a conversion of that particular field outside of Cobol (?)

A better answer may be obtained if we know the following:
Platform (mainframe, PC, unix, etc)?
Compiler/version?
What does outside mean in this case?

Tom Morrison
 
I'm not sure what platform the data was created on, I only have the data layout and sample data file. Outside of cobol meant using a tool like perl to reformat this into something readable. Any hint will be appreciated. Thanks.
 
Just found out data was created on VM platform. If it turns out what I'm trying to do can't be done what PIC clause can be used to make sure that field is viewable in a pc based text file. Thanks
 
tubiron -

This data format is referred to as "zoned decimal".

If you don't care about the sign, the PICTURE to use is "9(6).99" That will explicitly include the decimal point and drop the sign that's causing you the problem. If you need to retain the sign, use the SIGN IS LEADING SEPARATE clause in addition to the PICTURE. Another approach is PIC -(7).99. This will cause the sign to appear if the number is negative. The sign will "float" adjacent to the most significant digit e.g. -.01 rather than -000000.01.

To manually translate the number, you can do the rough equivalent of (forgive my lousy C++ pseudo-code):
Code:
answer = first-digits * 10;  // get first 7 digits 
                             // shift left one position

switch (last-char){
  case '{':    // zero
  case '}':    // negative zero?
         break;
  case 'A':    // positive numbers
  case 'B':
  .
  .
  .
  case 'I': answer += last-char - 'A' + 1;
            break;

                // all negative numbers
  default:  answer = -answer - last-char + 'J' - 1;
}
answer /= 100;  // account for two decimal places          
[\code]

Regards.

Glenn
 
Thank you for this life saver. I opted to use the manual one. Now I just need some sanity checks. Here's some sample data and corresponding translation. Does this look right or I'm way off?

0003277B -> 327.72
0001502D -> 150.24
0000535G -> 53.57
0000490{ -> 49.00

Thank you once again.
 
Hi,

An Easy way to interpret zoned decimals....
+---------------------------------------------------------------+
| Last Character will be | |
| represented as below for..| 0 1 2 3 4 5 6 7 8 9 |
+---------------------------------------------------------------+
| If the Number is +ve | { A B C D E F G H I |
+---------------------------------------------------------------+
| If the Number is -ve | } J K L M N O P Q R |
+---------------------------------------------------------------+

Example:
For 02 C-AMOUNT PIC S9(6)V99.
If values is -> Interpret as
0003277B -> +327.72
0003277K -> -327.72
0000490} -> -49.00
0000490{ -> +49.00




 
I'm working on a similar issue....

I have questions on the following:

My comma delimited file has a field that is 225.00

My COBOL Field that holds that value is defined as
PIC S9(6)V9(2).

THis is stored in a Indexed file.

Later in a test program when I write out to a different sequential file to view my records, this field value shows up as:

2259000{

THis doesn't look right...

Anyone have any suggestions?

Thanks.
-David
 
David,

How is the value getting from the comma-delimited file to the COBOL field? Please show snips from your data division and procedure division.

Tom Morrison
 
DATA DIVISION.

FD SEQ-FILE-REC PIC X(250).

FD IDX-FILE-REC.
01 FIELDS.
03 IDX-FILE-KEY PIC 9(11).
03 FIELD1 PIC X(10).
03 FIELD2 PIC X(10).
03 IDX-FILE-NBR-FIELD PIC S9(6)V9(2).
...etc
...........................

PROCEDURE DIVISION.
...
UNSTRING SEQ-FILE-REC
DELIMITED BY ","
INTO
IDX-FILE-KEY
...
..
IDX-FILE-NBR-FIELD
..
..
END-UNSTRING.
WRITE IDX-FILE-REC
END-WRITE.
 
Okay, David, that makes it very clear.

You must modify your technique to accomodate some standard COBOL rules.

First, UNSTRING states "The characters thus examined (excluding the delimiter characters, if any) are treated as an elementary alphanumeric data item, and are moved into the current receiving item according to the rules for the MOVE statement." (emphasis added)

So according to this rule, you should get the approximate equivalent of MOVE "225.00 " to IDX-FILE-NBR-FIELD. That's probably not what you want.

Since you are using RM/COBOL, you may use the deedit feature of the MOVE statement like this:
Code:
data division.
...
working-storage section.
...
01  numeric-intermediate-step pic x(18).
01  numeric-intermedite-edit 
    redefines numeric-intermediate-step 
                              pic Z(18).

Now you modify your UNSTRING a bit:
Code:
UNSTRING SEQ-FILE-REC
DELIMITED BY ","
INTO
  IDX-FILE-KEY
   ...
   ..
   numeric-intermediate-step
   ..
   ..
END-UNSTRING.
MOVE numeric-intermedite-edit TO IDX-FILE-NBR-FIELD.

This takes advantage of the case described in your Langusge Reference Manual where:
- a numeric edited data item is the source item, and
- a numeric (or numeric edited) data item is the receiving item.


Tom Morrison
 
Thanks.
I tried that and my output after reading the idx file is now:

0002250{

which according to posts made previously above on this thread should be the same thing as 225.00, right?

-David
 
David,

Yes, that is the correct internal representation; see table 4-5, Valid Data Item Encodings, in your Language Reference Manual.

webrabbit,

Not necessary with RM/COBOL (which we know David to be using from previous threads). When we were designing the deedit feature for RM/COBOL, since the 1985 Standard was silent on how the deediting was to take place, we used the least restrictive rules possible. The result is that the only requirement is that it be numeric edited. We then do a deedit of the item's value, all the way to treating a trailing CR or DB as negative. We found this threshold of rules (or lack thereof) most useful to our customers.

Tom Morrison
 
Okay, now I'm confused as to why the leading zeroes are showing up on my output. I have the WS- variable that I'm moving my IDX-FILE-NBR-FIELD to defined as:

WS-IDX-FILE-NBR-FIELD PIC Z(6)V9(2).

Shouldn't this show up as:

2250{

instead of

0002250{

??
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top