|
-
Oct 11th, 2000, 06:16 AM
#1
How can I do bit shifting in VB? Is there any other way than to change value hard way to binary and then do the shifting and after all convert final value to desimal?
-
Oct 11th, 2000, 06:57 AM
#2
Lively Member
Don't think there is any easy way doing that.
Working with bits in VB is hard. Just try to split an integer(WORD) into its High and Low values. &HEFCD -> High=&HEF Low=&HCD.
-
Oct 11th, 2000, 11:04 AM
#3
Addicted Member
Hi !!!
I can't remember where I found the information about left/right shifting in VB (Microsoft or Net ?)
But here is the code:
Private Function Shl(ByVal dw As Long, n As Byte) As Long
Shl = dw * 2 ^ n
End Function
Private Function Shr(dw As Long, n As Byte) As Long
Shr = dw \ 2 ^ n
End Function
hope this help
-
Oct 11th, 2000, 11:19 AM
#4
Lively Member
Here's the standard way to get HI and LO WORD:
Code:
Public Function GetHiWord(dw As Long) As Integer
If dw And &H80000000 Then
GetHiWord = (dw \ &HFFFF) - 1
Else
GetHiWord = dw \ &HFFFF
End If
End Function
Public Function GetLoWord(dw As Long) As Integer
If dw And &H8000 Then
GetLoWord = &H8000 Or (dw And &H7FFF& )
Else
GetLoWord = dw And &HFFF&
End If
End Function
And HI LO BYTE:
Code:
' This is the LOBYTE of the wParam:
LOBYTE = wParam And &HFF&
' This is the HIBYTE of the wParam:
HIBYTE = wParam \ &H100 And &HFF&
You'll need it sooner or later if you use the API much.
C/C++,Delphi, VB6,Java,PB (blech!),ASP,JSP,SQL...bla bla bla and bla
I love deadlines. I like the whooshing sound they make as they fly by.
—Douglas Adams
-
Oct 11th, 2000, 12:19 PM
#5
Frenzied Member
Here is an alternate method with examples for both Integers and Longs.
Code:
Private Declare Sub CopyMemory Lib "KERNEL32" _
Alias "RtlMoveMemory" (hpvDest As Any, _
hpvSource As Any, _
ByVal cbCopy As Long)
Function HiWord(ByVal dw As Long) As Integer
CopyMemory HiWord, ByVal VarPtr(dw) + 2, 2
End Function
Function LoWord(ByVal dw As Long) As Integer
CopyMemory LoWord, dw, 2
End Function
Function HiByte(ByVal w As Integer) As Byte
CopyMemory HiByte, ByVal VarPtr(w) + 1, 1
End Function
Function LoByte(ByVal w As Integer) Byte
CopyMemory LoByte, w, 1
End Function
-
Oct 11th, 2000, 01:26 PM
#6
Frenzied Member
Using this quoted function:
Private Function Shl(ByVal dw As Long, n As Byte) As Long
Shl = dw * 2 ^ n
End Function
wouldn't you have problems with overflows?
Harry.
"From one thing, know ten thousand things."
-
Oct 11th, 2000, 02:04 PM
#7
Any ideas about byte arrays and strings?
-
Oct 11th, 2000, 05:39 PM
#8
Frenzied Member
What do you want to know "about byte arrays and strings"?
This thread has gone from bit shifting to byte swapping to byte arrays and strings. No criticism intended, but perhaps your question should be in a new thread so that the right people see it.
-
Oct 11th, 2000, 10:34 PM
#9
Hyperactive Member
Hmmm..
hitcgar, Do you stand by your suggestion? I seem to make
it overflow quite easily by testing with a value like
123456&.
TheOnly answered the question properly because the question
was about shifting bits left or right.
All the replies that kindly tell MerryVIP how to split
words into integers (the ones that work) are very nice, but
don't really answer the question...
As for my 5 cents worth:
To Split a Word, use the UDT
Code:
Private Type SplitLong
lo As Integer
hi As Integer
End Type
Private Type NormalLong
val As Long
End Type
' in some sub
Dim myLong1 As SplitLong
Dim myLong2 As NormalLong
myLong2.val = 123456&
LSet myLong1 = myLong2
Debug.Print myLong1.hi, myLong1.lo
To bit shift, use TheOnly's code. Yes it will overflow if
you put in a high value for n, however you can either limit
n in the function or assume the user knows what the heck
they're doing. Who would even want to try to bit shift
beyond a word boundary anyhow?
If you don't know what bit shifting is, then here is a clue
If you bit shift the number 3 by 2 bits to the left, you
get 12. If you bit shift 10, by 1 bit to the right, you
get 5. Clear as mud? 
Cheers
-
Oct 12th, 2000, 02:46 AM
#10
Overflows...:(
Okay, where I need the bit shifting is a C/C++ code I've to translate to VB (I've only DJGPP C/C++ compiler which is for DOS and I can't afford MS C++ etc.)
The code calculates ID from a file name, like filename can be README.TXT - I need the ID calculating for my game editor.
Here's the code:
Code:
int Cmix_file::get_id(string name)
{
name = to_upper(name);
int i = 0;
unsigned int id = 0;
int l = name.length();
while (i < l)
{
unsigned int a = 0;
for (int j = 0; j < 4; j++)
{
a >>= 8;
if (i < l)
a += static_cast<unsigned int>(name[i]) << 24;
i++;
}
id = (id << 1 | id >> 31) + a;
}
return id;
}
README.TXT 's ID should be 8882CFF1 in hex
and hmm...README.DOC returns the same so it looks like it
takes only README. But that can't be like that...Or can it?
Well, have to search the things little more.
Thanks for the replies
-
Oct 12th, 2000, 02:50 AM
#11
Fix...
Okay, it changes text to italic when there's "I" between "[" and "]". So there should be name"I".
Hope you got this
-
Oct 12th, 2000, 12:10 PM
#12
OK, maybe I didn't make myself clear enough.
The only solutions for bit shifting given so far, worked on integers and long's. How should I go around when I wanted a bit shift on a block of memory bigger then these, like a string or byte array (or an allocated block of memory created with the GlobalAlloc API, or a bitmap, or whatever)?
If nobody knows the answer, never mind. It was only a hypothetical question.
-
Oct 12th, 2000, 01:28 PM
#13
Hyperactive Member
Even hypothetically
The idea of bit shifting outside of a word boundary is foreign to me. Perhaps my lack of C++ experience is showing through?
When do you ever want to bit shift across a byte array or string? And how do you do this in C++.
My guess is that you need to use a loop to achieve it. Afterall, the << and >> operators in C++ only work on Integers anyhow.
Cheers
-
Oct 13th, 2000, 03:52 PM
#14
Lively Member
Sorry, thanks for the note! That was old VB 3 junk I picked off the web from MSDN a while ago! 
Code:
Public Function LoWord(DWord As Long) As Integer
If DWord And &H8000& Then ' &H8000& = &H00008000
LoWord = DWord Or &HFFFF0000
Else
LoWord = DWord And &HFFFF&
End If
End Function
Public Function HiWord(DWord As Long) As Integer
HiWord = (DWord And &HFFFF0000) \ &H10000
End Function
Public Function MakeDWord(LoWord As Integer, HiWord As Integer) As Long
MakeDWord = (HiWord * &H10000) Or (LoWord And &HFFFF&)
End Function
Hi & Lo word extracting is usally done with bit shifting or bitwise ANDing as you can see from the definitions of the HIWORD, LOWORD macros in C:
Code:
#define LOWORD(l) ((WORD)((DWORD_PTR)(l) & 0xffff))
#define HIWORD(l) ((WORD)((DWORD_PTR)(l) >> 16))
#define LOBYTE(w) ((BYTE)((DWORD_PTR)(w) & 0xff))
#define HIBYTE(w) ((BYTE)((DWORD_PTR)(w) >> 8))
Thanks to the others who posted alternate methods - interesting.
You can use TheOnly's posted code to do the shift right 16 to extract the HIWORD or shift right 8 for the HIBYTE.
Anyway doesn't solve original question.
C/C++,Delphi, VB6,Java,PB (blech!),ASP,JSP,SQL...bla bla bla and bla
I love deadlines. I like the whooshing sound they make as they fly by.
—Douglas Adams
-
Oct 13th, 2000, 04:38 PM
#15
Guru
The very very bestest best ways to use all the bit stuff, no overflows, no errors, no nothing except working code:
Code:
Option Explicit
Function RShift(ByVal lNum As Long, ByVal lBits As Long) As Long
If lBits <= 0 Then RShift = lNum
If (lBits <= 0) Or (lBits > 31) Then Exit Function
RShift = (lNum And (2 ^ (31 - lBits) - 1)) * _
IIf(lBits = 31, &H80000000, 2 ^ lBits) Or _
IIf((lNum And 2 ^ (31 - lBits)) = 2 ^ (31 - lBits), _
&H80000000, 0)
End Function
Function LShift(ByVal lNum As Long, ByVal lBits As Long) As Long
If lBits <= 0 Then LShift = lNum
If (lBits <= 0) Or (lBits > 31) Then Exit Function
If lNum < 0 Then
LShift = (lNum And &H7FFFFFFF) \ (2 ^ lBits) Or 2 ^ (31 - lBits)
Else
LShift = lNum \ (2 ^ lBits)
End If
End Function
Property Get LoWord(dwNum As Long) As Integer
LoWord = dwNum And &HFFFF
End Property
Property Let LoWord(dwNum As Long, ByVal wNewWord As Integer)
dwNum = dwNum And &HFFFF0000 Or wNewWord
End Property
Property Get HiWord(dwNum As Long) As Integer
HiWord = ((dwNum And IIf(dwNum < 0, &H7FFF0000, &HFFFF0000)) \ _
&H10000) Or (-(dwNum < 0) * &H8000)
End Property
Property Let HiWord(dwNum As Long, ByVal wNewWord As Integer)
dwNum = dwNum And &HFFFF& Or IIf(wNewWord < 0, ((wNewWord And &H7FFF) _
* &H10000) Or &H80000000, wNewWord * &H10000)
End Property
Property Get LoByte(wNum As Integer) As Byte
LoByte = wNum And &HFF
End Property
Property Let LoByte(wNum As Integer, ByVal btNewByte As Byte)
wNum = wNum And &HFF00 Or btNewByte
End Property
Property Get HiByte(wNum As Integer) As Byte
HiByte = (wNum And &HFF00&) \ &H100
End Property
Property Let HiByte(wNum As Integer, ByVal btNewByte As Byte)
wNum = wNum And &HFF Or (btNewByte * &H100&)
End Property
Usages:
Code:
Something = RShift(SomeValue, HowManyBits) ' Same with LShift
MyWord = HiWord(MyDWord) ' Get the HiWord (same way with LoWord)
HiWord(MyDWord) = MyWord ' Set the HiWord (same with LoWord)
MyByte = HiByte(MyWord) ' Get the HiByte (same with LoByte)
HiByte(MyWord) = MyByte ' Set the HiByte (same with LoByte)
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|