Bit shift when there is no … bit shift operator

bit-manipulationbit-shiftvbscript

I have to implement a checksum (CRC16 CCITT) to verify the content of a file.
The checksum is rather simple to implement in C or Java thanks to << and >> operators and the many examples available on the net.

The thing is… my checksum computation has to be implemented in VBScript.

My experience with this language is nearly null but from my understanding, there isn't anything provided to do bit shifting in VBScript. Therefore I rely on multiplications and divisions by two. It works well except with negative values.

I ran few tests and I believe that VBScript handles its 16 bits integers with two's complement.

Q1: can someone confirm me this (two's complement in VBScript) ? I didn't find any precise information from MSDN website.

Q2: Is it possible to do a bit shift (right and left) with simple mathematical operations when the negative number is coded with two's complement ?

.

Thanks a lot, I'd really like to avoid a kludge like dealing with integers as arrays of '1' and '0' or calling some java / c app from VBScript.

EDIT thank you for the help, find below my implementation of a right shift in VBScript:

Function rightShift(value,bits)
    Dim res

    res = 65535 AND value

    If value>=0 Then
       res = res \ (2^bits)
    Else If value=-1 Then
             res = rightShift(res + 32768, bits - 1)
         Else
             res = rightShift(value \ 2 + 32768, bits - 1)
         End If
    End If

    rightShift = res AND 65535
End Function 

Note about the code above: value was sometimes exceeding the 16 bits therefore I had to mask the unused bits to avoid overflow (AND 65535).

Best Answer

In two's-complement arithmetic, the only impact that negative values have occurs when dividing by 2 to shift right: the intended right shift will take place, but it will also introduce a new 1-bit in the most significant bit (MSB) position to "keep the value negative" -- unless the original value was -1, in which case all bits become 0. So to correct for this, try the following pseudocode:

rightshift(x) {
    if x >= 0 return x / 2;
    if x < -1 return x / 2 - MINVAL;    # Strip out sign bit
    # x must be -1, i.e. "all bits on"
    return x - MINVAL;
}

MINVAL should be the value whose representation consists of just the MSB on and all other bits off, which is -32768 for 16 bits. (So named because it will be the most negative representable number using two's-complement.) Interestingly, adding MINVAL works just as well as subtracting it in the above pseudocode, since in two's-complement arithmetic, x - y = x + NOT(y) + 1, and MINVAL == NOT(MINVAL) + 1.

Left shifts using multiply-by-2 work for negative numbers just as well as they do for positive ones.

Related Topic