ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

Contribution: Put large number into 64-bit binary form

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Contribution: Put large number into 64-bit binary form

    OS/400 releases before 7.1 do not allow %BINARY with more than 32-bit fields and even then it has to be signed. The following CL code takes the input parameter (a 15 digit decimal) and puts it into a 64-bit binary field &HIGHLOWBIN. This is defined as *CHAR LEN(8). The code is not useful in itself, I have developed it so I could include it in a CLP that creates a user space and updates it with a passed value, which is a start point for a trigger program - for a data warehouse. If you want to see it work, create a command to feed the 15 digit decimal into it (don't try a call pgm) and put the program in debug.

    PGM PARM(&STARTPOINT)
    DCL VAR(&STARTPOINT) TYPE(*DEC) LEN(15 0)
    DCL VAR(&INT4LIMS) TYPE(*DEC) LEN(10 0)
    DCL VAR(&INT4LIMU) TYPE(*DEC) LEN(10 0)
    DCL VAR(&WORKNBR) TYPE(*DEC) LEN(15 0)
    DCL VAR(&HIGHORDER) TYPE(*DEC) LEN(10 0)
    DCL VAR(&LOWORDER) TYPE(*DEC) LEN(10 0)
    DCL VAR(&HIGHBIN) TYPE(*CHAR) LEN(4)
    DCL VAR(&LOWBIN) TYPE(*CHAR) LEN(4)
    DCL VAR(&HIGHLOWBIN) TYPE(*CHAR) LEN(8)

    CHGVAR VAR(&INT4LIMS) VALUE(2147483648)
    CHGVAR VAR(&INT4LIMU) VALUE(4294967296)

    CHGVAR VAR(&WORKNBR) VALUE(&STARTPOINT)
    DOWHILE COND(&WORKNBR >= &INT4LIMU)
    CHGVAR VAR(&WORKNBR) VALUE(&WORKNBR - &INT4LIMU)
    CHGVAR &HIGHORDER (&HIGHORDER + 1)
    ENDDO

    CHGVAR &LOWORDER &WORKNBR
    IF COND(&WORKNBR >= &INT4LIMS) THEN(DO)
    CHGVAR VAR(&LOWORDER) VALUE(&WORKNBR - &INT4LIMU)
    ENDDO

    CHGVAR %BIN(&HIGHBIN) &HIGHORDER
    CHGVAR %BIN(&LOWBIN) &LOWORDER
    CHGVAR &HIGHLOWBIN (&HIGHBIN *CAT &LOWBIN)
    ENDPGM: ENDPGM

  • #2
    Re: Contribution: Put large number into 64-bit binary form

    Digging through MI instructions can help with some messy processing. Manipulation of large values can be done with some MI builtin functions. The Copy Numeric Value (CPYNV) MI instruction has a builtin form that can be called as procedure '_LBCPYNV'. The proc can convert many numeric types of all valid scales and precisions to pretty much all others.

    This shows a couple examples:
    Code:
    pgm    ( +
             &PckDec15_0  +
           )
    
       dcl   &PckDec15_0  *dec   ( 15 0 )
    
    
       dcl   &PckDecNew   *char     8     value( x'000000000000000F' )
    
       dcl   &RtnVal      *char     8     value( ' ' )
    
    /* Value definitions:                                            */
    /*    Reserved hex zeros:                            ********    */
    /* Total digits or bytes:                          **            */
    /* Fractional digits:                            **              */
    /* Data type:                                  **                */
       dcl   &Dec_Dfn     *char     7     value( x'03000F00000000' )
       dcl   &SBin_Dfn    *char     7     value( x'00000800000000' )
       dcl   &Flt_Dfn     *char     7     value( x'01000800000000' )
    
    /* Get *DEC (15 0) into 8-byte Signed Binary form in &RtnVal... */
       callprc      '_LBCPYNV'   ( +
                                   &RtnVal        +
                                   &SBin_Dfn      +
                                   &PckDec15_0    +
                                   &Dec_Dfn       +
                                 )
    
    
    /* dmpclpgm */
    
    /* ...and turn 8-byte Signed Binary into new *DEC (15 0) form... */
       callprc      '_LBCPYNV'   ( +
                                   &PckDecNew     +
                                   &Dec_Dfn       +
                                   &RtnVal        +
                                   &SBin_Dfn      +
                                 )
    
    dmpclpgm
    
       return
    
    endpgm
    The program accepts a *DEC (15 0) value and converts it to an 8-byte signed integer form in &RtnVal. The conversion is controlled by the two structures I named &Dec_Dfn and &SBin_Dfn. The contents of those are defined in the Set Data Pointer Attributes (SETDPAT) documentation.

    For &Dec_Dfn, the first byte is x'03' for a packed decimal. Then 1-byte of x'00' for zero fractional positions and x'0F' for 15 total digits. For &SBin_Dfn, it's 1-byte of x'00' for signed binary and 2-bytes of x'0008' to indicate 8-bytes, or 64-bits. (I added an unused &Flt_Dfn to show how a FLOAT8 could be described. FLOAT8 values are used for various useful APIs.

    I also added a second call to '_LBCPYNV' for added illustration. The &RtnVal variable is converted back to a *DEC (15 0) form, but it's stored in a *CHAR (8) variable. That can be handy when packed values need to be handled for substrings. It also emphasizes that the handling of the values is based on the structure templates and not on the DCL definitions.

    The DMPCLPGM just shows what all resulting values look like in program variables and memory.

    Example call:
    Code:
    call TSTCPYNV parm( x'123456789012345D' )
    That calls with a packed value of (-123456789012345). The x'D' makes it negative. You can use x'F' at the end if you want positive. The digits can be zeros, but it's important to have exactly 15 numeric digits along with the sign character between the quotes.
    Attached Files
    Tom

    There are only two hard things in Computer Science: cache invalidation, naming things and off-by-one errors.

    Why is it that all of the instruments seeking intelligent life in the universe are pointed away from Earth?

    Comment


    • #3
      Re: Contribution: Put large number into 64-bit binary form

      Thanks tomliotta

      I am new to MI having just started using _CMPSWP but I do prefer your direct solution to my own convoluted approach.

      Comment


      • #4
        Re: Contribution: Put large number into 64-bit binary form

        Most "thanks" would go to Bruce Vining, the ex-IBMer who provides numerous examples of using MI builtins with ILE CL. A Google search could lead to many articles by him. In this case, I'm just helping spread some info. Everybody has to learn from somewhere.
        Tom

        There are only two hard things in Computer Science: cache invalidation, naming things and off-by-one errors.

        Why is it that all of the instruments seeking intelligent life in the universe are pointed away from Earth?

        Comment

        Working...
        X