|
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 mailing list archive is Copyright 1997-2025 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.