'Operations with decimal numbers from a C++ program

The IBM i standard library provides the _DecimalT class for working with decimal numbers. However, compared to working on this type from C or RPG programs, working through the _DecimalT class is significantly inferior in performance (for a division operation, for example, about 10 times slower). The specified class uses function calls from standard service programs to perform operations on the decimal type. I think that slowdown happens just because of calls of these functions. Does anyone have any idea how to work with the decimal type from C++ programs more efficiently? Is it possible to use (directly or indirectly) the MI DIV instruction?



Solution 1:[1]

I do not think the MI DIV instruction is useable from ILE code. There is no bound program access provided for that instruction.

Look at the CPYNV instruction. Note it has a built in number used for access from ILE code: https://www.ibm.com/docs/en/i/7.2?topic=instructions-copy-numeric-value-cpynv

But not all MI instructions have an ILE built in number. The documentation on DIV does not include mention of a built in number.

Here is RPG code that runs the MI CPYNV instruction to copy from one RPG packed decimal variable to another. But without the built in number, I do not think you can do something comparable from ILE RPG or ILE C for the DIV instruction.

** --------------------- conMiScalar ----------------------- 
** value of the Type field in refScalarAttr struct.          
dconMiScalar_None...                                         
d                 c                   x'ff'                  
dconMiScalar_Bin  c                   x'00'                  
dconMiScalar_Zoned...                                        
d                 c                   x'02'                  
dconMiScalar_Packed...                                       
d                 c                   x'03'                  
dconMiScalar_Char...                                         
d                 c                   x'04'                  
dconMiScalar_UBin...                                         
d                 c                   x'0a'                  

** ----------------------- refScalar ---------------------------
** MI scalar operand.                                           
drefScalar        ds                  qualified based(@)        
d type                           1a                             
d lgth                           5i 0                           
d prec                           3i 0 overlay(lgth:1)           
d digits                         3i 0 overlay(lgth:2)           
d rsv1                          10i 0         

d csno            s             10p 0                   
d pvCsno          s             10p 0                   
d scalar_csno     ds                  likeds(refScalar) 
d scalar_pvCsno   ds                  likeds(refScalar)  
d msg             s             50a   varying
 /free                                                        
      csno        = 25 ;                                      
      clear       scalar_csno ;                               
      scalar_csno.type = conMiScalar_packed ;                 
      scalar_csno.prec = 0 ;                                  
      scalar_csno.digits = 10 ;   

      clear       scalar_pvCsno ;               
      scalar_pvCsno.type = conMiScalar_packed ; 
      scalar_pvCsno.prec = 0 ;                  
      scalar_pvCsno.digits = 10 ;            

      pr_LbCpyNv( %addr(pvCsno): %addr(scalar_pvCsno):   
                  %addr(csno): %addr(scalar_csno)) ;     
                                                         
      msg         = 'pvCsno:' + %char(pvCsno) ;          
      dsply       msg ;                                                                 

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 RockBoro