RPG

Numeric Datatypes in RPG.


RPG has multiple numeric datatype support. Other then  TWO most famous ZONED and PACKED numbers there are BINARY , INTEGER and FLOAT.

NOTE: This article contains few examples from FIX-FORMAT RPG to explain few points. Its highly recommended use only FREE FORMAT RPG.

Here is how these Datatypes work

1. ZONED Number (aka SIGNED Number):

      • This is kind of most ancient data type used by IBM.
      • ZONED are also called SIGNED so the data type “S” is used by Fix-Format RPG.#1
      • DS numeric sub-fields are default to ZONED datatype.#1
      • Its a bit memory consuming as each digit in the number takes its own “1 byte/8 bits” of memory.
      • Actually for every digit in a number of more than 1 byte , 4 bits are wasted without any use.(Explain later in this section)
      • ZONED number are always SIGNED and SIGN does not consume extra space
        • ZONENUMBER will use 3 bytes.
        • and can contain values from -999 to 999 (both inclusive)Example
          D ZONENUMBER      s              3S 0     
            dcl-s ZONENUMBER zoned(3:0) ;

         

      • So here is how ZONED number are saved in memory.
        • Each digit takes 8 bits of memory.
        • 1st 4 bits are called “ZONE” and used to save SIGN information.
        • Last 4 bits are called “DIGIT” and used to save digit value.
        • 1 byte ZONED number with value +5 is saved like this
          ZONE DIGIT
          1 1 1 1 0 1 0 1
          Hexadecimal F = positive  5
        • 1 byte ZONED number with value -5 is saved like this
          ZONE DIGIT
          1 1 0 1 0 1 0 1
          Hexadecimal D = negative 5
        • So each digit in number  have space for its own sign but system use only lowest digit’s ZONE value for sign information.
        • 3 byte zoned number (like defined above as ZONENUMBER) with value -345 will be saved like this
          byte 3 byte 2 byte 1
          ZONE DIGIT ZONE DIGIT ZONE DIGIT
          0 0 1 1 0 1 0 0 1 1 0 1 0 1 0 1
          Waste 3 Waste 4 Hex D =negative 5

2. PACKED Number :

    1. In Fix Format RPG datatype “P” represents PACKED number and for a standalone numeric filed  if you dont define a data type it will be default to PACKED number.
    2. Following 2 lines of code are equivalent and declare a 3 length PACKED number
      D PACKNUMBER      s              3P 0
      D PACKNUMBER      s              3  0
        dcl-s PACKNUMBER packed(3:0) ;
    3. It use less memory than ZONED number.
    4. Every digit in the number user half of byte ( means 4 bits).
    5. But in PACKED number SIGN also use half of byte.(Lowest 4 bits)
    6. So PACKNUMBER variable (defined above) with value -345 will use 2 complete bytes like
      byte 2 byte 1
      0 0 1 1 0 1 0 0 0 1 0 1 1 1 0 1
      3 4 5 Hex D =negative
    7. No memory is wasted for ODD length variable. But same is not true for EVEN length PACKED variables.
       dcl-s PACKEDEVEN packed(4:0) ;
    8. In this case  PACKEDEVEN variable will use 3 bytes (2 bytes for digits and 1/2 byte for sign but system can assign only full byte).
    9. So PACKEDEVEN variable  with value 2345 will be saved like
      byte 3 byte 2 byte 1
      0 0 1 0  0 0 1 1 0 1 0 0 0 1 0 1 1 1 1 1
      Waste 2 3 4 5 Hex F =positive
    10. Means for every EVEN length PACKED decimal 4 bits of memory will be wasted.(Much better than ZONED number).

Wait there are more numeric datatypes.

3. binary datatypes:

  • The binary data type is a class of data types in which each bit is represented as power of 2.
  • SIGN is saved in LEFT MOST bit. LEFT MOST bit 1 means NEGATIVE number and 0 means POSITIVE number
  • NEGATIVE numbers are saved as 2’s complement.(More in INTEGER Section )
  • RPG has 2 implementation of binary data type
    • The old one is called BINARY.
    • The new one is INTEGER.

     

    3.1 BINARY :

    • Not recommended to use any more. Mostly replaced INTEGER (more in next section).
    • Only exists for compatibility reasons only and is very inefficient.#1
    • 1 to 4 length BINARY number use 2 bytes
    • 5 to 9 length BINARY number use 4 bytes
    • More than 9 length BINARY number are not allowed.
    • How are the SIGN saved ? Later in INTEGER section.
    • BINARY variable in RPG is defined like this
      D BINNUMBER       s              3B 0
       dcl-s BINNUMBER bindec(3) ;
    • Number 9 will be saved in memory something like this. 9 in decimal = 1001 in binary.
      byte 2 byte 1

      0

      0

      0

      0

      0

      0

      0

      0

      0

      0

      0

      0

      1

      0

      0

      1

      32768 16384 8192 4096 2048 1024 512 256 128 64 32 16 8 4 2 1
      215 214 213 212 211 210 29 28 27 26 25 24 23 22 21 20
    • Technically 2 byte BINARY number is able to save value from -32,768 to 32,767 but not in RPG.
    • RPG implementation of BINARY allow maximum allowed value based in length given for the BINARY variable.
    • Means a 3B 0 BINARY variable can only hold values from -999 to 999 and 4B 0 variable from -9999 to 9999.
    • Lost of memory is wasted so a new and better binary data type INTEGER is introduced

   3.2 INTEGER

  • INTEGER is actual implementation of binary datatype in RPG.
  • When use C APIs (which binary field in their signature) in RPG, you can use this datatype to pass binary field values.
  • Decimal position is always ZERO.
  • Only predefined lengths (As shown in table below) are allowed.
  • Can be SIGNED [datatype “I” ]or UNSIGNED [datatype “U”] .

For SIGNED INTEGER Left MOST bit is saved for SIGN.

SIGNED INTEGER Bytes use Value range Will replace API’s bits used Value range power of 2
3I 0 1 -128 to 127 Binary(1) 8 -2to 27-1
5I 0 2 -32768 to 32767 Binary(2) 16 -215 to 215-1
10I 0 4 -2147483648 to 2147483647 Binary(4) 32 -231 to 231-1
20I 0 8 -9223372036854775808 to
9223372036854775807
Binary(8) 64 -263 to 263-1

Negative number and 2’s complement.

In binary format NEGATIVE number are saved as 2’s complement.

Here is how -5 will be saved in 1 byte (3I 0) variable

  27 26 25 24 23 22 21 20
128 64 32 16 8 4 2 1
510 In binary format 0 0 0 0 0 1 0 1
1’s complement Convert 1s into 0s and 0s into 1s 1 1 1 1 1 0 1 0
2’s complement add 1 1 1 1 1 1 0 1 1

Left most bit as 1 represents a NEGATIVE number so if we convert this binary into decimal again :

-128 + 64 + 32 + 16+8+0+2+1 ==> -128 + 123 ==> -5

For UNSIGNED INTEGER not bit is saved for SIGN so values rages on positive side become around double that of SIGNED INTEGER.

UNSIGNED INTEGER Bytes use Value range Will replace API’s bits used Value range power of 2
3U 0 1 0 to 255 Binary(1) 8 0 to 28
5U 0 2 0 to 65535 Binary(2) 16 0 to 216
10U 0 4 0 to 4294967295 Binary(4) 32 0 to 232
20U 0 8 0 to 18446744073709551 615 Binary(8) 64 0 to 264

 


#1: Thank you Jon Paris for very useful information. More details in Comment section.


IBM i developer.

View Comments

Leave a Reply to Sumit goyal
Cancel Reply