Newsgroup: it.comp.lang.visual-basic
Titolo: [?] shift dei bit in VB

Salve vengo dal C e programmo in VB da pochi mesi.
Come si puo ottenere in maniera facile la manipolazione di bit in VB (non
pretendo la facilita del C o dell'assembler). Sono propenso ad usare API e
DLL.
Grazie in anticipo.
Maurizio Tolfa
maur...@tolfa.com

Se non ti servono tutti i bit puoi usare queste bellissime funzioni
shr(x)
{
    x = x \ 2
}
shl(x)
{
    x = x * 2
}
Se vuoi shiftare di + passi puoi usare le potenze di 2...
Non funziona solo se usi tutti i bit compreso il primo (che indica il
segno).
Fabrizio

...

Ma tu sai che differenza c'è tra SHIFT e operazione di prodotto ?
Ad esempio che succede se x non è numerico ? Inoltre........ quello che tu
chiami semplicemente
"primo" bit sarebbe l'MSB o l'LSB ? In ogni caso il fatto che sia il segno
DIPENDE DAL DATA TYPE !
Suggerimento : Non azzardare consigli su funzioni di basso livello.
Stefano

Non so se ti può essere utile!!!!
Occasionally, you need to shift bits. This bit operation doesn't come up
that often in Basic, but when you need to get a certain bit into a certain
position, nothing else will do.
Shifting left 1 bit means multiplying by 2, shifting left 2 bits means
multiplying by 4, and so on. Similarly, shifting right 1 bit means dividing
by 2, and so on. In Basic terms, the operation starts out looking simple:
Function LShiftWord1(w As Integer, c As Integer) As Integer
 LShiftWord1 = w * (2 ^ c)
End
FunctionFunction RShiftWord1(w As Integer, c As Integer) As Integer
RShiftWord1 = w \ (2 ^ c)
End Function
These functions work as long as you feed them positive integers and the
results come out as positive integers. Otherwise, things go wrong. Before we
get to the real version, let's take a look at a C++ version:
// Shift bits of DWord right
DWORD DLLAPI RShiftDWord(DWORD dw, unsigned c)
{   return dw >> c;}
That's it. Even if you're not a C++ programmer, you can probably guess the
code for LShiftDWord, RShiftWord, and LShiftWord. There's still a function
call for shifting. What Visual Basic really needs are Shl and Shr operators
as in most other languages. Then the work would be done automatically
inline. Unfortunately, you have to do the messy job yourself if you're not
willing to add a C++ DLL.
Function LShiftWord(ByVal w As Integer, ByVal c As Integer) As Integer
BugAssert c >= 0 And c <= 15
Dim dw As Long
dw = w * Power2(c)
If dw And &H8000& Then
LShiftWord = CInt(dw And &H7FFF&) Or &H8000    Else
 LShiftWord = dw And &HFFFF&
End If
End Function
Notice that this function uses the Power2 property to look up powers of 2
rather than calculating them. See "Module initialization versus component
initialization" earlier in this chapter.
Since shifting is faster than the equivalent multiplication and
division operations in assembly language, hardcore programmers in other
languages often shift bits to optimize multiplication and division by
multiples of 2. But you can see why the functions I just mentioned are
useless for optimization: it doesn't do any good to fake division by
shifting if your shift function fakes shifting by dividing.
The function works by doing the arithmetic on a temporary Long variable and
then converting the result back to an Integer. But you can't do that for the
LShiftDWord and RShiftDWord functions because there isn't a larger integer
size to cast down from. The functions have to use error trapping to identify
overflow, and they will fail on some input. It's the best I could do, and
rarely will you ever hit the limits.
The Win32 GetLogicalDrives function returns a Long in which the
corresponding bit is set for each existing drive. The easiest way to check
those drives is to loop through all 26 bits, shifting them one at a time
into the rightmost position and then testing them. Here's a function that
translates bits into a more Basic-like string of pluses and minuses:
Function VBGetLogicalDrives() As String
Dim f32 As Long, i As Integer, s As String
 f32 = GetLogicalDrives()
For i = 0 To 25
 s = s & IIf(f32 And 1, "+", "-")
 f32 = RShiftDWord(f32, 1)
 Next
VBGetLogicalDrives = s
End Function
The CDrives class described in Chapter 4 has a more realistic example of
RShift­DWord and GetLogicalDrives.