Newsgroup: it.comp.appl.access
Titolo: Confronto bit a bit

Salve a tutti.
Volevo avere chiarimenti circa lo scopo del confronto bit a bit. Mi sono un 
po' informato in internet e ho capito:
1) come trasformare un numero decimale in binario e viceversa.
2) che il confronto bit a bit prende in considerazione ogni singolo bit di 
un operando e lo confronta con il bit che occupa la stessa posizione 
nell'altro operando. Il risultato del confronto sarà determinato 
dall'operatore logico utilizzato tenendo conto che il bit 0 corrisponde a 
False e il bit 1  corrisponde a True.
Supponiamo per esempio di digitare nella finestra immediata in un modulo di 
Access:
Caso AND
? 23 and 200.
00010111
11001000
-----------
00000000
Il risultato è 0 (False) perché, per ogni posizione, i bit corrispondenti 
dei due operandi non sono mai contemporaneamente 1 e 1 (cioè True e True).
oppure
Caso OR
? 13 Or 17:
00001101 (13)
00010001 (17)
--------
00011101 (29)
Il risultato è 29.
Capisco "tecnicamente" cosa succede ma (sarò ottuso) ma non afferro 
esattamente in quale contesto è utile fare questo tipo di confronto. Avete 
esempi pratici?
Grazie a chi vorrà rispondere

 Il risultato è 29.

Infatti non si usa spesso. Io uso una tecnica simile in un db in cui ho
bisogno di parecchi flag del tipo si/no. Invece di crearmi 32 campi di
tipo si/no uso un unico campo di tipo Numerico Long (32 bit) e lavoro
settando e testando i singoli bit con gli operatori logici.
Vantaggi: struttura della tabella più semplice e con meno campi, minore
occupazione di spazio
Svantaggi: gestione dei flag più complicata (va fatta da codice), e
impossibilità di vedere a colpo d'occhio lo stato dei flag aprendo la
tabella
Puoi gestire i bit con un ciclo:
Dim Flags As Long, n As Long
  Flags = 91246580
  For n = 0 To 30
    Debug.Print "Bit " & n & " " & IIf(Flags And 2 ^ n, "Settato (1)",
"Resettato (0)")
  Next
Ciao.
-Marco-
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 -Marco-
Oltretutto è possibile effettuare Filtri con operatori logici anche
direttamente su SQL...!
http://www.alessandrobaraldi.it/DettaglioFaq.asp?IdFAQ=227
-- 
@Alex (Alessandro Baraldi)
---------------------------------------------------------------------------
http://www.sitocomune.com/
http://www.alessandrobaraldi.it
---------------------------------------------------------------------------


Effettivamente nella gestione dei Data Base non è che se ne faccia
grande uso.
Nel codice può tornare utile, a parte il caso noto di usare i singoli
bit per una serie di valori boolean (vero/falso) così in un long ne
salvi 32, ti faccio alcuni esempi così, al volo:
Numero qualsiasi AND 1 = 1 se è dispari, 0 se è pari
Carattere ASCII di una lettera (ad es. 65 per la "A") XOR 32 lo
converte in minuscolo e viceversa:
65 XOR 32 = 97
97 XOR 32 = 62
quindi ASC("A") XOR 32 = ASC("a")
Per ora non me ne vengono in mente altri, ma ce ne sono......
Ciao
Filippo

 Filippo
Ipotesi:
Campo di tipo Testo in qui ogni Char ha un significato logico attribuito ad
un elemento del Record:
VALORE=10010110 ---> 1*2^7+0*2^6+0*2^5+1*2^4+0*2^3+1*2^2+1*2^1+0*2^0=150=H96
Per testare il singolo BIT si usa la mascheratura Binaria quindi:
Test 1° BIT ---> Valore AND 1 [---->00000001]= Valore 1°Bit
Test 2° BIT ---> Valore AND 2 [---->00000010]= Valore 2°Bit
Test 3° BIT ---> Valore AND 4 [---->00000100]= Valore 3°Bit
Test 4° BIT ---> Valore AND 8 [---->00001000]= Valore 4°Bit
ecc.....
Saluti


ecc.....
D'accordissimo, ok, mai messa in dubbio l'utilità del BitMapping anzi,
ai tempi del DOS ne ero un fanatico..... ;) e mi ero scritto queste
funzioni (la sintassi è un po' datata  ma mi sembra comunque chiara):
Function BitTest (InteroLungo as Long, BitNumero as Integer) as
Integer 
'
' BitTest controlla lo stato del bit BitNumero nell'InteroLungo  e
'ritorna 0 o 1, potrebbe essere anche Boolean ma così può tornare
' utile per convertire in formato binario un numero
  BitNumero = BitNumero And 31
  If BitNumero = 31 Then
    N& = -
2147483648
#
  Else
    N& = 2 ^ BitNumero
  End If
  If InteroLungo& And N& Then
    BitTest = 1
  Else
    BitTest = 0
  End If
End Function
Function BitSet(InteroLungo&, BitNumero) as long
'
' BitSet& pone a 1 il Bit BitNumero (da destra) nell'InteroLungo&
' BitNumero va da 0 (il primo a Dx) a 31 (il primo a Sx)
'
  BitNumero = BitNumero And 31
  If BitNumero = 31 Then
    N& = -
2147483648
#
  Else
    N& = 2 ^ BitNumero
  End If
  BitSetL& = InteroLungo& Or N&
End Function
Function BitClear (InteroLungo&, BitNumero) as long
'
' BitClearL pone a 0 il bit BitNumero nell'InteroLungo&
  BitNumero = BitNumero And 31
  If BitNumero = 31 Then
    N& = -
2147483648
#
  Else
    N& = 2 ^ BitNumero
  End If
  BitClear = InteroLungo& And (N& Xor -1)
End Function
Function BitChange (InteroLungo as Long, BitNumero as Integer) as Long
' BitChange cambia il bit BitNumero nel'InteroLungo da 1 a 0 e
'viceversa
  BitNumero = BitNumero And 31
  If BitNumero = 31 Then
    N& = -
2147483648
#
  Else
    N& = 2 ^ BitNumero
  End If
  BitChange = InteroLungo& Xor N&
End Function
Aggiungo, se a qualcuno può interessare, che anziché usare
l'istruzione 2 ^ XYZ conviene usare una funzione ad hoc che è più
veloce dell'operatore di elevamento a potenza.
Qualcosa del tipo:
Function Potenza2(Esponente) as Long
  Static Risultato(0 To 31) As Long
  Dim i As Integer
'La prima volta:
    If Risultato(0) = 0 Then
        Risultato(0) = 1
        For i = 1 To 30
            Risultato(i) = Risultato(i - 1) * 2
        Next i
        Risultato(31) = &H80000000        
    End If
' Le volte successive, direttamente da qui:
 Potenza2 = Risultato(Esponente)
End Function
Ciao
Filippo

 end function
Ci sono funzioni NATIVE come strConv o UCASE/LCASE non hai letto...???
In ogni caso provala per vedere se funziona... a me non restituisce nulla.
Per tutto il resto CONCORDO in qunato è l'uso corretto del metodo.
P.S. per l'elevamento a potenza prova la funzione che sfrutta il Logaritmo,
sapendo che
però hai a disposizione solo Ln... in quanto la funzione LOG in realtà è in
base e magari è più veloce.
;-)


In ogni caso provala per vedere se funziona... a me non restituisce nulla.
strano, forse l'ho digitata male, a me funziona da circa 15 anni, da
quando mi divertivo a scrivere piccole routine in Assembler.
Prova questo test:
DIM i as integer
for i = 65 to 126
	Debug.Print i, chr(i), i OR 32, chr(i OR 32), i AND 95, chr(i
AND 95), i XOR 32, chr(i XOR 32)
next i
e dovresti avere un quadro globale della conversione in minuscolo
(Lcase), maiuscolo (Ucase) e dello scambio (quella che io chiama
SwapCase e che annulla gli effetti del tasto CapsLock).
Ciao
Filippo

 Filippo
E' chiarissimo l'esempio che fai... ed ovviamente funziona, in caso si
voglia
effettuare l'inversione e non il semplice UCASE questo metodo è l'unico.
Non scrivo Assembler da 20 anni... e siccome facevo Automazione industriale
con Z80 non gestivo queste esigenze... ora è tutto più semplice(e meno
efficiente).
;-)
Ciao


Ciao
Che bella chiacchierata.
Ciao e grazie
Filippo

 Filippo
E' un piacere quelle rare volte che si può aprire un tavolo tecnico
approfittarne... ultimamente oltre a MsgBox e Colori sulle TextBox
non esce altro...
Ciao Filippo
