Software Engineers Handbook/Language Dictionary/PLI/bit strings

Note: This article requires basic knowledge of PL/I which can be found in Software Engineers Handbook/Language Dictionary/PLI.

Bit Strings "as Strings" edit

In PL/I bit strings formally are declared as strings of "1-bit-letters", i.e. all builtin string functions may be used for it,

dcl   my_chars   char (8) varying   init ( 'ABCDCD' );
dcl   my_bits    bit  (8) varying   init ( '01010'B );
   put skip list ( length ( my_chars ) );   /* output is 6, the current length of the varying string */
   put skip list ( length ( my_bits  ) );   /* output is 5, the current length of the varying string */
   put skip list ( index ( my_chars , 'CD'  ) );   /* output is 3, the first position of substring 'CD'  */
   put skip list ( index ( my_bits  , '10'B ) );   /* output is 2, the first position of substring '10'B */

Bit Strings as Boolean Values edit

The common use of bit strings is to employ them as bit vectors, especially bit (1) strings represents single boolean values:

  • '1'B is interpreted as True
  • '0'B is interpreted as False

Bit (1) strings may be used as boolean expressions in conditional and loop statements.

dcl   one_bit   bit (1);
   one_bit = ( 1 < 2 );   /* now one_bit has the value '1'B */
   one_bit = ( 2 < 1 );   /* now one_bit has the value '0'B */
   if one_bit then
      put skip list ( 'value of one_bit is true' );
   else
      put skip list ( 'value of one_bit is false' );
   do while ( one_bit );
      .....
   end;

Bit strings used in an expression expecting a bit (1) value are interpreted as '1'B = True if and only if at least one bit has then value '1'B.

dcl   many_bits   bit (99);
   if many_bits then
      put skip list ( 'at least one of the bits has value 1'B' );
   else
      put skip list ( 'none of the bits has value 1'B' );
   do while ( many_bits );   /* do while at least one bit is set */
      .....
   end;

Fundamental Boolean Operators edit

Boolean operators may be used for calculating new bit (1) values:

  • The prefix operator ¬ is used as logical NOT.
  • The infix operator & is used as logical AND.
  • The infix operator | is used as logical OR.
dcl   bit_a    bit (1);
dcl   bit_b    bit (1);
dcl   result   bit (1);
   result = ¬ bit_a;           /* result = '1'B if and only if bit_a is '0'B */
   result =   bit_a & bit_b;   /* result = '1'B if and only if both bit_a and bit_b are '1'B */
   result =   bit_a | bit_b;   /* result = '0'B if and only if both bit_a and bit_b are '0'B */

Note: Using compile-time options NOT operator and OR operator may be replaced by other symbols,
for being compatible with existing PL/I programs often ^ is used as NOT, ! is used as OR.
Note: In Enterprise PL/I for z/OS ¬ may also by used as an infix operator, A ¬ B means A XOR B (exclusive-or).

Boolean operators may also be used for bit (n) strings with n > 1,
in this case calculation is done in a bit-by-bit way, i.e.

  • 1st bit of ( A & B ) = ( 1st bit of A ) & ( 1st bit of B )
  • 2nd bit of ( A & B ) = ( 2nd bit of A ) & ( 2nd bit of B )
  • and so on ...

If A and B have different length the shorter of them is padded on the right with '0'B.

dcl   bit_a   bit (3)   init ( '101'B  );
dcl   bit_b   bit (4)   init ( '1100'B  );
   put skip list ( ¬ bit_a );         /* '010'B  */
   put skip list ( ¬ bit_b );         /* '0011'B */
   put skip list ( bit_a & bit_b );   /* '1000'B */
   put skip list ( bit_a | bit_b );   /* '1110'B */

Builtin Function BOOL edit

All of the 16 possible binary boolean operations can be done with the BOOL function.

BOOL ( A , B , pattern_4 )

where A and B are bit strings and pattern_4 is a bit (4) string.

Let us as first assume A and B would be bit (1), then the function of pattern_4 is:

  • 1st bit of pattern_4 defines the result of bool if A = '0'B and B = '0'B
  • 2nd bit of pattern_4 defines the result of bool if A = '0'B and B = '1'B
  • 3rd bit of pattern_4 defines the result of bool if A = '1'B and B = '0'B
  • 4th bit of pattern_4 defines the result of bool if A = '1'B and B = '1'B

If A or B is bit (n) with n > 1 then calculation is done in a bit-by-bit way, see above.

Some possible values of pattern_4:

                           alternative      meaning
bool ( A , B , '0001'B )       A  &  B      A AND  B    logical AND
bool ( A , B , '0111'B )       A  |  B      A OR   B    logical OR
bool ( A , B , '0110'B )       A ¬=  B      A XOR  B    exclusive-OR
bool ( A , B , '1110'B )   ¬ ( A  &  B )    A NAND B    NOT AND
bool ( A , B , '1000'B )   ¬ ( A  |  B )    A NOR  B    NOT OR
bool ( A , B , '1001'B )       A  =  B      A IFF  B    equivalence
bool ( A , B , '1101'B )      ¬A  |  B      A  ->  B    implication: if A then B
bool ( A , B , '1011'B )       A  | ¬B      a  <-  B    implication: if B then A

Array Operations edit

The builtin function ALL and ANY expects an array as argument.

Let us as first assume the argument ARRAY would be an array of bit (1), then

  • ALL returns '1'B = True if and only if all elements of ARRAY are '1'B.
  • ANY returns '1'B = True if and only if at least 1 element of ARRAY is '1'B.

If argument ARRAY is an array of bit (n) with n > 1 then calculation is done in a bit-by-bit way, see above.

dcl   array (3)     bit (8)   init ( '11110000'B ,
                                     '11001100'B ,
                                     '10101010'B   );
dcl   number (42)   bin fixed (15);
   put skip list ( ALL ( array ) );   /* output is '10000000'B */
   put skip list ( ANY ( array ) );   /* output is '11111110'B */
   if ANY ( number < 0 ) then         /* expression "number < 0" returns an array of 42 bit (1) strings */
      put skip list ( 'at least 1 number is negative' );