Newsgroup: it.comp.lang.visual-basic
Titolo: Esadecimale2

Scusate il secondo post... ma lo faccio per riassumere il meglio ...
anche perchè ho trovato (non credo di essere il primo) un modo
simpatico per tirar fuori un numero esadecimale partendo dai bit
Sappiamo che il massimo numero esprimibile da un esadecimale è
(salvo smentita di Roal che mi ha cacciato fuori un 256) ... un bel
255.
Detto questo immaginiamo un bel numerone ... 5690
Allora facendo un pò di giochino mi sono detto divido il numerone
per 255 che il massimo numero ottenibile in scala di bit
ed ottengo 22 (solo la parte intera) poi con il mod mi faccio dire
quando manca di resto nella divisione ed ottengo 80
gioco fatto. Esprimo il mio 22 in scala di bit che sarebbe
128 64 32 16 8 4 2 1
  0    0   0   1  0 1 1 0
raggruppato 0001 0110 in esadecimale 16
ora esprimo la rimanenza 80 meno la parte intera della divisione 22
ovvero 58 in esadecimale
128 64 32 16 8 4 2 1
  0    0   1   1  1 0 1 0
raggruppato 0011 1010 in esadecimale 3A
il risultato 163A
Se fai hex(5690) ottiene 163A ... se fai con il sistema di Rol
ottieni 163A ... potenzialmente lo considero corretto come sistema
bisogna solo capire se ho scoperto l'acqua calda ... se vale la pena
usare sto sistema ... o se peggio ha qualche falla.
Che ne pensate? Questo mi evita di capire il 256 di Roal
Saluti Andrea

Credo che abbia qualche falla con numeri grossi ...
ho scoperto un pozzo di petrolio con dentro tanta aranciata
avariata.
Andrea

Comunque mi lascio aperto il discorso del flag ....
capire cioč come con un and od un or posso sapere
se un dato flag o numero esadecimale č contenuto in
un altro.
Potete aiutarmi. L'msdn non mi č sempre molto chiaro.
E non capisco come (i numeri sono a caso)
&h543 and &h234 = true .... o una cosa del tipo che
starebbe ad indicarmi che il flag h543 mi č dato dal risultato
di n flag tra cui il mio 234.
Andrea

E non capisco come (i numeri sono a caso)
Io addirittura utilizzo il discorso dei flag per far una list con i
giorni della settimana evidenziabili.
Ovviamente partiamo dalla premessa che conosciamo questa tabella
	    |	A     |        B       |      A  AND B       |
-----------------------------------------------------------------
	    |        V     |        V        |            V
	    |        V     |        F        |            F
 	    |        F     |        V        |            F
                 |        F     |        F        |            F
O meglio, il risultato di (A AND B) è vera se e solo se A e B sono V
(in caso di sistema binario, se sono entrambi uguali a 1)
Ora mettiamo in coda la rappresentazione binaria delle prime potenze
del due:
	2 =   00000010
	4 =   00000100
	8 =   00001000
            16=   00010000
           32 =   00100000
           64 =   01000000
          128=   10000000
Quando tu utilizzi l'operatore logico AND (bit a bit) non fai altro
che confrontare, per mezzo dell'AND, ciascun bit dei due numeri a
confronto;
es.
	3 = 00000011
	2 = 00000010
Se tu fai 2 AND 3 (oppure 3 AND 2, è la stessa cosa, ovviamente!)
(puoi partire da destra o da sinistra ... mettiamo che partiamo da
sinistra)
Il primo bit del numero 3 è 0 e del numero 2 è 0        -> 0 AND 0 =0
Il secondo bit del numero 3 è 0 e del numero 2 è 0   -> 0 AND 0 =0
Il terzo bit del numero 3 è 0 e del numero 2 è 0         -> 0 AND 0=0
Il quanrto bit del numero 3 è 0 e del numero 2 è 0    ->  0 AND 0=0
il quinto bit del numero 3 è 0 e del numero 2 è 0       ->  0 AND 0=0
Il sesto bit del numero 3 è 0 e del numero 2 è 0        ->  0 AND 0=0
Il sesto bit del numero 3 è 0 e del numero 2 è 0         -> 0 AND 0=0
Il settimo bit del numero 3 è 1 e del numero 2 è 1     ->  1 AND 1=1
l'ottavo bit del numero 3 è 1 e del numero 2 è 0       ->  1 AND 0 =0
In definitiva, il risultato di 2 AND 3 ( oppure 3 AND 2) è
		00000010
Ovvero 2!
Bene, ora che hai capito come funziona l'operatore AND (bit a bit,
proprio perchè si confrontano tutti i bit, come ho appena fatto), ti
chiederai come utilizzare questo giochetto.
Ti faccio vedere come lo uso io.
Mettiamo che hai una lista di tutti i giorni della settimana
(lunedi,martedi...domenica) e vuoi fare in modo che l'utente possa
evidenziarli o meno per poi registrare su un archivio o su un file lo
stato finale.
La prima idea potrebbe essere, nel caso dell'archivio, di utilizzare 7
campi booleani (uno per ciascun giorno della settimana) e salvare lo
stato di ciascuno.
Questo metodo funziona, ma si potrebbe fare anche in questo modo.
Se fai attenzione a come (vedi sopra) è nella sua natura la
rappresentazione binaria delle potenze del 2 ti rendi subito conto che
	2 AND 4 = 0
	4 AND 8 = 0
	2 AND 16 = 0
	32 AND 16 = 0
	.....
Puoi fare qualsiasi combinazione, ma non troverai mai un risultato
diverso da 0 perchè l'unico bit 1 che c'e' in ciascun numero è
posizionato in modo tale che in qualsiasi altra potenza del due ci sia
uno 0!!!!
E quindi   		->   1 AND 0 = 0
Poichè l'unico contributo poteva venire proprio da quell'unico 1,
sicuramente il risultato finale sarà per tutte le combinazioni 0!!!
L'utilità di tutto ciò sembra sempre più lontana, ma ormai ci siamo.
Sempre dalla lista in alto, se provo a sommare 2 e 8, per esempio,
mi accorgo che
	2 + 8    =
			00000010   +
			00001000   =
			---------------------
			00001010
Che è uguale, ovviamente, a 10.
Se ora provo a fare 10 AND 2 ottengo 2 perchè
 
		00001010   AND
		00000010     =
		--------------------------
	             00000010
Ma questo era ovvio perchè 2 e 8 non avevano alcun bit diverso da 1 in
comune e quindi se provo ad applicare l'operatore AND alla loro somma
e a 2 o a 8, riottengo 2 o 8.
Quindi, ora, se faccio questa associazione:
		Lunedì  =     2
		Martedì =     4
		Mercoledì=  8
		Giovedì   =  16
		Venerdì    = 32
		Sabato     = 64
		Domenica=128
E, prima di salvare nell'archivio, faccio la somma dei giorni
selezionati, posso salvare il tutto in una variabile.
Mettiamo che l'utenti selezioni, Lunedi, Venerdi e Sabato.
La loro somma è 98.
Salvo il valore 98 nell'archivio o nel file.
Nella fase di lettura poi, scrivo queste istruzioni
	if somma AND 2 = 2 then seleziona_lunedi
	if somma AND 4 = 4 then seleziona_martedi
 	if somma AND 8 = 8 then seleziona_mercoledi
	if somma AND 16 =16 then seleziona_giovedi
	if somma AND 32 = 32 then seleziona_venerdi
	if somma AND 64 = 64 then seleziona_sabato
	if somma AND 128 = 128 then seleziona_domenica
Così, con una sola variabile, mi sono risparmiato sette campi.
E questo è poi il metodo utilizzato nei flag ( o comunque la base è
questa).
Dove sta il difetto ?
Come ti sei reso conto progredendo con la base del due si raggiungono
velocemente grandi numeri e si comincia ad avere difficoltà a
maneggiarli.
Ma per queste piccole cose (come i giorni della settimana) è più che
utile.
Se hai bisogno di altri chiarimenti, sono qui. Ciao.
 

 utile.
Probabilmente è ancora presto e la mia mente si deve ancora aprire
completamente alla programmazione, però fai tutto questo casino per
risparmiare 7 campi?
Ma ne vale veramente la pena?
Davide

Ma ne vale veramente la pena?
Non e' solo risparmio di database, ma anche:
- in ram (e su disco) usare 1 byte invece di 28 (pensa se fosse un array: moltiplica per 
il numero di elementi);  --> SPAZIO
- trasferire  7 flag in un colpo solo (ad una funzione, ad una macchina in rete,
ecc.) --> VELOCITA'
- poter aggiungere ancora un ottavo flag _senza_ minimamente alterare il codice
che utilizza dato, semplicemente chi ignorava l' esistenza dell' ottavo flag continuera'
felicemente ad ignorarlo ed il programma funzionera' lo stesso; e questo e' un solo byte:
pensa che in un long (che e' la parola del pentium) riesci ad impaccare 32 flag;
--> MANTENIMENTO DEL CODICE
- con questa tecnica se memorizzassi, ad esempio degli indirizzi ip, che, come sai, 
sono nella forma xxx.yyy.zzz.www, invece di prevedere 15 byte per indirizzo te ne
bastano solo 4: se ne devi registrare, che so, centomila, la "piccola" differenza e'
di 878 KB;
ecc. ecc.
-- 
ciao, hal

 di 878 KB;
[cut]
ma programmare in questo modo ti viene così naturale e spontaneo o prima di
iniziare lo sviluppo di un programma ti fermi che ne so..a fare uno schemino
di dove, come e in che modo puoi recuperare velocità?
A me, almeno per il momento,  ( perchè "programmo" da poco presumo/spero)
non viene affatto naturale ragionare così anche perchè il mio pensiero si
concentra sul come farlo funzionare il programma (che per me è già tanto).
Lasciatelo dire, tu sei un maestro, spero un giorno di poter arrivare a
tanto anche io.
Delle volte non mi sento degno di postare su questo ng...
Davide

 Delle volte non mi sento degno di postare su questo ng...
Senza nulla togliere ad hal, che č veramente uno dei migliori, ricordati che
le soluzioni piů complesse non sempre sono le migliori, anzi!
Come diceva Einstain "non esistono soluzioni semplici, ma solo soluzioni
_piů_ semplici".
Ciao

 maneggiarli.
e perché? basta la posizione. Mica devi calcolarle esplicitamente (e se
anche fosse lo fai una volta per tutte)
Const LUN = 2^0
Const MAR = 2^1
.
.
e poi:
If giorni And LUN Then seleziona_Lunedì
[(giorni And LUN) darà 0 oppure LUN a seconda del valore del bit 0; il primo
valore (0) è interpretato come False, il secondo (LUN) come True. A me piace
questa forma contratta, ma nulla vieta di usare la normale If giorni And LUN
= LUN. C'è chi usa If (cond = True) Then ..; a me non piace, preferisco If
cond Then ..]
In questo modo puoi costruire espressioni condizionali in modo quasi
automatico e molto naturale:
Const Festivo = SAB Or DOM
Const Feriale = Not Festivo    '!!!!!!!!
If giorni And Festivo Then ...
Altra cosa molto pratica: implementare una matrice di CheckBox (o una
ListBox a selezione multipla):
For i = 0 to 6
   If giorni And 2^i Then
      chkDaySelected(i) = vbChecked
   Else
      chkDaySelected(i) = vbUnChecked
   End If
Next i
Per salvare i cambiamenti:
giorni = 0
For i = 0 to 6
   If chkDaySelected(i) = vbChecked Then
      giorni = giorni Or 2^i
   End If
Next i
oppure al volo sull'evento Click dei CheckBox.
..e sono solo alcuni spunti. Usa i bit!
anche i GigaByte sono fatti di bit :)
Silv:o)

Davide
Non vedo dove sia il casino ...
In fase di progettazione, per mia comodità, mi creo una enum con le 7
costanti per i giorni della settimana.
In fase di salvataggio devo:
	-controllare lo stato di ciascuna selezione e fare una somma
	(comunque lo stato della selezione l'avrei dovuto fare!)
In fase di lettura devo fare 7 confronti;
 
Non mi sembra poi così complicato ...

di dove, come e in che modo puoi recuperare velocità?
E' ovvio che le idee per risolvere i problemi sono dettate dalle
conoscenze maturate... la velocità con cui vengono in mente, invece,
dall'esperienza ...

 Usare OR al posto del fare la somma ?
in pratica nessuna. Anche qui è questione di stile e di abitudine.
Mamma M$, per dirne una, usa negli esempi ora un metodo ora l'altro.
Ciao, Silv:o)

 Usare OR al posto del fare la somma ?
A scanso di equivoci, il consiglio "usa i bit!" non voleva essere
assolutamente diretto a te in particolare, che mi pare li utilizzi bene e ne
consigli l'uso, ma una esortazione del tutto generica, come dire "evviva i
bit!".
Probabilmente dovevo agganciarmi al messaggio precedente di Andrea, che
chiedeva lumi sull'uso delle tecniche di mascheramento con i bit.
Ciao, Silv:o)

 Einstein
Stano... ero convinto anch'io si scrivesse "Einstein"... poi ho cercato
"Einstain" su Lycos (tanto per dirne uno) e ho trovato un mucchio di link
con questo nome.
Ora riprovo con "Einstein" e ne trovo altrettanti...
Tutto è relativo? :)
Ciao

 valori presi in considerazione e' composto da potenze di 2.
Esatto, se i bit non si sovrappongono, Insiemistica e Calcolo Combinatorio
ci insegnano che OR = + e AND = *