shift operator anomaly/ambiguity when it comes to bytes?

  • Thread starter Thread starter Markus Hahn
  • Start date Start date
M

Markus Hahn

While coding some binary data handling I found this IMHO strange behavior:

Dim bToShift As Byte = 1
bToShift <<= 9
Console.WriteLine("and the value is {0}", bToShift)

The output is "2", I expected it to be zero (outshifted bits don't come back).
The rule I determined is: whatever the shift operator S is, its real value is (S mod 8).

Is this as designed? I read the VB lanuage specification, but I cannot find anything there which would explain it. Looking at the IL
code confirms the shift value.

The real world problem I experienced wassomething like

Dim b as Byte()
Dim nReg as Integer
...
nReg = (b(0) << 24) or ((b1 and &hFF) << 16)

with (b(0) << 24) not chaging anything(!) The following solution

nReg = (CType(b(0), Integer)) << 24 or ((b1 and &hFF) << 16)

solved the problem. What's confusing is that the AND operator apparently enforces a Byte2Integer conversion automatically

Does anybody have similar experiences/solutions/explanations?

-markus
 
Nothing in the VB spec about this? Well, that's a surprise!




Markus Hahn said:
While coding some binary data handling I found this IMHO strange behavior:

Dim bToShift As Byte = 1
bToShift <<= 9
Console.WriteLine("and the value is {0}", bToShift)

The output is "2", I expected it to be zero (outshifted bits don't come back).
The rule I determined is: whatever the shift operator S is, its real value is (S mod 8).

Is this as designed? I read the VB lanuage specification, but I cannot
find anything there which would explain it. Looking at the IL
code confirms the shift value.

The real world problem I experienced wassomething like

Dim b as Byte()
Dim nReg as Integer
...
nReg = (b(0) << 24) or ((b1 and &hFF) << 16)

with (b(0) << 24) not chaging anything(!) The following solution

nReg = (CType(b(0), Integer)) << 24 or ((b1 and &hFF) << 16)

solved the problem. What's confusing is that the AND operator apparently
enforces a Byte2Integer conversion automatically
 
The specification is not so bad, but just by looking at some IL code it could definitely provide more details. Well, I guess binary
data handling is not something VB.NET was majorly intended for :)

-markus
 
Markus,
MSDN clearly states "Arithmetic shifts are not circular, which means the
bits shifted off one end of the result are not reintroduced at the other
end". Which appears contrary to what you are saying ;-).

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vblr7/html/vaoprArithLeftShift.asp

However! here's the kicker (later on the same page) "To prevent shifting by
more bits then the result can hold, Visual Basic masks the value of amount
with a size mask corresponding to the data type of pattern"

Section "11.18 Shift Operators" states something similar "If the value of
the second operand is greater then the number of bits in the first operand,
or is negative, then the shift amount is computes as RightOperand And
SizeMask where SizeMask is"

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbls7/html/vblrfVBSpec11_11.asp
Is this as designed? I read the VB lanuage specification...
Documented and by design!

Hope this helps
Jay

Markus Hahn said:
While coding some binary data handling I found this IMHO strange behavior:

Dim bToShift As Byte = 1
bToShift <<= 9
Console.WriteLine("and the value is {0}", bToShift)

The output is "2", I expected it to be zero (outshifted bits don't come back).
The rule I determined is: whatever the shift operator S is, its real value is (S mod 8).

Is this as designed? I read the VB lanuage specification, but I cannot
find anything there which would explain it. Looking at the IL
code confirms the shift value.

The real world problem I experienced wassomething like

Dim b as Byte()
Dim nReg as Integer
...
nReg = (b(0) << 24) or ((b1 and &hFF) << 16)

with (b(0) << 24) not chaging anything(!) The following solution

nReg = (CType(b(0), Integer)) << 24 or ((b1 and &hFF) << 16)

solved the problem. What's confusing is that the AND operator apparently
enforces a Byte2Integer conversion automatically
 
Ah, now it makes sense. Thanks!
Although this masking thing is still confusing IMHO.

-markus
 
Back
Top