× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.


  • Subject: Re: Character to Decimal
  • From: Mel Rothman <melrothman@xxxxxxxx>
  • Date: Thu, 17 Aug 2000 16:31:09 -0500

According to the MI Library reference, "The cvtefni and cvtefnd
functions scans a character string for a valid decimal number in display
format, removes the display character, and converts the 
result to integer (in the case of cvtefni) or double (in the case of
cvtefnd)."

Cvtefni handles only whole numbers.  Cvtefnd's double lacks the required
precision.  

Barbara Morris's solution overcomes both and it is much faster than
cvtefnd.

Using two versions of c2n subprocedures (not available for posting
because of they are part of a copyrighted package), one using cvtefnd,
the other a simplified version of Barbara's code, Barbara's code is 4.7
to 4.9 times faster.  In both cases the input string is 30.9,
'123456789012345678901.123456789'.

More important, the cvtefnd version returns the wrong answer,
123456789012345683968.000000000 and Barbara's returns the right answer,
123456789012345678901.123456789.


Mel Rothman


Richard Jackson wrote:
> 
> Can someone with access to an MI compiler post a program that contains
> CVTEFN?  It has got to be faster than this.
> 
> Richard Jackson
> mailto:richardjackson@richardjackson.net
> www.richardjacksonltd.com
> Voice: 1 (303) 808-8058
> Fax:   1 (303) 663-4325
> 
> -----Original Message-----
> From: owner-rpg400-l@midrange.com [mailto:owner-rpg400-l@midrange.com]On
> Behalf Of Mel Rothman
> Sent: Thursday, August 17, 2000 1:45 PM
> To: RPG400-L@midrange.com
> Subject: Re: Character to Decimal
> 
> Colin Thorpe wrote:
> >
> > Hi all,
> >
> > I am trying to take a character field (10A) containing something like
> > 123.45bbbbb,
> > And move it into a numeric field (12,2) 0000000123.45.
> >
> > The character field may or may not contain a decimal point.
> > Therefore its value could be from  .01 ==> 9999999999
> >
> > Some time ago the C function ATOL was mentioned by Hans.
> >
> > I'm using V3R7 and managed to get his example working fine.
> >
> > Unfortunately this only returns the integer part of the value.
> >
> > I also tried ATOF but I'm not sure what the resulting value means.
> 2235.14
> > = 1079246848 ?
> >
> > I can solve this problem using data structures and selects but I'm looking
> > for an elegant ILE solution.
> >
> > Any help will be greatly appreciated.
> >
> > Thanks in advance
> >
> > Colin
> 
> Colin, Barbara Morris from IBM's Toronto, Canada has posted the
> following in several places.  I think it is just what you are asking
> for.
> 
> Mel Rothman
> 
> <-----* prototype for /COPY file start here ----->
> 
>       *---------------------------------------------------------
>       * getNum - procedure to read a number from a string
>       *          and return a 30p 9 value
>       * Parameters:
>       *   I:      string   - character value of number
>       *   I:(opt) decComma - decimal point and digit separator
>       *   I:(opt) currency - currency symbol for monetary amounts
>       * Returns:  packed(30,9)
>       *
>       * Parameter details:
>       *   string:   the string may have
>       *             - blanks anywhere
>       *             - sign anywhere
>       *               accepted signs are: + - cr CR ()
>       *               (see examples below)
>       *             - digit separators anywhere
>       *             - currency symbol anywhere
>       *   decComma: if not passed, this defaults to
>       *                 decimal point   = '.'
>       *                 digit separator = ','
>       *   currency: if not passed, defaults to ' '
>       *
>       * Examples of input and output (x means parm not passed):
>       *
>       *        string         | dec | sep | cursym |   result
>       *        ---------------+-----+-----+--------+------------
>       *          123          | x   | x   | x      |   123
>       *          +123         | x   | x   | x      |   123
>       *          123+         | x   | x   | x      |   123
>       *          -123         | x   | x   | x      |   -123
>       *          123-         | x   | x   | x      |   -123
>       *          (123)        | x   | x   | x      |   -123
>       *          12,3         | ,   | .   | x      |   12.3
>       *          12.3         | x   | x   | x      |   12.3
>       *          1,234,567.3  | x   | x   | x      |   1234567.3
>       *          $1,234,567.3 | .   | ,   | $      |   1234567.3
>       *          $1.234.567,3 | ,   | .   | $      |   1234567.3
>       *          123.45CR     | x   | x   | x      |   -123.45
>       *
>       * Author: Barbara Morris, IBM Toronto Lab
>       * Date:   March, 2000
>       *---------------------------------------------------------
>      D getNum          pr            30p 9
>      D  string                      100a   const varying
>      D  decComma                      2a   const options(*nopass)
>      D  currency                      1a   const options(*nopass)
> 
> <-----* prototype for /COPY file end here ----->
> 
> <-----* test program start here----->
> 
>       * Copy prototype for procedure getNum
>      D/COPY GETNUM_P
> 
>      D res             s                   like(getNum)
>      D msg             s             52a
> 
>      C     *entry        plist
>      C                   parm                    p                32
>      C                   parm                    dc                2
>      C                   parm                    c                 1
> 
>      C                   select
>      C                   when      %parms = 1
>      C                   eval      res = getNum(p)
>      C                   when      %parms = 2
>      C                   eval      res = getNum(p : dc)
>      C                   when      %parms = 3
>      C                   eval      res = getNum(p : dc : c)
>      C                   endsl
>      C                   eval      msg = '<' + %char(res) + '>'
>      C     msg           dsply
> 
>      C                   return
> 
> <-----* test program end here----->
> 
> <-----* module GETNUM start here ----->
> 
>      H NOMAIN
> 
>       * Copy prototype for procedure getNum
>      D/COPY GETNUM_P
> 
>      p getNum          b
>      D getNum          pi            30p 9
>      D  string                      100a   const varying
>      D  decComma                      2a   const options(*nopass)
>      D  currency                      1a   const options(*nopass)
> 
>       * defaults for optional parameters
>      D decPoint        s              1a   inz('.')
>      D comma           s              1a   inz(',')
>      D cursym          s              1a   inz(' ')
>       * structure for building result
>      D                 ds
>      D result                        30s 9 inz(0)
>      D resChars                      30a   overlay(result)
>       * variables for gathering digit information
>       * pNumPart points to the area currently being gathered
>       * (the integer part or the decimal part)
>      D pNumPart        s               *
>      D numPart         s             30a   varying based(pNumPart)
>      D intPart         s             30a   varying inz('')
>      D decPart         s             30a   varying inz('')
>       * other variables
>      D intStart        s             10i 0
>      D decStart        s             10i 0
>      D sign            s              1a   inz('+')
>      D i               s             10i 0
>      D len             s             10i 0
>      D c               s              1a
> 
>       * override defaults if optional parameters were passed
>      C                   if        %parms > 1
>      C                   eval      decPoint = %subst(decComma : 1 : 1)
>      C                   eval      comma    = %subst(decComma : 2 :1)
>      C                   endif
> 
>      C                   if        %parms > 2
>      C                   eval      cursym = currency
>      C                   endif
> 
>       * initialization
>      C                   eval      len = %len(string)
>       * begin reading the integer part
>      C                   eval      pNumPart = %addr(intPart)
> 
>       * loop through characters
>      C                   do        len           i
>      C                   eval      c = %subst(string : i : 1)
> 
>      C                   select
>       * ignore blanks, digit separator, currency symbol
>      C                   when      c = comma or c = *blank or c = cursym
>      C                   iter
>       * decimal point: switch to reading the decimal part
>      C                   when      c = decPoint
>      C                   eval      pNumPart = %addr(decPart)
>      C                   iter
>       * sign: remember the most recent sign
>      C                   when      c = '+' or c = '-'
>      C                   eval      sign = c
>      C                   iter
>       * more signs: cr, CR, () are all negative signs
>      C                   when      c = 'C' or c = 'R' or
>      C                             c = 'c' or c = 'r' or
>      C                             c = '(' or c = ')'
>      C                   eval      sign = '-'
>      C                   iter
>       * a digit: add it to the current build area
>      C                   other
>      C                   eval      numPart = numPart + c
> 
>      C                   endsl
>      C                   enddo
> 
>       * copy the digit strings into the correct positions in the
>       * zoned variable, using the character overlay
>      C                   eval      decStart = %len(result) -
> %decPos(result)
>      C                                      + 1
>      C                   eval      intStart = decStart - %len(intPart)
>      C                   eval      %subst(resChars
>      C                                  : intStart
>      C                                  : %len(intPart))
>      C                               = intPart
>      C                   eval      %subst(resChars
>      C                                  : decStart
>      C                                  : %len(decPart))
>      C                               = decPart
>       * if the sign is negative, return a negative value
>      C                   if        sign = '-'
>      C                   return    - result
>       * otherwise, return the positive value
>      C                   else
>      C                   return    result
>      C                   endif
>      p                 e
> 
> <-----* module GETNUM end here ----->
+---
| This is the RPG/400 Mailing List!
| To submit a new message, send your mail to RPG400-L@midrange.com.
| To subscribe to this list send email to RPG400-L-SUB@midrange.com.
| To unsubscribe from this list send email to RPG400-L-UNSUB@midrange.com.
| Questions should be directed to the list owner/operator: david@midrange.com
+---

As an Amazon Associate we earn from qualifying purchases.

This thread ...

Follow-Ups:
Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.