Shift Bits of Unsigned Int

M

Marty McFly

Hello VB Gurus,

I have an unusual requirement to shift an unsigned int right one bit:

Dim myVar As UInt32 = UInt32.Parse("123456")
Dim myResult As UInt32
myResult = myVar >> 1

However, the >> operator only works on Byte, Short, Integer, and Long.

I also tried to convert to binary and manually shift the bits, but I only
found ways to go from binary to string--not back to binary.

Does anyone know how this could be done? (I'm not too concerned about
performance, so even resource-killing string manipulation would be fine with
me.)

Thank you,

Marty
 
C

Cablewizard

Marty,

Well, there are a few things you can do.
First, do you "really" need the resulting internal value to be a UInt32?
Since UInt's are not CLS compliant, and currently are not supported in VB, I
urge you to not use them.
Could an Int32 or Int64 work?

In this particular example, since you are shifting by one bit to the right, your
maximum possible value would by nature end up being that of a Signed Int32 I
believe.
In this case, you could do the following:

Dim myVar As Int64 = Int64.Parse("123456")
Dim myResult As Int32

myResult = CInt(myVar >> 1)

With that said, I realize that maybe you do "need" for it to remain as a UInt32.
IMHO, the fastest and easiest way to deal with this until VB 2005, would be to
write a very small function in a C# DLL and add a reference to that in your VB
project. However, keep in mind that passing UInt's between assemblies is not
recommended due to the non-CLS compliance. Sure it works, just not recommended.

Possibly the "better" easy way would be to just cast everything to Int64
internally, and then back to UInt32 to store values back out, if this is
required.

Although making a general recommendation that would work for you overall
implementation would require me to know more about what you really need to
achieve.

Gerald
 
D

David Browne

Marty McFly said:
Hello VB Gurus,

I have an unusual requirement to shift an unsigned int right one bit:

Dim myVar As UInt32 = UInt32.Parse("123456")
Dim myResult As UInt32
myResult = myVar >> 1

However, the >> operator only works on Byte, Short, Integer, and Long.

I also tried to convert to binary and manually shift the bits, but I only
found ways to go from binary to string--not back to binary.

Does anyone know how this could be done? (I'm not too concerned about
performance, so even resource-killing string manipulation would be fine with
me.)

The BitConverter can "convert" from signed to unsigned integers.

Function RightShiftOneBit(ByVal u As UInt32) As UInt32
Dim s As Int32 = BitConverter.ToInt32(BitConverter.GetBytes(u), 0)
Return BitConverter.ToUInt32(BitConverter.GetBytes(s >> 1), 0)
End Function

David
 
D

David Browne

David Browne said:
The BitConverter can "convert" from signed to unsigned integers.

Function RightShiftOneBit(ByVal u As UInt32) As UInt32
Dim s As Int32 = BitConverter.ToInt32(BitConverter.GetBytes(u), 0)
Return BitConverter.ToUInt32(BitConverter.GetBytes(s >> 1), 0)
End Function

Oops, that screws up if the sign bit is set since >> shifts in another sign
bit.

This works, though

Function RightShiftOneBit(ByVal u As UInt32) As UInt32
Dim b(8) As Byte
Array.Copy(BitConverter.GetBytes(u), b, 4)
Dim s As Int64 = BitConverter.ToInt64(b, 0)
Return BitConverter.ToUInt32(BitConverter.GetBytes(s >> 1), 0)
End Function


David
 
C

Cablewizard

David Browne said:
The BitConverter can "convert" from signed to unsigned integers.

Function RightShiftOneBit(ByVal u As UInt32) As UInt32
Dim s As Int32 = BitConverter.ToInt32(BitConverter.GetBytes(u), 0)
Return BitConverter.ToUInt32(BitConverter.GetBytes(s >> 1), 0)
End Function

David

There is an issue with the above if the high bit of the UInt32 is set, which
being a UInt, this could be likely.
If you perform the conversion as listed, things can get out of whack.
For example, let's say the initial UInt value is &h FFFF FFFF (d 4,294,967,295)
If you bit shift that 1 right, you get &h 7FFF FFFF (d 2,147,483,647)

In your sub, due to two's complement confusion, would return &h FFFF FFFF

Although this sub should work just fine for everything else between 0 and +7FFF
FFFF

Gerald
 
C

Cablewizard

Oops, that screws up if the sign bit is set since >> shifts in another sign
bit.

This works, though

Function RightShiftOneBit(ByVal u As UInt32) As UInt32
Dim b(8) As Byte
Array.Copy(BitConverter.GetBytes(u), b, 4)
Dim s As Int64 = BitConverter.ToInt64(b, 0)
Return BitConverter.ToUInt32(BitConverter.GetBytes(s >> 1), 0)
End Function


David

Heh, you caught it before I could get my Outlook to send.
How about this:

Function RightShiftOneBit(ByVal u As UInt32) As UInt32
Dim tmp As Int64 = Convert.ToInt64(u)
Return (Convert.ToUInt32(tmp >> 1))
End Function

:)
Gerald
 
G

Guest

Just learning how to handle the shift operators and don't quite understand what you mean by "shifts in another sign bit". I use the >> and << operators on Postiive integers but never realized that shifting another negative integer results in the highest bit being reset to one..is this what heppans?
 
D

David Browne

Dennis said:
Just learning how to handle the shift operators and don't quite understand
what you mean by "shifts in another sign bit". I use the >> and <<
operators on Postiive integers but never realized that shifting another
negative integer results in the highest bit being reset to one..is this what
heppans?
Try evaluating -1 >> 1. If a 0 were shifted into the high bit, then the
result would be a large positive integer (2^31 -1). If a 1 is shifted in
the result would be -1.

In fact the result is -1.

David
 

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