View previous topic :: View next topic
|
Author |
Message |
rajesh_mbt
New User
Joined: 27 Mar 2006 Posts: 97 Location: India
|
|
|
|
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 |
|
|
Akatsukami
Global Moderator
Joined: 03 Oct 2009 Posts: 1787 Location: Bloomington, IL
|
|
|
|
In what application is it considered acceptable to lose high-order digits? |
|
Back to top |
|
|
rajesh_mbt
New User
Joined: 27 Mar 2006 Posts: 97 Location: India
|
|
|
|
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 |
|
|
don.leahy
Active Member
Joined: 06 Jul 2010 Posts: 765 Location: Whitby, ON, Canada
|
|
|
|
That's a weird requirement. How would you handle, say, 412? Would it be 0.0012? |
|
Back to top |
|
|
Robert Sample
Global Moderator
Joined: 06 Jun 2008 Posts: 8700 Location: Dubuque, Iowa, USA
|
|
|
|
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 |
|
|
Robert Sample
Global Moderator
Joined: 06 Jun 2008 Posts: 8700 Location: Dubuque, Iowa, USA
|
|
|
|
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 |
|
|
rajesh_mbt
New User
Joined: 27 Mar 2006 Posts: 97 Location: India
|
|
|
|
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 |
|
|
rajesh_mbt
New User
Joined: 27 Mar 2006 Posts: 97 Location: India
|
|
|
|
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 |
|
|
Anuj Dhawan
Superior Member
Joined: 22 Apr 2006 Posts: 6248 Location: Mumbai, India
|
|
|
|
The requirement is indeed cryptic and I'll take the benefit of doubt - what if the input is like 01234 or 0.1234? |
|
Back to top |
|
|
Peter cobolskolan
Active User
Joined: 06 Feb 2012 Posts: 104 Location: Sweden
|
|
|
|
It vill not pass an earlier validation. |
|
Back to top |
|
|
Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
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 |
|
|
Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
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 |
|
|
sprathap1987
New User
Joined: 04 Aug 2012 Posts: 2 Location: India
|
|
|
|
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 |
|
|
Anuj Dhawan
Superior Member
Joined: 22 Apr 2006 Posts: 6248 Location: Mumbai, India
|
|
|
|
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 |
|
|
Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
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 |
|
|
rajesh_mbt
New User
Joined: 27 Mar 2006 Posts: 97 Location: India
|
|
|
|
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 |
|
|
dick scherrer
Moderator Emeritus
Joined: 23 Nov 2006 Posts: 19243 Location: Inside the Matrix
|
|
|
|
Hello,
Quote: |
But on my requirement the zero would not come for decimal separations :-) |
I do not understand what this tells me
Can you show this in a data example or 2? |
|
Back to top |
|
|
|