1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Answered Variablelengthencoding Function Not Working

Discussion in 'Development' started by Cecil, Aug 1, 2017.

  1. Cecil

    Cecil 17+ years progress programming and still learning.

    I writing a Variable Length Encoding function based on some Java code. it looks quite simple but I get different results.

    Here is the original Java Code:
    Code (progress):
    1. public class VariableLengthEncoding {
    2.    
    3.     public static Vector encodeValue(int value) {
    4.         Vector<Integer> digits = new Vector();
    5.  
    6.         do {
    7.             int digit = value % 128;
    8.             value = value / 128;
    9.             // if there are more digits to encode, set the top bit of this digit
    10.             if ( value > 0 ) {
    11.               digit = digit | 0x80;
    12.             }
    13.            
    14.             digits.add(digit);
    15.         }
    16.         while ( value > 0 );
    17.        
    18.         return digits;
    19.     }
    20. }
    Here is my ABL code equivalent:

    Code (progress):
    1. FUNCTION bitWiseOR RETURNS INTEGER (INPUT X AS INTEGER, INPUT Y AS INTEGER):
    2.    DEFINE VARIABLE b1 AS INTEGER NO-UNDO.
    3.    DEFINE VARIABLE b2 AS INTEGER NO-UNDO.
    4.    DEFINE VARIABLE n  AS INTEGER NO-UNDO.
    5.    DEFINE VARIABLE Z  AS INTEGER NO-UNDO.
    6.  
    7.    DO n = 1 TO 32:
    8.      ASSIGN
    9.        b1 = GET-BITS(X, n, 1)
    10.        b2 = GET-BITS(Y, n, 1)
    11.        .
    12.        IF b1 = 1 OR b2 = 1 THEN PUT-BITS(Z, n, 1) = 1.
    13.    END.
    14.  
    15.    RETURN Z.
    16. END FUNCTION.
    17.  
    18. function variableLengthEncoding returns character(input x as integer):
    19.  
    20.     define variable encodeByte     as integer   no-undo.
    21.     define variable encodeBytes    as character no-undo.
    22.     define variable encodeByteRaw as raw       no-undo.
    23.  
    24.     do while x > 0:
    25.        
    26.         encodeByte = x mod 128.
    27.        
    28.         x = x / 128.
    29.        
    30.         /** if there are more digits to encode, set the top bit of this digit **/
    31.         if (x > 0) then
    32.             put-byte(encodeByteRaw, 1) = bitWiseOR(input encodeByte, input 0x80).
    33.  
    34.         encodeBytes = encodeBytes + ",0x" + caps(hex-encode(encodeByteRaw)).
    35.        
    36.     end.
    37.    
    38.     encodeBytes = left-trim(encodeBytes , ',').
    39.    
    40.     return encodeBytes.
    41. end.  
    42.  
    43. message VariableLengthEncoding (INPUT 268435455).
    When encoding 268435455 it should return "0xFF, 0xFF, 0xFF, 0x7F" but it return "0xFF,0x80,0x80,0x80,0x00" why would that be?
     
    Last edited: Aug 1, 2017
  2.  
  3. Cecil

    Cecil 17+ years progress programming and still learning.

    I think the problem might be with "x = x / 128." where the value of the expression is being rounded to fit into a integer. However I not positive that I know how to fix this.

    I was hoping "x = truncate(x / 128, 0)." would fix it, but nooo. Doh!
     
    Last edited: Aug 1, 2017
  4. Cecil

    Cecil 17+ years progress programming and still learning.

    I belive I've found the solution:

    Code (progress):
    1. FUNCTION bitWiseOR RETURNS INTEGER (INPUT X AS INTEGER, INPUT Y AS INTEGER):
    2.    DEFINE VARIABLE b1 AS INTEGER NO-UNDO.
    3.    DEFINE VARIABLE b2 AS INTEGER NO-UNDO.
    4.    DEFINE VARIABLE n  AS INTEGER NO-UNDO.
    5.    DEFINE VARIABLE Z  AS INTEGER NO-UNDO.
    6.  
    7.    DO n = 1 TO 32:
    8.      ASSIGN
    9.        b1 = GET-BITS(X, n, 1)
    10.        b2 = GET-BITS(Y, n, 1)
    11.        .
    12.        IF b1 = 1 OR b2 = 1 THEN PUT-BITS(Z, n, 1) = 1.
    13.    END.
    14.  
    15.    RETURN Z.
    16. END FUNCTION.
    17.  
    18. DEFINE VARIABLE iexp AS INT EXTENT 16 INITIAL [ 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768 ].
    19.  
    20. FUNCTION RightShift returns INTEGER ( i_ivalue AS INTEGER, i_ishift AS INTEGER ):
    21.  
    22.     RETURN INTEGER( TRUNCATE( i_ivalue / iexp[ i_ishift + 1], 0 ) ).
    23.  
    24. END function.
    25.  
    26. function variableLengthEncoding returns character(input x as integer   ):
    27.  
    28.     define variable encodeByte     as integer   no-undo.
    29.     define variable encodeBytes    as character no-undo.
    30.     define variable encodeByteRaw as raw       no-undo.
    31.    
    32.     do while x > 127 :
    33.        
    34.         put-byte(encodeByteRaw, 1) = bitWiseOR(input x, input 0x80).
    35.  
    36.         encodeBytes = encodeBytes + ",0x" + caps(hex-encode(encodeByteRaw)).
    37.        
    38.         x = RightShift(x,7).
    39.        
    40.     end.
    41.    
    42.     put-byte(encodeByteRaw, 1) = x.
    43.  
    44.     encodeBytes = encodeBytes + ",0x" + caps(hex-encode(encodeByteRaw)).
    45.  
    46.     encodeBytes = left-trim(encodeBytes , ',').
    47.    
    48.     return encodeBytes.
    49. end.  
    50.  
    51. message VariableLengthEncoding (INPUT 0).
    52. message VariableLengthEncoding (INPUT 127).
    53. message VariableLengthEncoding (INPUT 128).
    54. message VariableLengthEncoding (INPUT 16383).
    55. message VariableLengthEncoding (INPUT 2097151).
    56. message VariableLengthEncoding (INPUT 2097152).
    57. message VariableLengthEncoding (INPUT 268435455).
     
  5. Cringer

    Cringer ProgressTalk.com Moderator Staff Member

    Truncate only works on decimal values.

    Code (progress):
    1.  
    2. define variable x as integer     no-undo.
    3. define variable y as decimal     no-undo.
    4.  
    5. assign
    6.     x = 127
    7.     y = 127.
    8.  
    9. assign
    10.     x = x / 128
    11.     y = y / 128.
    12.  
    13. message x truncate(y,0)
    14.     view-as alert-box info buttons ok.
    15.  
    So if you do your work in a decimal field which you always truncate to 0, and then int() the value before you use it, then you should be good to go.
     
  6. TomBascom

    TomBascom Curmudgeon

    Divide by 128.0

    That should result in your truncate() behaving.
     
  7. Cecil

    Cecil 17+ years progress programming and still learning.

    In the the end I looked for other sample code and I changed the code to not use the dividing method, but to change to a bit shift.
     
  8. Cecil

    Cecil 17+ years progress programming and still learning.

    I should of said that I was tinkering with the code and i changed the 'x' variable to a decimal so I could use TRUNCATE function.
     

Share This Page