IBM Mainframe Forum Index
 
Log In
 
IBM Mainframe Forum Index Mainframe: Search IBM Mainframe Forum: FAQ Register
 

Dynamic Decimal Place separation


IBM Mainframe Forums -> COBOL Programming
Post new topic   Reply to topic
View previous topic :: View next topic  
Author Message
rajesh_mbt

New User


Joined: 27 Mar 2006
Posts: 97
Location: India

PostPosted: Sat Aug 18, 2012 12:13 am
Reply with quote

Hi,
I've a requirement where my input field will be some numeric values which actually need to convert into decimal value.

Eg. 234567 It should be changed as -> 345.67
31235673 mean -> 1235.673

What is the best way can achieve in cobol using single move/compute or any.
Please suggest ideas here..
Back to top
View user's profile Send private message
Akatsukami

Global Moderator


Joined: 03 Oct 2009
Posts: 1788
Location: Bloomington, IL

PostPosted: Sat Aug 18, 2012 12:14 am
Reply with quote

In what application is it considered acceptable to lose high-order digits?
Back to top
View user's profile Send private message
rajesh_mbt

New User


Joined: 27 Mar 2006
Posts: 97
Location: India

PostPosted: Sat Aug 18, 2012 12:21 am
Reply with quote

My actual value starts from the 2nd position only and the 1st position indicates number of decimal position. Hope you are clear now
Back to top
View user's profile Send private message
don.leahy

Active Member


Joined: 06 Jul 2010
Posts: 765
Location: Whitby, ON, Canada

PostPosted: Sat Aug 18, 2012 12:36 am
Reply with quote

That's a weird requirement. How would you handle, say, 412? Would it be 0.0012?
Back to top
View user's profile Send private message
Robert Sample

Global Moderator


Joined: 06 Jun 2008
Posts: 8696
Location: Dubuque, Iowa, USA

PostPosted: Sat Aug 18, 2012 12:45 am
Reply with quote

As Don points out, your "requirement" is severely lacking in details and indicates either you are not posting the full story, or you have not thought through the requirement very well..
However, your base requirement is easy to accomplish in COBOL:
Code:
       WORKING-STORAGE SECTION.
       77  WS-INPUT-FIELD              PIC X(30).
       77  WS-HOLD-FIELD               PIC X(29).
       77  WS-DECIMALS                 PIC 9(01).
       77  WS-NUM-VALUE                PIC 9(30).
       77  WS-FINAL-VALUE              PIC 9(15)V9(15).
       77  WS-FINAL-PRINT              PIC 9(15).9(15).
      /
       PROCEDURE DIVISION.
       S1000-MAIN       SECTION.
           MOVE 234567                TO  WS-INPUT-FIELD.
           MOVE WS-INPUT-FIELD (1 : 1)TO  WS-DECIMALS.
           MOVE WS-INPUT-FIELD (2 :)  TO  WS-HOLD-FIELD.
           COMPUTE WS-NUM-VALUE =
                   FUNCTION NUMVAL (WS-HOLD-FIELD) .
           COMPUTE WS-FINAL-VALUE =
                   WS-NUM-VALUE / 10 ** WS-DECIMALS.
           MOVE WS-FINAL-VALUE        TO  WS-FINAL-PRINT.
           DISPLAY '>' WS-FINAL-PRINT '<'.

           MOVE 31235673              TO  WS-INPUT-FIELD.
           MOVE WS-INPUT-FIELD (1 : 1)TO  WS-DECIMALS.
           MOVE WS-INPUT-FIELD (2 :)  TO  WS-HOLD-FIELD.
           COMPUTE WS-NUM-VALUE =
                   FUNCTION NUMVAL (WS-HOLD-FIELD) .
           COMPUTE WS-FINAL-VALUE =
                   WS-NUM-VALUE / 10 ** WS-DECIMALS.
           MOVE WS-FINAL-VALUE        TO  WS-FINAL-PRINT.
           DISPLAY '>' WS-FINAL-PRINT '<'.
produces output of
Code:
 >000000000000345.670000000000000<
 >000000000001235.673000000000000<
You'll want to adjust the PICTURE clauses to match your actual data, and you want to be sure the data is left-justified. You could probably do this in fewer lines of COBOL, but I wanted to clearly delineate the steps involved.
Back to top
View user's profile Send private message
Robert Sample

Global Moderator


Joined: 06 Jun 2008
Posts: 8696
Location: Dubuque, Iowa, USA

PostPosted: Sat Aug 18, 2012 2:29 am
Reply with quote

This code produces the same results:
Code:
           MOVE WS-INPUT-FIELD (1 : 1)    TO  WS-DECIMALS.
           COMPUTE WS-FINAL-VALUE =
                   FUNCTION NUMVAL (WS-INPUT-FIELD (2 : ) )
                   / 10 ** WS-DECIMALS.
           MOVE WS-FINAL-VALUE        TO  WS-FINAL-PRINT.
           DISPLAY '>' WS-FINAL-PRINT '<'.
Back to top
View user's profile Send private message
rajesh_mbt

New User


Joined: 27 Mar 2006
Posts: 97
Location: India

PostPosted: Sat Aug 18, 2012 8:01 am
Reply with quote

don.leahy wrote:
That's a weird requirement. How would you handle, say, 412? Would it be 0.0012?


Yup, thats how the requirement.
Back to top
View user's profile Send private message
rajesh_mbt

New User


Joined: 27 Mar 2006
Posts: 97
Location: India

PostPosted: Sat Aug 18, 2012 8:03 am
Reply with quote

Robert Sample wrote:
This code produces the same results:
Code:
           MOVE WS-INPUT-FIELD (1 : 1)    TO  WS-DECIMALS.
           COMPUTE WS-FINAL-VALUE =
                   FUNCTION NUMVAL (WS-INPUT-FIELD (2 : ) )
                   / 10 ** WS-DECIMALS.
           MOVE WS-FINAL-VALUE        TO  WS-FINAL-PRINT.
           DISPLAY '>' WS-FINAL-PRINT '<'.


Thanks a lot. I think this helps me more!!
Back to top
View user's profile Send private message
Anuj Dhawan

Superior Member


Joined: 22 Apr 2006
Posts: 6250
Location: Mumbai, India

PostPosted: Sat Aug 18, 2012 10:38 am
Reply with quote

The requirement is indeed cryptic and I'll take the benefit of doubt - what if the input is like 01234 or 0.1234? icon_confused.gif
Back to top
View user's profile Send private message
Peter cobolskolan

Active User


Joined: 06 Feb 2012
Posts: 104
Location: Sweden

PostPosted: Sat Aug 18, 2012 10:52 am
Reply with quote

It vill not pass an earlier validation.
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Sat Aug 18, 2012 7:07 pm
Reply with quote

An alternative, with more typing.

Uses UNSTRING to a JUSTIFIED RIGHT field followed by INSPECT to change leading spaces to zero. Then EVALUATE, using 88s on the first byte of the input, with an appropriate MOVE from one of 10 redefined items with the correct number of decimal places.

I've made some assumptions about the input :-)

Zippier than Robert's two.

You don't really have to type much, you just use the editor :-)

Code:
       01  W-WHEN-COMPILED             PIC X(8)BX(8).
       01  WS-INPUT-FIELD.
           05  WS-INPUT-DECIMAL-COUNT  PIC X.
               88  WS-INPUT-0-DEC-PLACES
                                       VALUE '0'.
               88  WS-INPUT-1-DEC-PLACE
                                       VALUE '1'.
               88  WS-INPUT-2-DEC-PLACES
                                       VALUE '2'.
               88  WS-INPUT-3-DEC-PLACES
                                       VALUE '3'.
               88  WS-INPUT-4-DEC-PLACES
                                       VALUE '4'.
               88  WS-INPUT-5-DEC-PLACES
                                       VALUE '5'.
               88  WS-INPUT-6-DEC-PLACES
                                       VALUE '6'.
               88  WS-INPUT-7-DEC-PLACES
                                       VALUE '7'.
               88  WS-INPUT-8-DEC-PLACES
                                       VALUE '8'.
               88  WS-INPUT-9-DEC-PLACES
                                       VALUE '9'.
           05  WS-INPUT-VALUE          PIC X(10).
                                                           
       01  WS-HOLD-FIELD               PIC X(10) JUST RIGHT.
       01  FILLER REDEFINES WS-HOLD-FIELD.
           05  WS-HOLD-0-DEC-PLACES    PIC 9(10).
       01  FILLER REDEFINES WS-HOLD-FIELD.
           05  WS-HOLD-1-DEC-PLACE     PIC 9(9)V9(1).
       01  FILLER REDEFINES WS-HOLD-FIELD.
           05  WS-HOLD-2-DEC-PLACES    PIC 9(8)V9(2).
       01  FILLER REDEFINES WS-HOLD-FIELD.
           05  WS-HOLD-3-DEC-PLACES    PIC 9(7)V9(3).
       01  FILLER REDEFINES WS-HOLD-FIELD.
           05  WS-HOLD-4-DEC-PLACES    PIC 9(6)V9(4).
       01  FILLER REDEFINES WS-HOLD-FIELD.
           05  WS-HOLD-5-DEC-PLACES    PIC 9(5)V9(5).
       01  FILLER REDEFINES WS-HOLD-FIELD.
           05  WS-HOLD-6-DEC-PLACES    PIC 9(4)V9(6).
       01  FILLER REDEFINES WS-HOLD-FIELD.
           05  WS-HOLD-7-DEC-PLACES    PIC 9(3)V9(7).
       01  FILLER REDEFINES WS-HOLD-FIELD.
           05  WS-HOLD-8-DEC-PLACES    PIC 9(2)V9(8).
       01  FILLER REDEFINES WS-HOLD-FIELD.
           05  WS-HOLD-9-DEC-PLACES    PIC 9(1)V9(9).
                                                       
       01  WS-FINAL-PRINT              PIC 9(10).9(9).
      /
       PROCEDURE DIVISION.
           MOVE WHEN-COMPILED TO W-WHEN-COMPILED
           DISPLAY "DYNDEC " W-WHEN-COMPILED
                                                       
           MOVE "234567"              TO  WS-INPUT-FIELD
           PERFORM                    10-DYNAMIC-DECIMAL
           MOVE "31235673"            TO WS-INPUT-FIELD
           PERFORM                    10-DYNAMIC-DECIMAL
           MOVE "023646"              TO WS-INPUT-FIELD
           PERFORM                    10-DYNAMIC-DECIMAL
           MOVE "90000123999"         TO WS-INPUT-FIELD
           PERFORM                    10-DYNAMIC-DECIMAL
           MOVE "83656569"            TO WS-INPUT-FIELD
           PERFORM                    10-DYNAMIC-DECIMAL
           MOVE "47395661"            TO WS-INPUT-FIELD
           PERFORM                    10-DYNAMIC-DECIMAL
           MOVE "15"                  TO WS-INPUT-FIELD
           PERFORM                    10-DYNAMIC-DECIMAL
           MOVE "50000100004"         TO WS-INPUT-FIELD
           PERFORM                    10-DYNAMIC-DECIMAL
           MOVE "61"                  TO WS-INPUT-FIELD
           PERFORM                    10-DYNAMIC-DECIMAL
           MOVE "7"                   TO WS-INPUT-FIELD
           PERFORM                    10-DYNAMIC-DECIMAL
                                                       
           GOBACK
           .
       10-DYNAMIC-DECIMAL.
                                                       
           UNSTRING WS-INPUT-VALUE
             DELIMITED BY SPACE       INTO WS-HOLD-FIELD
                                                       
           INSPECT WS-HOLD-FIELD
             REPLACING LEADING SPACE  BY ZERO
                                                       
           EVALUATE TRUE
             WHEN WS-INPUT-0-DEC-PLACES
               MOVE WS-HOLD-0-DEC-PLACES
                                      TO WS-FINAL-PRINT
             WHEN WS-INPUT-1-DEC-PLACE
               MOVE WS-HOLD-1-DEC-PLACE
                                      TO WS-FINAL-PRINT
             WHEN WS-INPUT-2-DEC-PLACES
               MOVE WS-HOLD-2-DEC-PLACES
                                      TO WS-FINAL-PRINT
             WHEN WS-INPUT-3-DEC-PLACES
               MOVE WS-HOLD-3-DEC-PLACES
                                      TO WS-FINAL-PRINT
             WHEN WS-INPUT-4-DEC-PLACES
               MOVE WS-HOLD-4-DEC-PLACES
                                      TO WS-FINAL-PRINT
             WHEN WS-INPUT-5-DEC-PLACES
               MOVE WS-HOLD-5-DEC-PLACES
                                      TO WS-FINAL-PRINT
             WHEN WS-INPUT-6-DEC-PLACES
               MOVE WS-HOLD-6-DEC-PLACES
                                      TO WS-FINAL-PRINT
             WHEN WS-INPUT-7-DEC-PLACES
               MOVE WS-HOLD-7-DEC-PLACES
                                      TO WS-FINAL-PRINT
             WHEN WS-INPUT-8-DEC-PLACES
               MOVE WS-HOLD-8-DEC-PLACES
                                      TO WS-FINAL-PRINT
             WHEN WS-INPUT-9-DEC-PLACES
               MOVE WS-HOLD-9-DEC-PLACES
                                      TO WS-FINAL-PRINT
           END-EVALUATE
                                                       
           DISPLAY '>' WS-INPUT-FIELD '<'
                   '>' WS-INPUT-VALUE '<'
                   '>' WS-INPUT-DECIMAL-COUNT '<'
                   '>' WS-FINAL-PRINT '<'
           .



Output is:

Code:
DYNDEC 08/18/12 07.23.38                         
>234567     <>34567     <>2<>0000000345.670000000<
>31235673   <>1235673   <>3<>0000001235.673000000<
>023646     <>23646     <>0<>0000023646.000000000<
>90000123999<>0000123999<>9<>0000000000.000123999<
>83656569   <>3656569   <>8<>0000000000.036565690<
>47395661   <>7395661   <>4<>0000000739.566100000<
>15         <>5         <>1<>0000000000.500000000<
>50000100004<>0000100004<>5<>0000000001.000040000<
>61         <>1         <>6<>0000000000.000001000<
>7          <>          <>7<>0000000000.000000000<
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Sat Aug 18, 2012 10:39 pm
Reply with quote

This

Code:
      01  WS-HOLD-FIELD               PIC X(10) JUST RIGHT.


could be changed to this

Code:
      01  WS-HOLD-FIELD               PIC 9(10).


And the INSPECT... REPLACING removed.

I normally don't like moving Xs to 9s, the UNSTRING won't work as wanted otherwise.

Could avoid the UNSTRING altogether with appropriate redefinitions, but I don't see a need. The later redefinitions are to avoid "math".

Unless certain of the data, needs a NUMERIC validation as well.

Interesting question about whether to change the DELIMITED to ALL SPACE for the UNSTRING. However, with only one receiving field I think BY SPACE would have the edge.

OK, so I know it very probably doesn't matter, but I just can't get out of the habit :-)
Back to top
View user's profile Send private message
sprathap1987

New User


Joined: 04 Aug 2012
Posts: 2
Location: India

PostPosted: Mon Aug 20, 2012 3:09 pm
Reply with quote

Hi,

Also another way to go.
As per the requirment, you will get maximum of 9 positions in fractional part and the integer part is as your wish.

E.g.
If you are getting the input with maximum length 20 then your final value would be with length 9(10).9(9): (note: first digit is to tel the decimal places)
WS-Section.
Code:
01 WS-INPUT.                                       
   03 WS-DECIMAL PIC 9.                           
   03 WS-INTEGER PIC X(27).                       
   03 WS-INTEGER-9  REDEFINES WS-INPUT PIC 9(27). 
01 WS-FINAL-VALUE PIC 9(18).9(9).                 

PROCEDURE DIVISION.

         INITIALIZE WS-INPUT WS-FINAL-VALUE
         MOVE 22345 TO WS-INPUT.           
         PERFORM 100-FORMAT-DECIMAL.     

         INITIALIZE WS-INPUT WS-FINAL-VALUE   
         MOVE 412 TO WS-INPUT.               
         PERFORM 100-FORMAT-DECIMAL.         
                                     
         INITIALIZE WS-INPUT WS-FINAL-VALUE 
         MOVE 7 TO WS-INPUT.                 
         PERFORM 100-FORMAT-DECIMAL.   
         GOBACK.

100-FORMAT-DECIMAL.
         IF WS-INTEGER > SPACE                                   
            COMPUTE WS-INTEGER-9 = FUNCTION NUMVAL(WS-INTEGER)   
         ELSE                                                     
            MOVE ALL ZEROES TO WS-INTEGER-9                       
         END-IF                                                   
         MOVE WS-INTEGER-9(1:(19 - WS-DECIMAL)) TO WS-FINAL-VALUE
         MOVE WS-INTEGER-9((20 - WS-DECIMAL):(WS-DECIMAL)) TO     
                          WS-FINAL-VALUE(12:(WS-DECIMAL))
OUTPUT:
0000000023.450000000
0000000000.001200000
0000000000.000000000

Code'd
Back to top
View user's profile Send private message
Anuj Dhawan

Superior Member


Joined: 22 Apr 2006
Posts: 6250
Location: Mumbai, India

PostPosted: Mon Aug 20, 2012 4:22 pm
Reply with quote

Peter cobolskolan wrote:
It vill not pass an earlier validation.
Possibly there is 'an earlier validation' (though it was not mentioned by OP). The output from Robert's reply got me asking this, what if the input itself came in like
Code:
>000000000000345.670000000000000<
>000000000001235.673000000000000<
and yes, I assumend I don't know the source of input. If there are no leading zeros, yes, all is well...
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Mon Aug 20, 2012 7:53 pm
Reply with quote

Siva,

What do you feel is the particular benefit of your solution over others suggested.

What happens with zero decimal places - did you check on that?

What is the INITIALIZE for?

Why do you REDEFINE then destroy the input?
Back to top
View user's profile Send private message
rajesh_mbt

New User


Joined: 27 Mar 2006
Posts: 97
Location: India

PostPosted: Thu Aug 23, 2012 6:36 am
Reply with quote

Bill Woodger wrote:
Siva,

What do you feel is the particular benefit of your solution over others suggested.

What happens with zero decimal places - did you check on that?

What is the INITIALIZE for?

Why do you REDEFINE then destroy the input?



Thanks so much for all your suggestions. But on my requirement the zero would not come for decimal separations :-)
Back to top
View user's profile Send private message
dick scherrer

Moderator Emeritus


Joined: 23 Nov 2006
Posts: 19244
Location: Inside the Matrix

PostPosted: Thu Aug 23, 2012 9:06 am
Reply with quote

Hello,

Quote:
But on my requirement the zero would not come for decimal separations :-)
I do not understand what this tells me icon_confused.gif

Can you show this in a data example or 2?
Back to top
View user's profile Send private message
View previous topic :: :: View next topic  
Post new topic   Reply to topic View Bookmarks
All times are GMT + 6 Hours
Forum Index -> COBOL Programming

 


Similar Topics
Topic Forum Replies
No new posts Extracting Variable decimal numbers f... DFSORT/ICETOOL 17
No new posts Using Dynamic file handler in the Fil... COBOL Programming 2
No new posts JCL Dynamic System Symbols JCL & VSAM 3
No new posts Need Help with Packed Decimal Signs DFSORT/ICETOOL 4
No new posts Synctool-dynamic split job for varyin... JCL & VSAM 7
Search our Forums:

Back to Top