Programming Languages on Power

Power Programming Languages

IBM Power, including the AIX, IBM i, and Linux operating systems, support a wide range of programming languages, catering to both traditional enterprise applications and modern development needs.


#Power

 View Only
  • 1.  Rpgle problem with div operation

    Posted Mon January 30, 2023 06:48 AM
    Hi, 

    In a specific protocol, our client ask to send data without decimal, a number of 33,98 I have to convert it into (339800000), and in output  I didn't have  any problem,  but in input this is converted to float and when I divide my number from  (339800000) to 33,98 I receive a float like 33.979999999999996.

    here's my sample program:

    **free
    Ctl-Opt  DftActGrp(*no)
      ActGrp(*StgMdl)
      StgMdl(*SNGLVL)
      BndDir('AL400MNUV2')
      Thread(*Concurrent)
      Option(*NoUnRef :*SrcStmt :*NoDebugIo)
      DatFmt(*Iso) TimFmt(*Iso)
      Debug(*Constants)
      AlwNull(*UsrCtl)
      FltDiv(*yes)
      DftName(TESTDEC)
      Text('Test decimali');
    
    // ________________________________________________________
    //      Campi di work
    Dcl-S PrezzoChar      Char(20) Inz('339800000');
    Dcl-S PrezzoDec       Packed(30:15);
    Dcl-S PrezzoFloat     Float(8);
    
    Dcl-Pr DspLongMsg ExtPgm('QUILNGTX');
      Text      Char(16773100) const options(*varsize);
      Length    Int(10)     Const;
      Msgid     Char(7)     Const;
      Qualmsgf  Char(20)    Const;
      ErrorCode Char(32767) options(*varsize);
    End-Pr DspLongMsg;
    
    Dcl-Ds ApiError Qualified;
      BytPrv    Int(10) Inz(%Size(ApiError));
      BytAvl    Int(10) Inz(0);
      MsgId     Char(7);
      *n        Char(1);
      MsgDta    Char(128);
    End-Ds ApiError;
    
    Dcl-Ds TextMsg;
      TextArr Char(80) Dim(24);
    End-Ds TextMsg;
    // ___________________________________________________________________________
    
    PrezzoDec = %Dec(PrezzoChar : 30 :15) / (10**7);
    PrezzoFloat = %Int(PrezzoChar) / (10**7);
    PrezzoDec = %Dec(PrezzoFloat :30 :15) ;
    
    TextArr(1) = 'Prezzo Float: ' + %Char(PrezzoFloat);
    TextArr(2) = 'Prezzo Dec  : ' + %Char(PrezzoDec);
    
    DspLongMsg(TextMsg:%Len(TextMsg):'':'':ApiError);
    
    Return;​


    I try the H spec FLTDIV, but it seems there's no effect...

    Anyone have a solution?

    Many thanks.

    ------------------------------
    Paolo Salvatore
    ------------------------------

    #RPG


  • 2.  RE: Rpgle problem with div operation

    Posted Mon January 30, 2023 07:50 AM
    Hi Paolo,

    it seems, that you have a Float factor in your expression - because normally a decimal expression results in a decimal result. 

    Please try to use 10000000 instead of 10**7 - the intermediate data type of the ** operator is Float by definition. 

    HTH
    Daniel





  • 3.  RE: Rpgle problem with div operation

    Posted Wed February 01, 2023 04:40 AM
    HI Daniel, 

    thank you for your answer, using a work field type int to make the 10**7 it works perfectly.

    Many thanks

    ------------------------------
    Paolo Salvatore
    ------------------------------



  • 4.  RE: Rpgle problem with div operation

    Posted Wed February 01, 2023 09:30 AM

    Hi Paolo,

    If you coded your work field like this:

    workfld = 10 ** 7;

    It's better to ensure that the float value is rounded when it is assigned to a non-float value.

    workfld = %inth(10 ** 7);
    
    OR
    
    eval(h) workfld = 10 ** 7;


    ------------------------------
    Barbara Morris
    ------------------------------



  • 5.  RE: Rpgle problem with div operation

    Posted Wed February 01, 2023 02:26 PM
    Hi Barbara, Hi Paolo,

    shouldn't it be OK to write something like this:

       PrezzoDec = %Dec(PrezzoChar : 30 :15) / %Int(10**7);

    Is that case, the divisor is an int - not a float - which should result in a decimal result.

    So the workfld shouldn't be necessary.

    Kind regards,
    Daniel





  • 6.  RE: Rpgle problem with div operation

    Posted Wed February 01, 2023 05:34 PM

    Hi Daniel,

    You're right that the work field isn't necessary.

    But you should code %INTH, not %INT.

    Even if %INT(10**7) does return 10000000, it's possible that some %INT(10**n) would return an unexpected value if the float value for 10**N was a tiny bit less than 10**N rather than a tiny bit more. Many decimal values cannot be expressed exactly as a float value, so the float value is often a tiny bit off either more or less than the decimal value. So using half-adjust is always a good idea when going from float to non-float.



    ------------------------------
    Barbara Morris
    ------------------------------