Ron, Another option would be to use the Late Bound Copy Numeric Value APIs. These allow you to convert from any numeric format to any nomeric format. I use these extensively in our dynamic applications along with a routine that converts a character value to a known numeric format. Here is the prototype and module for the API wrapper that I created: ************************************************** ******************************************** * Proto - CnvNumFmt * * By - David Morris * * Purpose - Convert format of numeric variables. * ************************************************** ******************************************** ************************************************** ******************************************** * CvtNumFmt Convert numeric format. * * Input: * * InpVar Left justified input value. * * InpFmt Input format, P/S/F/I/B/U. Packed/Zoned/Float/Integer/Binary/Unsigned int. * * InpPre Input value precision. * * InpDec Input value decimal positions. * * OutFmt Output format, I/P/S/U/B. * * OptOutPre Output value precision, default is input precision. If not passed, default * * is input precision. * * OptOutDec Output value decimal positions, default in input decimal positions. If not * * passed default is input decimal positions. * * HlfAdj Half adjust output, *ON=Half adjust, default is to truncate. * * Return: * * RtnVal Re-formatted left justified output value. * ************************************************** ******************************************** DCvtNumFmt PR 32A Return value. D InpVar 32A CONST D InpFmt 1A CONST D InpPre 5U 0 CONST D InpDec 5U 0 CONST D OutFmt 1A CONST D OptOutPre 5U 0 CONST OPTIONS(*OMIT: *NOPASS) D OptOutDec 5U 0 CONST OPTIONS(*OMIT: *NOPASS) D OptHlfAdj 1N CONST OPTIONS(*NOPASS) ************************************************** ******************************************** * HlfAdj Half adjust value and return result. * * Input: * * InpVar Left justified input value. * * InpFmt Input format, P/S/F/I/B/U. Packed/Zoned/Float/Integer/Binary/Unsigned int. * * InpPre Input value precision. * * InpDec Input value decimal positions. * * OptOutDec Output value decimal positions, default in input decimal positions. If not * * passed, default is zero. * * Return: * * RtnVal Half adjusted value left-adjusted. * ************************************************** ******************************************** DHlfAdj PR 32A Return value. D InpVar 32A CONST D InpFmt 1A CONST D InpPre 5U 0 CONST D InpDec 5U 0 CONST D OptOutDec 5U 0 CONST OPTIONS(*NOPASS) /TITLE CnvNumFmt - Convert the format of numeric values. ************************************************** ******************************************** * Module - CntNumFmt * * By - David Morris * * Purpose - Convert the format of numeric values. * * Compile - CRTRPGMOD MODULE(objlib/CntNumFmt) * * SRCFILE(srclib/QRPGLESRC) * * SRCMBR(CnvNumFmt) * * DBGVIEW(*SOURCE) * ************************************************** ******************************************** H NoMain H OPTION(*SRCSTMT) /COPY QPROTOSRC,CEEDOD /COPY QPROTOSRC,CEETSTA /COPY QPROTOSRC,CnvNumFmt ************************************************** ******************************************** * LBCpyNV C library function Late bound copy numeric value. * ************************************************** ******************************************** DLBCpyNV PR extproc('_LBCPYNV') D PR_pTgtVal * VALUE D PR_TgtTmp CONST LIKE(DPATmp) D PR_pSrcVal * VALUE D PR_SrcTmp CONST LIKE(DPATmp) ************************************************** ******************************************** * LBCpyNVR C library function Late bound copy numeric value with rounding. * ************************************************** ******************************************** DLBCpyNVR PR extproc('_LBCPYNVR') D PR_pTgtVal * VALUE D PR_TgtTmp CONST LIKE(DPATmp) D PR_pSrcVal * VALUE D PR_SrcTmp CONST LIKE(DPATmp) ********************** * Numeric descriptor * ********************** DDPATmp DS BASED(pDPATmp) D DPATyp 1A D DPAPre 5I 0 D DPADec 1A OVERLAY(DPAPre) D DPAReserved 10I 0 /TITLE CvtNumFmt - Convert numeric format. ************************************************** ******************************************** * *CvtNumFmt - Convert numeric format. * ************************************************** ******************************************** PCvtNumFmt B EXPORT DCvtNumFmt PI LIKE(RtnVar) D InpVar CONST LIKE(RtnVar) D InpFmt 1A CONST D InpPre 5U 0 CONST D InpDec 5U 0 CONST D OutFmt 1A CONST D OptOutPre 5U 0 CONST OPTIONS(*OMIT: *NOPASS) D OptOutDec 5U 0 CONST OPTIONS(*OMIT: *NOPASS) D OptHlfAdj 1N CONST OPTIONS(*NOPASS) ***************** * Return string * ***************** DRtnVar S 32A INZ(*LOVAL) ****************** * Work variables * ****************** DOutPre S LIKE(OptOutPre) DOutDec S LIKE(OptOutDec) DHlfAdj S LIKE(OptHlfAdj) DSrcVar S LIKE(InpVar) ************************** * Convert to single byte * ************************** D DS D CvtNum 5U 0 D CvtByt 1A OVERLAY(CvtNum: 2) ********************** * Numeric descriptor * ********************** DSrcTmp S LIKE(DPATmp) DTgtTmp S LIKE(DPATmp) ************************ * Define numeric types * ************************ DSIGNED C x'00' DFLOAT C x'01' DZONED C x'02' DPACKED C x'03' DUNSIGNED C x'0A' C* Set output decimal precision, default is input precision. C IF %PARMS >= 6 C CALLP CEETSTA(ArgPas: 6: *OMIT) Precision passed? C END C IF ArgPas = 1 AND C %PARMS >= 6 C EVAL OutPre = OptOutPre C ELSE C EVAL OutPre = InpPre C END C* Set output decimal places, default is input decimals. C IF %PARMS >= 7 C CALLP CEETSTA(ArgPas:7:*OMIT) Decimal Pos passed? C END C IF ArgPas = 1 AND C %PARMS >= 7 C EVAL OutDec = OptOutDec C ELSE C EVAL OutDec = InpDec C END C* Set half adjust, default to truncate. C IF %PARMS >= 8 C EVAL HlfAdj = OptHlfAdj C ELSE C EVAL HlfAdj = *OFF C END C* C* Setup source template. C EVAL pDPATmp = %ADDR(SrcTmp) C SELECT C WHEN InpFmt = 'P' C EVAL DPATyp = PACKED C WHEN InpFmt = 'S' C EVAL DPATyp = ZONED C WHEN InpFmt = 'F' C EVAL DPATyp = FLOAT C WHEN InpFmt = 'I' OR C InpFmt = 'B' C EVAL DPATyp = SIGNED C WHEN InpFmt = 'U' C EVAL DPATyp = UNSIGNED C OTHER C ENDSL C* C EVAL DPAPre = InpPre C EVAL CvtNum = InpDec C EVAL DPADec = CvtByt C EVAL DPAReserved = *ZEROS C* C* Setup target template. C EVAL pDPATmp = %ADDR(TgtTmp) C SELECT C WHEN OutFmt = 'P' C EVAL DPATyp = PACKED C WHEN OutFmt = 'S' C EVAL DPATyp = ZONED C WHEN OutFmt = 'F' C EVAL DPATyp = FLOAT C WHEN OutFmt = 'I' OR C OutFmt = 'B' C EVAL DPATyp = SIGNED C WHEN OutFmt = 'U' C EVAL DPATyp = UNSIGNED C OTHER C ENDSL C* C EVAL DPAPre = OutPre C EVAL CvtNum = OutDec C EVAL DPADec = CvtByt C EVAL DPAReserved = *ZEROS C* C EVAL SrcVar = InpVar C* C IF HlfAdj C CALLP LBCPYNVR( C %ADDR(RtnVar): C TgtTmp: C %ADDR(SrcVar): C SrcTmp) C ELSE C CALLP LBCPYNV( C %ADDR(RtnVar): C TgtTmp: C %ADDR(SrcVar): C SrcTmp) C END HlfAdj C* C RETURN RtnVar PCvtNumFmt E /TITLE HlfAdj - Half adjust numeric value. ************************************************** ******************************************** * *HlfAdj - Half adjust numeric value. * ************************************************** ******************************************** PHlfAdj B EXPORT DHlfAdj PI LIKE(RtnVar) D InpVar CONST LIKE(RtnVar) D InpFmt 1A CONST D InpPre 5U 0 CONST D InpDec 5U 0 CONST D OptOutDec 5U 0 CONST OPTIONS(*NOPASS) ***************** * Return string * ***************** DRtnVar S 32A INZ(*LOVAL) DOutDec S LIKE(OptOutDec) INZ(*ZEROS) C IF %PARMS >= 5 C EVAL OutDec = OptOutDec C ENDIF C* C EVAL RtnVar = CvtNumFmt( C InpVar: C InpFmt: C InpPre: C InpDec: C InpFmt: C InpPre: C OutDec: C *ON) C* C RETURN RtnVar PHlfAdj E For converting character values to string, I based my code on something published in the RPG Building Block section of Midrange Computing back in 1998. I beleive that Barbara Morris has posted a more up to date and efficient version in this forum. David Morris