Custom Program to convert Text into its Numeric Equivalent



Support for OS/VS COBOL, VS COBOL II, COBOL for OS/390 & VM and Enterprise COBOL for z/OS

Custom Program to convert Text into its Numeric Equivalent

Postby Quasar » Thu Jun 09, 2011 11:56 am

Hi All -

As an exercise, I am trying to write routine, that should accept Textual-Data as Input, and return a Number-Representation as its Output. It should work just like the Numeric Intrinsic Function NUMVAL.

I have written the following sub-routine in COBOL and tested it. I just check every character, if it falls between '0' THRU '9', I move it to the Output Numeric Field. Could anyone give me some inputs, about which other possibilities need to be taken care of? Or is this comprehensive.

       IDENTIFICATION DIVISION.                                         00010000
       PROGRAM-ID. PROG99.                                              00020000
      *---------------------------------------------------------------* 00030000
      *  PROGRAM-ID : PROG99                        DATE   : 09/06/11 * 00030100
      *  Author     : Quasar Chunawala                                * 00030200
      *  Description: This program accepts alphanumeric Text Input,   * 00030300
      *               performs Validation, and returns back a numeric * 00030400
      *               representation of it.                           * 00030500
      *---------------------------------------------------------------* 00031000
       ENVIRONMENT DIVISION.                                            00040000
                                                                        00050000
       DATA DIVISION.                                                   00060000
       WORKING-STORAGE SECTION.                                         00070000
      *---------------------------------------------------------------* 00070100
      *                     Literals and Constants                    * 00070201
      *---------------------------------------------------------------* 00070300
       01  WS-LIT-MAX-DIGITS                PIC 99 VALUE 18.            00070401
       01  WS-LIT-ONE                       PIC 99 VALUE 01.            00070501
                                                                        00070601
      *---------------------------------------------------------------* 00070701
      *                     Flags and Switches                        * 00070801
      *---------------------------------------------------------------* 00070901
       01  FLAGS-AND-SWITCHES.                                          00071000
           05 WS-DEBUG-SW                   PIC X VALUE 'Y'.            00072000
              88 DEBUG-ON                   VALUE 'Y'.                  00073000
              88 DEBUG-OFF                  VALUE 'N'.                  00074000
           05 END-OF-STRING-SW              PIC X VALUE 'N'.            00074100
              88 END-OF-STRING              VALUE 'Y'.                  00074200
                                                                        00075000
      *---------------------------------------------------------------* 00076000
      *                         Counters                              * 00077000
      *---------------------------------------------------------------* 00078000
       01  WS-COUNTERS.                                                 00079000
           05 WS-IPOS                       PIC S9(04) COMP-3           00079100
                                            VALUE ZEROES.               00079200
           05 WS-OPOS                       PIC S9(04) COMP-3           00079300
                                            VALUE ZEROES.               00079400
      *---------------------------------------------------------------* 00079500
      *                       Miscallaneous                           * 00079600
      *---------------------------------------------------------------* 00079700
       01  WS-CHARACTER                     PIC X.                      00079800
       01  WS-PARA-NAME                     PIC X(30).                  00079900
                                                                        00080000
       LINKAGE SECTION.                                                 00081000
       01  LS-ALPHANUM-INPUT                PIC X(18).                  00090000
       01  LS-RETURN-CODE                   PIC 99.                     00100000
       01  LS-NUM-OUTPUT                    PIC S9(18).                 00110000
                                                                        00120000
       PROCEDURE DIVISION USING LS-ALPHANUM-INPUT                       00130000
                                LS-RETURN-CODE                          00131000
                                LS-NUM-OUTPUT.                          00132000
                                                                        00133000
       0000-MAIN.                                                       00140000
           MOVE '0000-MAIN' TO WS-PARA-NAME                             00150000
           PERFORM 8000-DEBUG                                           00160000
                                                                        00170000
           PERFORM 1000-PARSE-STRING                                    00171000
           THRU    1000-PARSE-STRING                                    00172000
           UNTIL   END-OF-STRING                                        00173000
                                                                        00174000
           MOVE 00 TO LS-RETURN-CODE                                    00175000
                                                                        00176000
           PERFORM 9999-GOBACK.                                         00180000
                                                                        00190000
       1000-PARSE-STRING.                                               00191000
           MOVE '1000-PARSE-STRING' TO WS-PARA-NAME                     00191102
           PERFORM 8000-DEBUG                                           00191200
                                                                        00191300
           ADD WS-LIT-ONE TO WS-IPOS                                    00191401
           MOVE LS-ALPHANUM-INPUT(WS-IPOS:1) TO WS-CHARACTER            00191500
           EVALUATE WS-CHARACTER                                        00191600
              WHEN '0' THRU '9'                                         00191700
                 ADD WS-LIT-ONE TO WS-OPOS                              00191801
                 MOVE WS-CHARACTER TO LS-NUM-OUTPUT(WS-OPOS:1)          00191900
           END-EVALUATE                                                 00192001
                                                                        00192101
           IF WS-IPOS = WS-LIT-MAX-DIGITS                               00192201
              SET END-OF-STRING TO TRUE                                 00192301
           END-IF.                                                      00192401
       1000-PARSE-STRING-EXIT. EXIT.                                    00192500
                                                                        00193000
       8000-DEBUG.                                                      00194000
           IF DEBUG-ON                                                  00195000
              DISPLAY WS-PARA-NAME                                      00196000
           END-IF.                                                      00197000
                                                                        00198000
       9999-GOBACK.                                                     00200000
           GOBACK.                                                      00210000


Thank you very much.
Quasar Chunawala,
Software Engineer, Lives at Borivali, Mumbai
User avatar
Quasar
 
Posts: 102
Joined: Wed Nov 10, 2010 7:11 pm
Location: Borivali, Mumbai
Has thanked: 13 times
Been thanked: 2 times

Re: Custom Program to convert Text into its Numeric Equivale

Postby BillyBoyo » Thu Jun 09, 2011 3:05 pm

Quasar wrote:
[...]
As an exercise, I am trying to write routine, that should accept Textual-Data as Input, and return a Number-Representation as its Output. It should work just like the Numeric Intrinsic Function NUMVAL.

I have written the following sub-routine in COBOL and tested it. I just check every character, if it falls between '0' THRU '9', I move it to the Output Numeric Field. Could anyone give me some inputs, about which other possibilities need to be taken care of? Or is this comprehensive.
[...]


So, "+", "-", ",", ".". You want to know that -1,321.49 is valid whereas x1(321?49 isn't. Try to check exactly what NUMVAL can handle, if you want to do the same.
BillyBoyo
Global moderator
 
Posts: 3804
Joined: Tue Jan 25, 2011 12:02 am
Has thanked: 22 times
Been thanked: 265 times

Re: Custom Program to convert Text into its Numeric Equivale

Postby GuyC » Thu Jun 09, 2011 3:28 pm

I've seen this a few times : Is there a reason why people define WS-LIT-ONE with a Value of 1
Is ADD WS-LIT-ONE TO WS-IPOS better than ADD 1 TO WS-IPOS
GuyC
 
Posts: 315
Joined: Tue Aug 11, 2009 3:23 pm
Has thanked: 1 time
Been thanked: 4 times

Re: Custom Program to convert Text into its Numeric Equivale

Postby BillyBoyo » Thu Jun 09, 2011 3:33 pm

OK, the program. I know you've learned this way, but here are my comments anyway.

      *---------------------------------------------------------------* 00070100
      *                     Literals and Constants                    * 00070201
      *---------------------------------------------------------------* 00070300
       01  WS-LIT-MAX-DIGITS                PIC 99 VALUE 18.            00070401
       01  WS-LIT-ONE                       PIC 99 VALUE 01.


Define things like maximum values with the same usage that the compiler is most likely to use. For any sort of loop control, subscript, index-related that will be COMP/BINARY/COMP-5. In this case, WS-LIT-MAX-DIGITS has to be converted each time it is used. Funny, for a "constant".

Avoid defining data name for things which are numbers but have no other meaning. If you are just adding one to something, there is no problem using a literal in the procedure. If, however, something is a numeric constant value but happens to have a meaning, define it, again as it is most likely to be used. So, WS-NUMBER-OF-LEAFLETS-FOR-NEW-CUSTOMER .... VALUE +1.

     01  FLAGS-AND-SWITCHES.                                          00071000
           05 WS-DEBUG-SW                   PIC X VALUE 'Y'.            00072000
              88 DEBUG-ON                   VALUE 'Y'.                  00073000
              88 DEBUG-OFF                  VALUE 'N'.                  00074000
           05 END-OF-STRING-SW              PIC X VALUE 'N'.            00074100
              88 END-OF-STRING              VALUE 'Y'.               


I prefer WS-DEBUG-SW-ON (-OFF) etc. Next to each other on the XREF. You can see where set and where used at the same time.

      *---------------------------------------------------------------* 00076000
      *                         Counters                              * 00077000
      *---------------------------------------------------------------* 00078000
       01  WS-COUNTERS.                                                 00079000
           05 WS-IPOS                       PIC S9(04) COMP-3           00079100
                                            VALUE ZEROES.               00079200
           05 WS-OPOS                       PIC S9(04) COMP-3           00079300
                                            VALUE ZEROES.             


COMP-3 should always be defined with an odd-number of 9's. Otherwise the compiler generates extra code to ensure that the high-order half-byte is always '0'.

      *                       Miscallaneous                           * 00079600
      *---------------------------------------------------------------*


If you need comments, at least check the spelling. All these sort of comments are basically superfluous.
BillyBoyo
Global moderator
 
Posts: 3804
Joined: Tue Jan 25, 2011 12:02 am
Has thanked: 22 times
Been thanked: 265 times

Re: Custom Program to convert Text into its Numeric Equivale

Postby BillyBoyo » Thu Jun 09, 2011 4:06 pm

           MOVE '0000-MAIN' TO WS-PARA-NAME                             00150000
           PERFORM 8000-DEBUG                                           00160000


Personally I've never understood this sort of stuff. Makes the program longer, more difficult to read quickly (as at the start of each para the first stuff is useless to the understanding of what the code is doing).


           PERFORM 1000-PARSE-STRING                                    00171000
           THRU    1000-PARSE-STRING                                    00172000
           UNTIL   END-OF-STRING                                        00173000


I can honestly say I have no idea what that does. Perform and thru using the same para?

           PERFORM 9999-GOBACK.                                         00180000


Hate this. Why "perform" something you know isn't going to come back to you? Put the GOBACK in the main body.

           ADD WS-LIT-ONE TO WS-IPOS                                    00191401


What happens the second time you call the module? WS-IPOS goes wandering off through the calling program. Or SSRANGE goes BANG!

LS-NUM-OUTPUT is never initiliased, but you do byte-by-byte moves. Call first with a long number, then with a short and see the effect.
BillyBoyo
Global moderator
 
Posts: 3804
Joined: Tue Jan 25, 2011 12:02 am
Has thanked: 22 times
Been thanked: 265 times

Re: Custom Program to convert Text into its Numeric Equivale

Postby Robert Sample » Thu Jun 09, 2011 4:43 pm

I can honestly say I have no idea what that does. Perform and thru using the same para?
Probably someone's crippled (mis)understanding of a site standard that says every COBOL PERFORM must have THRU. Don't laugh -- I've seen sites do this (and worse).
Robert Sample
Global moderator
 
Posts: 3719
Joined: Sat Dec 19, 2009 8:32 pm
Location: Dubuque, Iowa, USA
Has thanked: 1 time
Been thanked: 279 times

Re: Custom Program to convert Text into its Numeric Equivale

Postby BillyBoyo » Thu Jun 09, 2011 5:44 pm

Sorry Robert, I did laugh :)

Quasar, NUMVAL handles inputs and outputs of more than one length (even type, for outputs). Are you going for that as well?

What does your current solution do with this?

Th1s i2 a numb3r?
BillyBoyo
Global moderator
 
Posts: 3804
Joined: Tue Jan 25, 2011 12:02 am
Has thanked: 22 times
Been thanked: 265 times

Re: Custom Program to convert Text into its Numeric Equivale

Postby Quasar » Thu Jun 09, 2011 7:26 pm

Bill -

Thank you very much for your inputs. I have made some corrections to the program.

1. I have corrected the PERFORM THRU, and mentioned the EXIT Para in the PERFORM.

            PERFORM 1000-PARSE-STRING                                   
            THRU    1000-PARSE-STRING-EXIT                               
            UNTIL   END-OF-STRING                                       


2. I have put GOBACK in the Main Body of the program, instead of declaring it in another Paragraph.

        0000-MAIN.                                     
            ...
            ...
            GOBACK.                                   


3. Realised that the state of LS-Variables is preserved, during successive executions of a sub-program. I coded a separate paragraph to perform Initialisations, every time the Program is called.
4. I realised that, that the process of inspecting character in the Input String, checking it, and moving it to the corresponding number field, should be done in a Right-To-Left fashion, as numbers are right-justified.

            MOVE LS-ALPHANUM-INPUT(WS-IPOS:1) TO WS-CHARACTER           
            EVALUATE WS-CHARACTER                                       
               WHEN '0' THRU '9'                                         
                  MOVE WS-CHARACTER TO LS-NUM-OUTPUT(WS-OPOS:1)         
                  SUBTRACT WS-LIT-ONE FROM WS-OPOS                       
            END-EVALUATE                                                 
                                                                         
            SUBTRACT WS-LIT-ONE FROM WS-IPOS                             
            IF WS-IPOS = WS-LIT-ONE                                     
               SET END-OF-STRING TO TRUE                                 
            END-IF.                                                     


Now, here's the acid test. I made two calls to the routine, with different values.

Call to Sub-Program
MOVE '$1234.00' TO WS-ALPHANUM-INPUT   
MOVE 'PROG99'   TO WS-PROGRAM           
CALL WS-PROGRAM USING WS-ALPHANUM-INPUT
                      WS-RETURN-CODE   
                      WS-NUM-OUTPUT     
                                       
DISPLAY WS-NUM-OUTPUT                   


Output
000000000000123400


Call to Sub-Program
MOVE '$3572.80' TO WS-ALPHANUM-INPUT   
CALL WS-PROGRAM USING WS-ALPHANUM-INPUT
                      WS-RETURN-CODE   
                      WS-NUM-OUTPUT     
                                       
DISPLAY WS-NUM-OUTPUT                   


Output
000000000000357280


Attached herewith, please find the complete COBOL Program for your reference. Now, I am confused about two things.
1. How do I handle Signs? Do I have to according set the nibble in the output? Like if its, -1234, should the output be 123M? Or do I just ignore the signs? I don't know how NUMVAL Behaves...
2. What if want to do extensive number validation? I know that every shop has their own numeric validation program(software), which takes inputs, and returns back the number representation of it, or sets a BAD Return Code.

Thank you very much.
You do not have the required permissions to view the files attached to this post.
Quasar Chunawala,
Software Engineer, Lives at Borivali, Mumbai
User avatar
Quasar
 
Posts: 102
Joined: Wed Nov 10, 2010 7:11 pm
Location: Borivali, Mumbai
Has thanked: 13 times
Been thanked: 2 times

Re: Custom Program to convert Text into its Numeric Equivale

Postby Robert Sample » Thu Jun 09, 2011 7:43 pm

1. NUMVAL handles signs and returns the appropriate overlay. Whether or not your code does so depends upon what you are doing and whether or not the signs are important.
2. How extensive are you wanting to get? Floating point notation for COMP-1 and COMP-2 values? Packed decimal (COMP-3)? What about places that swap the comma and decimal point? What about NATIONAL data? Depending upon how complicated you want to get, there's quite a few nuances that could be considered.
Robert Sample
Global moderator
 
Posts: 3719
Joined: Sat Dec 19, 2009 8:32 pm
Location: Dubuque, Iowa, USA
Has thanked: 1 time
Been thanked: 279 times

Re: Custom Program to convert Text into its Numeric Equivale

Postby BillyBoyo » Thu Jun 09, 2011 8:23 pm

Th1s i2 a numb3r?


Did you try the about through your routine? Do you get 123? Not really the answer you want?

For the signs, you have to find the sign (leading or trailing) in the string. If '-' subtract your final numeric from zero and replace with the negative result.

You're not really doing the decimal processing. What about giving it "12345.6789"?

Lengths, you have to pass from the calling program. LENGTH OF special-register or LENGTH instrinsic function. Format of output number would have to come from caller, but I can't think of an easy way to get the type other than hard-coding, unless there is an intrinsic function (haven't looked).

If you want to deal with floating point, you'll need to recognise the "E". Other alphas/non-numerics that can't appear in a number you should reject as error.

NUMVAL would reject your two examples due to the currency sign. NUMVALC would be needed.

If you want to deal with all this, you still have a way to go. NUMVAL has an advantage over you that the compiler can tell it everything it needs to know. NUMVAL itself returns a floating-point number, which the compiler then moves to the appropriate field in the COMPUTE. You might want to think of something like that to get around the output length/type problem.

What about programs using ARITH(31)? Your maximum input field would have to be longer.

You could go with fixed-length fields, in a copybook.

01 number string lenght 31 + commas, decimal-point and sign.
01 return code (I'd favour COMP PIC S9(4)).
01 output number, COMP-2

You'd have to do your "DISPLAY" number in WS of the sub-program and move to the linkage at the end.

Plus what Robert said.

It's a bigger task than you thought?
BillyBoyo
Global moderator
 
Posts: 3804
Joined: Tue Jan 25, 2011 12:02 am
Has thanked: 22 times
Been thanked: 265 times


Return to IBM Cobol

 


  • Related topics
    Replies
    Views
    Last post