shift operator anomaly/ambiguity when it comes to bytes?

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
 
J

Jezebal

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
 
M

Markus Hahn

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
 
J

Jay B. Harlow [MVP - Outlook]

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
 
M

Markus Hahn

Ah, now it makes sense. Thanks!
Although this masking thing is still confusing IMHO.

-markus
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top