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.