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
).
Bitwise NOT (~)The 32-bit signed integer operand is inverted according to two's complement. That is, the presence of the most significant bit is used to express negative integers. Bitwise NOTing any number x yields -(x + 1) . For example, ~-5 yields 4 .
A bit shift is a bitwise operation where the order of several bits is moved, either to the left or right, to efficiently perform a mathematical operation. Bit shifts help with optimization in low-level programming because they require fewer calculations for the CPU than conventional math.
The bitwise-AND operator compares each bit of its first operand to the corresponding bit of its second operand. If both bits are 1, the corresponding result bit is set to 1. Otherwise, the corresponding result bit is set to 0.
Zero bits are shifted in from the left. The sign bit becomes 0 , so the result is always non-negative. Unlike the other bitwise operators, zero-fill right shift returns an unsigned 32-bit integer.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With