Newsgroup: it.comp.lang.visual-basic
Titolo: [RICHIESTA] ... Lavorare sui singoli bit

Oggi sono in vena di domande forse stupide :D ma che a me servono ;)
Avrei la necessità di lavorare sui singoli bit, cioè ho un byte composto 
da 01010101 e dovrebbe diventare 001001110001 secondo alcune regole.
Avete qualche link da cui posso iniziare a studiare come poter lavorare 
con vb.
In questo momento faccio in questo modo:
- Ho il byte e lo trasformo in una stringa di bit quindi ho la mia 
"01010101"
- Lavoro su questa stringa ricavandone che diventa "001001110001"
- Divido la stringa ottenuta in 8 bit e ritrasformo il tutto in byte per 
il salvataggio.
Visto che è un processo lento e labororioso qualcuno saprebbe come fare, 
o qualche api, o qualche suggerimento?
Grazie!!!
--
[CapoBecchino]

 Avrei la necessità di lavorare sui singoli bit
and, or, xor
Sergio.lokarstyle
-- 
Salutoni
Sergio
Per rispondere... togli il group dall'indirizzo
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 
Grazie
ps. io aggiungerei lokarstyle.lapidario :) che nel mio caso ci sta anche 
bene ;)
--
[CapoBecchino]

 agire di conseguenza.
Non facciamo confusione, please. La trasformazione in stringa dei bit è un
tuo personalissimo trip, che ti inviterei ad abbandonare :-)
Se hai un byte, e vuoi sapere se il bit 3 è "alto", supponendo che i bit
si contino a partire da destra e da zero non devi far altro che scrivere
if MioByte and 8 then
   'fai quello che devi
end if


 end if
Cioč fammi capire nel tuo esempio hai scritto and 8 perchč?
Esempio:
ho il mio byte "00001010" che in decimale equivale a 10 e vorrei testare 
il bit 4 ed il bit 6 se sono impostati ad 1 tu come scriveresti?
e questo che non riesco a capire :(

 e questo che non riesco a capire :(
Aritmetica binaria... ogni bit del byte ha un "peso" che è pari a 2 elevato
all'indice della cifra (che normalmente si numera da destra verso sinistra,
partendo da zero).
Pertanto se il bit di indice i è settato si avrà che Byte And (2 ^ i) <> 0.
Finché lavori con variabili Byte, nessun problema, ma attenzione ai bit di segno
con le variabili Integer e Long...
Bye
Raf

 e questo che non riesco a capire :(
Ti devi creare una maschera di bit. In pratica ti crei un byte dove è alto 
solo il bit che vuoi controllare.
Se ad esempio vuoi controllare il 3° bit, come da primo esempio, ti crei un 
byte cosi': 00001000 che in decimale...toh...vale 8.
se vuoi controllare il 6° bi, ti crei un byte cosi: 01000000 che vale in dec 
64
Facendo l'and col byte che vuoi controllare, se è 0 vuol dire che 
l'espressione è falsa, e quindi capisci come si comporta l'if.(non entra 
dentro)
Se vuoi controllare piu' bit contemporaneamente (il 4 ed il 6) ti crei il 
byte cosi': 01010000. Occhio pero', qui il risultato è diverso da 0 se 
ENTRAMBI i bit sono a uno!
Ciao
Umbe 

 e questo che non riesco a capire :(
forse voleva dire 4 e non otto
otto è la rappresentazione decimalre di 1000 in binario
quando fai un and tra due numeri si fa un and bit a bit , il numero otto 
ha un solo bit a 0 il 4° quindi otterrai un numero diverso da zero solo 
se anche il 4° bit del tuo numero è diverso da zero.
per il 4° e il 6° bit  basta che fai and con 10 se vuoi entrambe a 1
oppure con 2 e con 8

>> ed agire di conseguenza.
cmq č meglio se studi un po' di logica binaria.. č una materia poco 
intuitivi ai primi approcci

 Raf
--
[CapoBecchino]

 e questo che non riesco a capire :(
la AND fa l'AND logico BIT PER BIT dei due operandi.
tornando al tuo esempio:
test bit 4
00001010 AND  ---> 10 dec.
00010000  =   ---> bit 4 = 2^4=16 dec. ( nota che il bit piů a dx č 0)
-----------
00000000      ---> risultato =0
mentre, se vuoi testare il bit 3 :
00001010 AND
00001000  =
00001000   --->8 dec.
ciao, roby

 [CapoBecchino]
semplice, usi un integer al posto di un byte
occhio però al bit 15.... :)
ciao, roby

Il giorno Thu, 07 Jul 2005 17:04:17 +0200, "[CapoBecchino]"
<capoNOb...@hotSPAMmail.com> ha scritto:

Nella memoria del computer i dati sono sempre in binario (o esadecimale che in
fondo č lo stesso), quindi se consideri che in un byte ci sono otto bits per
testarli uno alla volta puoi semplicemente fare cosě:
Mask=1
For i=1 to 8
 a = Mybyte AND Mask 
 if a then debug.print "bit" & I & "a 1"
 Mask=Mask+Mask
Next
Se devi settare un bit farai l' OR tra i due bytes
Mybyte=Mybyte AND Mask 
Comunque lavorando sui bits io mi trovo meglio considerando i valori esadecimali
(da &h00 a &hFF per intenderci) che rendono le operazioni piů immediate
ciao
  Stefano

 lungo per questo usavo le stringhe. :(
Funzioncina generica scritta da Luca Dormio( e DarkByte) giusto un anno fa e 
rintracciabile con Google
copiata pari pari....
dim I as integer
If (I AND 2 ^ (<bit da controllare> - 1)) <> 0 Then
end if
Ciao Umbe 

 ciao, roby

che poi è la tua raccomandazione di stare attento anche al bit 15 ;) ma 
purtroppo non sono riuscito a cogliere il senso. Scusa :(
--
[CapoBecchino]

 il bit 31 mi da errore di overflow. Perchč?
perche' long e pari a quattro bytes ed  in quattro bytes ci stanno 32
bits (da bit 0 a bit 31)
cmq parlare di dato numerico e' fuorviante. Puoi tranquillamente usare
le stringhe
A (a maiuscolo) e' b01000001 (hex 41; dec 65 nella convenzione ASCII)
se non vado errato c'e' la funzione chr(carattereascii) che ti rende il
numero decimale (cioe' 65) e quello che a te interessa e' trattare il 
byte.  Qualsiasi funzione che tratti valori numerici da
0 a 255 (o meglio i valori 2alla0 --> 2alla7) e' buona per rilevare lo 
stato dei bits
p.s. anche la storia del bit di segno e' fuorviante (il 15' nel caso
degli integer il 31' nel caso dei long, e' il primo bit di sx).
Il fatto che quel bit sia ad uno, e quindi in  un numerico "segnato"
denoterebbe un negativo, ai tuoi fini non e' pertinente se sta a 1
sta a 1 punto.
--
a.cara

 [CapoBecchino]
Gestisci il tutto come un array di byte, cosě eviti anche i problemi
di overflow (e magari dato che ci sei evita di fargli calcolare ogni
volta tutti i valori di 2^...)
Andrea Fontana
www.e-nuts.net
 

 fare, o qualche api, o qualche suggerimento?
allora, fai un po di ordine mentale :
Rappresenta un numero come sequenza di 0 e 1 solo nella tua mente... per il 
resto usa quel che ti pare : Long, Integer, Stringa...
per esempio io userei dei numeri esadecimali quindi :
HEX = INT = BIN
0 = 0  = 0
1 = 1  = 1
...
9 = 9 = 1001
A = 10 = 1010
....
F = 15 = 1111
quindi usa numeri esadecimali e immaginali come binari.
Ora gli operatori AND e OR e derivati ti pemettono di fare qualsiasi 
confronto. Ci sono delle tabelle in giro con i risultati di tutti gli 
operatori binari, credo sia anche su msdn.
in pratica AND restituisce 1 se il confronto e' uguale 0 Se uno dei due e' 
diverso
1 and 1 = 1
1 and 0 = 0
0 and 1 = 0
0 and 0 = 1
quindi tu se "ANDY" un numero con 1 ti restituira' 1 solo quando anche il 
numero sara' 1 quindi  rielaborando l'esempio di CSSoft:
function TestaByte(ValoreDaTestare as long, Indice as integer) as integer
'io ho usato gli integer per non complicarti le idee con i boolean
'e la funzione e' assolutamente ottimizzabile
' un minimo di controllo errore
if (indice <= 0) or (indice >= 32) then
    'errore, indice non compreso nell'intervallo dei 32bit del long
     ....
endif
dim PesoDaControllare as long
PesoDaControllare = 2 ^ indice - 1 'due elevato alla potenza di "indice"
' questo passaggio (inutile) serve per farti capire che tu vuoi controllare 
in :
' AA& (numero in esadecimale)(10101010 nella tua mente)
' diciamo il 4° bit , ora il 4° bit e' uguale a : 2 elevato alla 3° (base 0) 
cioe 8&  (1000 bin nella tua mente)
'poi non ti resta che fare :
TestaByte = valoredatestare AND Pesodacontrollare
' quindi tu stai facendo :
' 10101010 AND 1000
'ovvero
' 10101010 AND
' 00001000
' ora dalla tabella di sopra sai che il 4° bit del numero di sopra e' 1, 
quello di sotto e' 1 e quindi la funzione ti da 1.
end sub
Spero che questa funzione ti aiuti a capire un po la dinamica binaria.
-- 
[Gigio2k]
http://www.g2kweb.it
[ it-alt.comp.hardware.modding ] - 
http://www.g2kweb.it/ichm
 

 sta a 1 punto.
Ecco, anche questa me la devi spiegare...
Non considerare il segno quando si lavora con variabili signed è proprio la
causa dell'errore di overflow.
Se per testare il bit 31 uso la condizione espressa da:
    (lngVar And 2 ^ 31) <> 0
questa dà errore, in quanto 2^31 >  
2147483647
 che è il max intero positivo
rappresentabile da un long (signed).
Il bit 31 in un Long è il segno e non si testa così, ma semplicemente:
    (lngVar And &H80000000) <> 0
ossia
    (lngVar And - 
2147483648
)
o banalmente
    (lngVar < 0)
Con la speranza di essere stato chiaro o per lo meno di non aver aggiunto
ulteriore confusione...
Bye
Raf

 ulteriore confusione...
Questa cosa e' "solare". Si e' pero' su una china perigliosa. Cio' che 
fa il linguagio(mappa) non si deve confondere con quello che e' invece
la realta (territorio). La realta e' che ad un indirizzo "ABCDEF00"
esiste un byte che sta ad esempio a "F0" (ovviamente ho usato la 
notazione esadecimale) ora se lo strumento che usi, in questo caso,
non ti consente di dire "per favore dammi il byte a questo indirizzo"
e' ben altra questione. E' chiaro che se gli dici "per favore mi fai una 
addizione su questa variabile che e' di tipo lungo e che non so dove sta 
pero' ti do il nome" il sistema ti possa rispondere "bada ti avviso, nun 
se po fa', perche' il nuovo numero nun c'entra e siccome io sona una 
unita' logica mi corre obbligo di impedirti di fare siffatte puttanate".
E' ovvio che essendo questo il luogo deputato a discutere di VB ritorno 
a dire che il tuo ultimo esempio e' "solare"
E infine cosa sarebbe il mondo senza confusione, neanche il barlume 
dell'ombra di una idea.
--
a.cara

[CapoBecchino] ha scritto:

Mi rendo conto dopo aver riletto il mio post di aver chiesto una cosa 
totalmente stupida per quello che mi serve e chiedo venia ma ero super 
stanco.
Ringrazio tutti coloro che mi hanno risposto siete stati gentilissimi :)
Provo a ripostare quello che realmente mi serve (oggi sono meno stanco ;) )
Allora io ho un qualcosa di questo tipo:
ho una stringa di bit "01010101 01010101 01" (lunga 18 bit) quindi non 
rappresentabile con soli 2 byte e non rapprensetabile con 3 byte in 
quanto per alcune operazioni che devo effettuare devo per forza di cose 
controllare tutti i miei 18 bit.
Avevo pensato di aggiungere un padding ma non va bene in quanto come gia 
specificato effettuando i miei calcoli devo per forza di cose averla in 
questo modo.
Ora ho un buffer di 3 byte quindi scorrendo la mia stringa iniziare io 
se incontro uno 0 scrivo uno 1 nel buffer e se incontro un 1 scrivo uno 
0 (questo è un esempio banale non è cosi che funziona, volevo solo far 
capire che leggendo un bit devo effettuare delle operazioni particolari 
che non si limitano alle semplici AND OR XOR che tra l'altro conosco :P ).
Dopo aver completato il mio buffer aggiungo finalmente il mio padding 
finale.
Esempio pratico:
stringa iniziale: 010101010101010101
buffer (prima del padding) elaborato: 101010101010101010
buffer elaborato con padding finale: 101010101010101010000000
ora posso scrivere i miei 3 byte.
Fin qui lo so fare, solo che attualmente uso le strighe per 
rappresentarmi i miei bit e quindi volevo solo sapere se ci fossero dei 
modi per veloccizare questo processo, per questo avevo pensato di 
lavorare direttamente sui singoli bit ed avevo chiesto lumi su cosa 
dovermi studiare per poter far questo :) senza dover rompere troppo le 
scatole. :)
Quindi per ora se avete materiale che posso vedere sempre riguardante 
operazioni sui bit ne sarei felice :)
Grazie a tutti e scusate del tempo che vi ho fatto perdere ..
--
[CapoBecchino].spera.chiarificatore :)

 ho una stringa di bit "01010101 01010101 01"
Prima di proseguire l'analisi, per favore, chiariamo il concetto di
"stringa di bit".
Sono abituato a pensare alla stringa come contenitore di dati
alfanumerici, in cui ogni elemento è costituito da uno o due byte a
seconda della codifica utilizzata, e "stringa di bit" mi manda un pochino
in corto circuito.
Per allargare un pochino il discorso, sarei anche curioso di sapere da
dove vai a leggere questa "stringa", per chiarirmi ulteriormente le idee.


 dove vai a leggere questa "stringa", per chiarirmi ulteriormente le idee.
Presto detto :)
La "stringa" in question (che davvero non so come chiamarla) viene 
generata automaticamente random (per quanto potrebbe essere random) sia 
   la sua lunghezza che il suo contenuto e quindi conoscendo la sua 
natura cioè che non sempre poteva essere rappresentata con variabili di 
tipo BYTE non ho fatto altro che crearmi una variabile di tipo STRING e 
registrare al suo interno i mie 1 e 0 ;) tutto qui. Spero di essere 
stato chiaro ;)
Grazie
-- 
[CapoBecchino]

 tipo BYTE 
cioe' non puoi riceverla come array di byte? e da quando?
intendi dire che puo' arrivare un numero arbitrario di bit?
-- 
ciao, hal

 a.cara
Ciao
Raf

> intendi dire che puo' arrivare un numero arbitrario di bit?
Da dove arrivano? per mandare, ad esempio, 23 bit devo comunque
occupare 3 byte.
-- 
ciao, hal

hal1961 ha scritto:

li genero io e quindi per ora genero semplicemente una stringa di 
0101010101 random sia in lunghezza che nella loro composizione :)

 0101010101 random sia in lunghezza che nella loro composizione :)
e allora genera un array di byte e non complicarti l'esistenza,
penalizzando pure le prestazioni con tutte quelle conversioni
da e verso String ;-)
-- 
ciao, hal

 di byte ma non posso :) devo per forza generare in questo modo ;)
perche'?
-- 
ciao, hal

hal1961 ha scritto:

Perchè mi servono in questo modo :)

 Perchè mi servono in questo modo :)
palle! :-P
-- 
ciao, hal

  che se mi avrei generato array
se mi AVREI???  !!! :)
Ciao 

 ha scritto nel messaggio 
news:4erze.8422$b93....@tornado.fastwebnet.it...


 Non mi sembra una cosa impossibile :)
Sai che non ci avevo pensato ??? Ti farò sapere ;) grazie dell'idea
--
[CapoBecchino]

 Non mi sembra una cosa impossibile :)
Di impossibile in visual basic c'e' davvero poco.
Di poco performante o error prone, invece, un po' di piu' ;-)
-- 
ciao, hal

 [CapoBecchino] 

 
Grazie oggi provo e ti faccio sapere .. :) intanto GRAZIEE!!!!
-- 
[CapoBecchino]