× 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: Fri, 18 Aug 2000 12:29:47 +0000
  • Organization: @Home Network Member

Thanks for this additional information, Richard.

Obviously, I misunderstood your earlier note and incorrectly assumed it referred
to the MI library functions, cvtefni and cvtefnd.

Hopefully, someone will follow up on your suggestion.

Yes, I used the 10,000 iterations technique.

Mel Rothman

Richard Jackson wrote:

> I looked at both cvtefni and cvtefnd before sending my note.  I didn't like
> the looks of either version so I didn't talk about them.
>
> The CVTEFN MI instruction has all the goodness of being implemented below
> the MI.  Can we write a routine in MI and make it bindable?  Do you suppose
> that we could convince someone to create a MI function call that returns
> packed instead of int or double?
>
> The MI code to perform Ms. Morris' routine will look something like this:
>
> DCL DD SOURCE CHAR(32) BAS(P02);
> DCL DD RECEIVER PKD(30,9) BAS(P01);
> DCL DD MASK CHAR(3) BAS(P03);
>
> CVTEFN RECEIVER, SOURCE, MASK ;
>
> Obviously we need some message monitors and the entry plist but this is the
> functional code equivalent to the GETNUM routine.  I think that it should be
> fast and it is nearly guaranteed to behave like reading numbers from a green
> screen.
>
> How did you produce your timing?  The tried and true 10,000 iterations
> technique?
>
> 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 3:31 PM
> To: RPG400-L@midrange.com
> Subject: Re: Character to Decimal
>
> 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 ...

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.