OS/400 Edition
Volume 3, Number 6 -- January 29, 2003

Converting Alpha to Numeric

Hey, Ted:

My AS/400 is receiving data from a shipping system through an ODBC connection. My RPG III (RPG/400) program needs to convert a nine-byte alphanumeric field to a number. The alpha field may contain zero or more digits, a decimal point, and two digits. How can I convert the alpha field to a number?

-- Duane

There are quite a few ways to convert alpha strings to numbers, Duane.

In your case, the easiest way is to let CL do the conversion. The Change Variable (CHGVAR) command can convert an alpha string to a packed decimal value. The alpha string can contain leading and/or trailing blanks, a leading hyphen for negative numbers, and a decimal point, which may be either a period or a comma.

Here's the program to convert the data.

PGM        PARM(&IN &OUT &RTNCD)         
DCL        VAR(&IN) TYPE(*CHAR) LEN(17)  
DCL        VAR(&OUT) TYPE(*DEC) LEN(15 2)
CHGVAR     VAR(&RTNCD) VALUE('0')        
CHGVAR     VAR(&OUT) VALUE(&IN)          
MONMSG     MSGID(CPF0818) EXEC(DO)       
   CHGVAR     VAR(&RTNCD) VALUE('1')     

The program returns a non-zero value in the third parameter if the input value is not convertible. An RPG III program would call the program this way:

C                     CALL 'NUM001CL'          
C                     PARM           ALPHA  17 
C                     PARM           NUM    152
C                     PARM           RTNCD   1

I have never had a performance problem with little programs like this, even though the CL program activates and deactivates on each call. If performance is a problem, you'll need to write an RPG routine to handle the conversion. I have used a method that I leaned in an assembly language class ages ago. It's based on Horner's Method, a way of expressing a polynomial without exponentiation. Here's the general idea.

C                     MOVE *ZERO     ACCUM  150
C           1         DO   9         X       30
C                     SUBSTALPHA:X   CHAR    1 
C                     MOVE CHAR      DIGIT   10
C                     MULT 10        ACCUM     
C                     ADD  DIGIT     ACCUM     
C                     ENDDO                    

You would have to beef up this code to handle invalid data, ignore leading and trailing blanks, and handle a decimal point.

If you can manage to get into the exciting world of ILE, you have more options.

If you are at V5R2, you can pass character strings to the %DEC, %DECH, %INT, %INTH, %UNS, %UNSH, and %FLOAT built-in functions. If the character string contains invalid data, the system ostensibly generates an exception with status code 105.

D Alpha           s             17                
D Num             s             15p 2             
D ValidData       s               n               

   ValidData = *on                      ;         
   monitor                              ;         
      num = %dec(Alpha:15:2)            ;         
   on-error 105                         ; 
      ValidData = *off                  ;         
   endmon                               ;         

I say "ostensibly" because you can't monitor for the 105 exception yet. There's a bug in the compiler that prevents you from listing error 105 in the on-error op code. I've reported it to IBM and I'm sure they'll have a PTF for it before long. Therefore, the above example has been not been tested with the monitor in place.

I'm not a fan of C, but binding the C run-time function atof is another possibility, as the following example shows.

D Alpha           s             17                          
D Num             s             15p 2                       
D atof            pr             8f   extproc('atof')       
D                                 *   value options(*string)
   num = %dech (atof (Alpha):15:2) ;                        
   *inlr = *on                     ;                        

Alpha contains the number to be converted. The options(*string) option terminates Alpha with a null character, as C requires of character strings. The num variable will be zero if Alpha contains invalid data.

I do not like this method because I do not like floating-point arithmetic. If you use atof, be sure to half-adjust the result, as I have done in this example. If you don't, the extracted number may not match the string. I also do not like the fact that invalid data returns a zero.

You can also use the Convert External Form to Numeric Value (cvtefn) MI library functions. I have played with them, and I consider them to be more trouble than they are worth.

Now that I've shared different ways to accomplish your task, let me tell you how I would handle this challenge. My preference would be to compile the CL source code in the first example into a module, which I would bind into an ILE program along with my RPG module. That would let me call the CL routine as a procedure, eliminating the overhead associated with calling a CL program. Only if performance were not acceptable would I consider another solution.

-- Ted

Sponsored By

Data Retrieval
on the AS/400 and iSeries
- Windows -
- Web -
- E-mail / FTP -
- Host Interface -

SEQUEL is the easiest, most versatile way to deliver AS/400 and iSeries data, no matter what your needs dictate! END USERS can create queries with almost no learning curve and without even knowing the database. PROGRAMMERS can get information in virtually any conceivable format, quickly and easily!

Read More / View Streaming Video


WorksRight Software



Converting Alpha to Numeric

Retrieve Qshell Exit Status in CL Programs

Reader Feedback and Insights: Effective Communication

Howard Arner
Joe Hertvik
Ted Holt
David Morris

Managing Editor
Mari Barrett

Publisher and
Advertising Director:

Jenny Thomas

Advertising Sales Representative
Kim Reed

Contact the Editors
Do you have a gripe, inside dope or an opinion?
Email the editors:

Copyright © 1996-2008 Guild Companies, Inc. All Rights Reserved.