Comment My gimmicky version of the ENCODE() function

Cecil

19+ years progress programming and still learning.
A few optimizations (from my early Z80 coding days ;-)):

1. EXP is fairly expensive, use a pre-calculated lookup table, this translates to an extent:
2. self modifying code is good - this translates to remove intermediate variables
3. XOR is true when bit 1 <> bit 2 - no need to do all the dancing around handling all combinations - your signature may need an update ;-)
4. loops are bad and should be unrolled - this translates to shift once instead of in loops

Code:
   DEFINE VARIABLE iexp AS INT EXTENT 16 INITIAL [ 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768 ].

   METHOD PRIVATE INTEGER RightShift(
      i_ivalue AS INTEGER,
      i_ishift AS INTEGER
   ):

      RETURN INTEGER( TRUNCATE( i_ivalue / iexp[ i_ishift + 1], 0 ) ).

   END METHOD.


   METHOD PRIVATE INTEGER BinaryAND (
      i_ivalue_1 AS INTEGER,
      i_ivalue_2 AS INTEGER
   ): 
       DEFINE VARIABLE icbit     AS INTEGER     NO-UNDO.
       DEFINE VARIABLE iresult   AS INTEGER     NO-UNDO.

       DO icbit = 1 TO 16:
          IF LOGICAL( GET-BITS( i_ivalue_1, icbit, 1 ) ) AND
             LOGICAL( GET-BITS( i_ivalue_2, icbit, 1 ) )
          THEN
             PUT-BITS( iresult, icbit, 1 ) = 1.
      END.

      RETURN iresult.

   END METHOD. /* End of METHOD BinaryAND */

   METHOD PRIVATE INTEGER BinaryXOR (
      i_ivalue_1  AS INTEGER,
      i_ivalue_2  AS INTEGER
   ):

      DEFINE VARIABLE icbit    AS INTEGER NO-UNDO.
      DEFINE VARIABLE iresult  AS INTEGER NO-UNDO.
  
      DO icbit = 1 TO 16:
         IF LOGICAL( GET-BITS( i_ivalue_1, icbit, 1 ) ) <>
            LOGICAL( GET-BITS( i_ivalue_2, icbit, 1 ) )
         THEN
             PUT-BITS( iresult, icbit, 1 ) = 1.
      END.

      RETURN iresult.

   END METHOD. /*End of METHOD BinaryXOR */

I initially used iexp when replacing the EXPs, but switched to PUT-BITS for its elegance.

Thanks for the update. It's now running faster. Average time is now 71 milliseconds compares to the original 3-4 seconds. I just need to write a Arithmetic RightShift function/method for another project I'm thinking of doing
 

Cecil

19+ years progress programming and still learning.
Improved shiftRight Function after I found a small hiccup due to negative numbers which was causing the function to return the incorrect values.

Code:
FUNCTION shiftRight RETURNS INTEGER (INPUT baseOperand AS INTEGER,
                                     INPUT expOperand  AS INTEGER):

    DEFINE VARIABLE shiftRightDec  AS DECIMAL NO-UNDO.
    DEFINE VARIABLE shiftRightInt  AS INTEGER NO-UNDO.
    DEFINE VARIABLE expArray       AS INTEGER NO-UNDO EXTENT 16 INITIAL [ 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768 ].
  
    shiftRightDec = (baseOperand / expArray[ expOperand + 1]).
  
    /** Need to handle the remainder. NOTE: using 'TRUNCATE' or 'ROUND' WILL NOT WORK!!! **/
    IF shiftRightDec = TRUNCATE( shiftRightDec, 0 ) THEN
        shiftRightInt =  INTEGER( shiftRightDec ).
    ELSE
        shiftRightInt = INTEGER( TRUNCATE( shiftRightDec, 0 ) + (IF shiftRightDec LT 0 THEN -1 ELSE 1) ).

    RETURN shiftRightInt.
END.

Also I need to create shiftRightLogical function and I came up with this as a solution. It's total fugly and I so wish that Progress would implement Bit Wise Manipulation stuff into the ABL. May be you might have a better solution handling 'Logical Right Shifts'.

Code:
FUNCTION shiftRightLogical RETURNS INTEGER (INPUT baseOperand AS INTEGER,
                                            INPUT expOperand  AS INTEGER):

    DEFINE VARIABLE bitLoop                  AS INTEGER  NO-UNDO.
    DEFINE VARIABLE shiftRightLogicalInt    AS INT64    NO-UNDO.
    DEFINE VARIABLE rawInteger              AS RAW      NO-UNDO.
  
    PUT-LONG(rawInteger, 1) = shiftRight(baseOperand, expOperand).
  
    shiftRightLogicalInt = GET-UNSIGNED-LONG(rawInteger,1).
  
    /*** Drop the number's sign bit from the MSB. ***/
    DO bitLoop = 32 TO (32 - (expOperand - 1)) BY -1:
        PUT-BITS(shiftRightLogicalInt, bitLoop, 1) = 0.
    END.

    RETURN shiftRightLogicalInt.
END.

MESSAGE shiftRightLogical( -9,2).
 
Top