I have a piece of cobol code that converts a variable X(17) to numeric using NUMVAL function. The pogram is failing with "Invalid argument to the function at column 16".
I figured out the issue, the file from which am reading the alphanumeric varibale is having spaces towards the end where the position is not being filled with numbers as a result the NUMVAL function can't take the spaces in its argument and is failing.
Any solution how this issue can be resolved, my alplanumeric variable can't be less than X(17). Is there any way I can avoid passing these spaces to the function. Anything if can be done in JCL through sort or any other ustilities would also be acceptable.
Any sort of valid response is greatly appreciated.
Joined: 18 Jun 2009 Posts: 407 Location: Nashville, TN
Hi BJ,
Can u provide some samples - Input and the Expected Output.
Would really like to know if spaces will be always at the last only (trailing) or is there a possibility that it could come in the front also like ' 12345 ' ?
Joined: 27 Oct 2009 Posts: 2481 Location: Netherlands, Amstelveen
The NUMVAL function returns the numeric value represented by the alphanumeric character string or national character string specified as the argument. The function removes any leading or trailing spaces in the string to produce a numeric value.
Quote:
the alphanumeric varibale is having spaces towards the end where the position is not being filled with numbers as a result the NUMVAL function can't take the spaces
Joined: 18 Jun 2009 Posts: 407 Location: Nashville, TN
Hi BJ,
Please refer manuals about NUMVAL. It should still work for the scenario you mentioned.
Quote:
The NUMVAL and NUMVAL-C functions convert character strings to numbers. Use these functions to convert alphanumeric data items that contain free format character representation numbers to numeric form, and process them numerically. For example:
01 R PIC X(20) VALUE "- 1234.5678".
01 S PIC X(20) VALUE "-$12,345.67CR".
01 TOTAL USAGE IS COMP-2.
.
.
.
COMPUTE TOTAL = FUNCTION NUMVAL(R) + FUNCTION NUMVAL-C(S).
The difference between NUMVAL and NUMVAL-C is that NUMVAL-C is used when the argument includes a currency symbol or comma, as shown in the example. You can also place an algebraic sign in front or in the rear, and it will be processed. The arguments must not exceed 18 digits (not including the editing symbols).
Joined: 29 Oct 2010 Posts: 121 Location: Puerto Rico
Good day to all!
It seem that NUMVAL doesn't handle spaces embedded between digits in the string. You will have to do an INSPECT on the string replacing all ' ' to '.' and then do the NUMVAL.
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
bibek24 wrote:
Hi,
I have a pieuce of cobol code that converts a varibale X(17) to numeric using NUMVAL function. The pogram is failing with "Invalid argument to the function at column 16".
I figured out the issue, the file from which am reading the alphanumeric varibale is having spaces towards the end where the position is not being filled with numbers as a result the NUMVAL function can't take the spaces in its argument and is failing.
Any solution how this issue can be resolved, my alplanumeric variable can't be less than X(17). Is there any way I can avoid passing these spaces to the function. Anything if can be done in JCL through sort or any other ustilities would also be acceptable.
Any sort of valid response is greatly appreciated.
Thanks
BJ
Mmmm...
Looking a bit closer, it would seem you have this sort of thing:
After your numeric-edited number, which you are trying to convert, you have some space followed by a single character.
You get a U4038 abend. You didn't mention that, and you didn't paste the full message, where an apparent "double space" would have been a clue.
Yes? Or no?
You have bad data as far as your field is concerned. If it is every record, perhaps the data definition is incorrect. If it is only a one or not-all records, it is just plain bad data.
If it is a bad data definition, you can fix it. If it is bad data, you have to avoid giving it to NUMVAL :-), and, of course, deal with it cleanly in your program (or skim out the rubbish for evaluation by a human, earlier than your program).
One thing you can't do is try to fix the data on-the-fly, as you don't know what it should have been.
If you can have more than 15 digits, are you using compiler option ARITH(EXTEND)? Otherwise your results might not be accurate (if you actually get any).
The funny thing is, if you do the work to validate the fielld, you'd probably not need NUMVAL :-)
MOVE ZERO TO WS-FIELD.
MOVE '1A2B3C4D5E6F' TO WS-WORK.
MOVE LENGTH OF WS-FIELD TO WS-SUB-1, WS-SUB-2.
PERFORM UNTIL WS-SUB-1 < 1
IF (WS-WORK (WS-SUB-1:1) NOT < ZERO
AND WS-WORK (WS-SUB-1:1) NOT > '9')
MOVE WS-WORK (WS-SUB-1:1)
TO WS-FIELD (WS-SUB-2:1)
SUBTRACT 1 FROM WS-SUB-2
END-IF
SUBTRACT 1 FROM WS-SUB-1
END-PERFORM.
Once completed, WS-FIELD will be right-justified with high-order ZEROS (00000000000123456).
With a little bit of ingenuity, you can create WS-FIELD as left-justified with low-order ZEROS.
Sorry for not giving the exact details. Below is the file that am processing. The file length is 200. The fields are:
Field1 - X(12)
Field2 - X(8)
Field3 -X(3)
Field4 - X(17)
Field5 - (17)
I am using NUMVAL for Field4 and Field5. The NUMVAL function works file for Field4 as no trailing spaces are there but it fails for Field5 which I feel there are trailing spaces.
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
Are you sure?
Subject to counting errors, field 5 is 17 characters, including trailing spaces, which should work with NUMVAL nicely, as indicated by Peter early today.
Field 4 looks more like 14 characters, and a field of three bytes containing some value which is non-displayable without HEX ON, so if it is 17 bytes long, that would cause you the problem. You'd need to either define the field as 14, followed by another field of three bytes, if that is what it should be, or correct whatever populates the field so that it contains trailing spaces if the number is not big enough, not trailing "whatevers".
I think I have to explain my whole processing am doing with these files. Here it is:
I have 2 VB files for which I have to put a file comparision logic. The field lengths are not defined in these files, so I can't do a comparision with this.
First am unstinging the data delimited by comma (,)and giving field length to each of the field through Eagle88 utility. The first field being 12 characters is my key and based on this key am comparing the files through a cobol program. After unstring, the file layout is what I have already defined in the previous response.
After unstring and defining field length, the file looks like below
The unstring is formating the Field4 nicely by putting some non-displayble characters at last 3 position of total 17 which is being accepted by numval function but as we don't have a comma to the end of Field 5, its taking spaces and NUMVAL is not accepting it.
Also I have keep the field length as X(17) as the data is expected so.
Ideally thats true NUMVAL should accept spaces but am really not sure why its behaving this way.
I wish if I can put a comma to the end of Field5 after trimming the trailing spaces but not sure how to trim the spaces in JCL. Am not willing to put a new program for this. If you can help me trimming spaces and putting a comma at end of field5, I can try applying the unstring utility and that may work I believe.
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
Here is my advice. Read Peter's posting. Read my last posting. Read dbz's posting.
NUMVAL is enormously happy with leading blanks and trailing blanks. NUMVAL does not like embedded blanks, but you don't have any.
So, along with leading/trailing blanks, NUMVAL likes a correctly formatted numeric-edited field. NUMVAL likes nothing else. NUMVAL hates everything else and will reveal to you the beauty of a U4038 user-abend if presented with anything else.
Now, from your definitions and your data that you have given us as input to your program, and your description of the processing which you and your Eagle-buddy carry out:
Field5 will convert perfectly with NUMVAL
Filed4 will cause NUMVAL to rush to the nearest "bathroom" and toss a U4038 down the porcelain throne (out of the way, dbz!).
Hi Akatsukami! There are always three things.
Have a close look at the message you are getting. Yes, the IGZ0152S. Look closer. Look in HEX. Do you see X'40??40' in between "character" and "was"? If that ?? is one of your nice formatting non-display characters, what then?
Now, you can shimmy and shammy about it as much as you like. You've lost a day looking at the wrong field because you didn't like the look of that field, but you liked the look of the other one. NUMVAL strongly disagrees with you.
Now, further advice. Nicley remove the nice formatting from Field4, so that it has spaces in the last three bytes. For the heck of it, if you don't believe me, get in an editor and do it by hand on a copy of the file (no double entendre intended). Then run your program. Then explain, if you can.
More further advice. The first thing to do before looking any further at an abend is to find out which instruction is causing it. I know there are shortcuts, but until you can understand what the computer is up to, not just follow what you think, I'd not advise you to take any (shortcuts, not advice).
More further advice. If looking for help here, answer questions asked (they are not asked just for the fun of it) and read what people post. If you don't understand what people have posted, first try to, really hard, with the assumption that they are correct. If you still don't get it, ask. Next time you won't waste a day.
At least one question you didn't answer, are you using more than 15 digits? (you seem to have 10 in front of the decimal and six after, but maybe they can't occur at the same time). If yes, what is the value of ARITH for your compiler options?
OK. Enough. Fix it. Have a good week end. You 'n "The Eagle" going anywhere nice?
Thanks all for your valuable response. I could figure out the issue with the unstring card. You were right, the problem was with the 1st amount field with non-displayable characters.
I changed my unstring card a little and initialize the output before writing and that worked.
Thanks again for you help!!!!
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
Thanks for letting us know. A brave move of yours, I think. Shows promise I hope.
With this business, you have to have an open mind. Someone can stare at a problem for hours, but if they are not looking at the right thing, it is time entirely wasted. If you don't get anywhere after a couple of hours, tear up everything you "know" about the problem, and start again - it is probably something that you "know" which is getting in the way of you solving it. The Computer is always right, it only does what we tell it, and sometimes we tell it the wrong things. It is always us who is wrong.
Now, what about that question I keep asking... can you confirm you are happy about the size of your fields?
Programming Guide wrote:
At most 15 decimal digits can be converted accurately to long-precision floating point (as described in the related reference below about conversions and precision). If the argument to NUMVAL or NUMVAL-C has more than 15 digits, it is recommended that you specify the ARITH(EXTEND) compiler option so that an extended-precision function result that can accurately represent the value of the argument is returned.
Language Reference wrote:
If the ARITH(COMPAT) compiler option is in effect, the total number of digits must not exceed 18. If the ARITH(EXTEND) compiler option is in effect, the total number of digits must not exceed 31.
You could try to check. I think one followed by 15 zeros is not a problem in retaining precision, but one followed by 15 ones might be.