Bit Shifting Operators Come to Synergy .NET

By Bob Studer, Senior Systems Software Engineer

Synergy DBL 10.1 on .NET adds two new operators for expressions: right bit shift ( >> ) and left bit shift ( << ). In combination with the other bitwise operators (|, &, etc.), shifting can access parts of fields that can be used to store flag data or to combine and extract small pieces of data. Bit shifts can be applied to Synergy decimal and integer types and some classes. They work by shifting, in bucket brigade fashion, the bits in the value on the left of the operator either to the left or the right by the number of bits specified by the value on the right of the operator. For example:

    data x, i1,       3
    data y, i1
    y = x << 2

In this example the binary value of x is 00000011. Shifting that left by two bits changes the binary value to 00001100, which is 12 decimal. In effect, x was multiplied by 22, or 4. If a 1 bit is shifted into the high bit of a signed field, the value will be negative, and if a 0 is shifted into the high bit, the value will be positive. Any bits shifted out of the high end of the field will be lost; 0 bits are shifted into the low end of the field.

On the other hand, if x is shifted 1 bit to the right, as follows:

    y = x >> 1

y will be set to 1. Thus, 00000011 becomes 00000001, in effect dividing x by 21, or 2. Any bits shifted out of the low end of the field will be lost, and bits that match the sign bit (the high-end bit) will be shifted in from the high end, so a negative value will stay negative, and a positive value will remain positive. This is called a sign-extending right shift.

Bit shifting is limited to integer types (i1, i2, i4, i8, int, short, long, and sbyte), Synergy decimal types (for example, d4), and classes that implement the op_RightShift or op_LeftShift operator methods. Synergy decimal types are first converted into integers before the shift is performed. The following example shows a class that implements the right shift operator:

namespace ns1
class fred
    public method fred
        arg,   int
    proc
        val = arg
    end

  public property val, int
        method get
        endmethod
        method set
        endmethod
    endproperty

    public static method op_RightShift,    @fred
        arg1,   @fred
        arg2,   int
    proc
        arg1.val = arg1.val >> arg2       ;Right shifts the val property
        mreturn arg1
        end

        private myval,        int
endclass
endnamespace

proc
    data h, @fred,  new fred(125)
    h = h >> 3              ;Calls the op_RightShift method
    console.writeline(h.val)
end

In combination with the other bitwise operators, shifting can be used to set and access groups of bits within a single field. These bits can represent groups of flags or small values.

    data combi,   sbyte
    data b1,      sbyte
    data b2,      sbyte
    b1 = 3
    b2 = 6
    console.writeline(b1)
    console.writeline(b2)
    combi = ((b1 & 7) << 3) | (b2 & 7)
    b2 = (combi >> 3) & 7
    b1 = combi & 7
    console.writeline(b1)
    console.writeline(b2)

The above code swaps the values contained in b1 and b2. Swapping values this way demonstrates that you can access the two three-bit “subfields” of the combi field separately. ANDing b1 and b2 with 7 ensures that the incoming values won’t exceed the three bits allocated to the subfields. The value of b1 is shifted to the left 3 bits, and then the value of b2 is ORed into the lower three bits of combi. The next statements then extract the two three-bit fields, storing them in opposite fields to demonstrate that the values have been correctly retrieved.

You can see how bit shifts give you more control over individual bits within integer types. We think you’ll find them extremely useful. See “Bitwise operators” in the Synergy/DE documentation for more information.