Gambas-it

Gambas3 => Programmazione => Topic aperto da: vuott - 20 Novembre 2016, 01:56:54

Titolo: Compitino per casa sui bit
Inserito da: vuott - 20 Novembre 2016, 01:56:54
Poiché questa settimana siete stati eccessivamente vivaci e biricchini, ho trovato un nuovo compitino (che ho ripreso ed opportunamente adattato da un forum sul linguaggio C) da svolgere nel fine settimana :

" Scandire bit per bit il valore numerico 165 e stampare in console tutti i suoi bit impostati a 1 "
Titolo: Re:Compitino per casa sui bit
Inserito da: Gianluigi - 20 Novembre 2016, 10:21:48
Poiché questa settimana siete stati eccessivamente vivaci e biricchini, ho trovato un nuovo compitino (che ho ripreso ed opportunamente adattato da un forum sul linguaggio C) da svolgere nel fine settimana :

" Scandire bit per bit il valore numerico 165 e stampare in console tutti i suoi bit impostati a 1 "

Scusi sig. Maestro,
ma come Lei ben sa, io in materia binaria sono parecchio asino.
Pertanto sono a domandare: Lei ci sta chiedendo di dare questa (http://www.gambas-it.org/wiki/index.php?title=Sapere_quanti_bit_posti_ad_1_sono_presenti_in_un_numero) soluzione?
Oppure ci chiede di ciclare con mod il numero 165 / 2 ed estrapolare solo gli uno?
Con rinnovata stima ecc...


 
Titolo: Re:Compitino per casa sui bit
Inserito da: vuott - 20 Novembre 2016, 15:09:11
Bene facesti a segnalarmi quella pagina, la quale contiene una soluzione in fin efficace, ma che fa uso della funzione Bin( ) e di una funzione sulle Stringhe Mid( ) .

La soluzione funziona, ma.... non mi piace.
Io avrei un altro modo, più elegante e veloce, ma voglio prima sbirciare sui vostri.    :devil:

Ad ogni modo mostraci la tua soluzione con la funzione Mod, che opera sui valori numerici interi.


Comunicazione integrativa:
Ogni soluzione aggiuntiva funzionante sarà inserita in quella pagina della nostra WIKI con citazione dell'autore.

Titolo: Re:Compitino per casa sui bit
Inserito da: Gianluigi - 20 Novembre 2016, 15:22:15
Bene facesti a segnalarmi quella pagina, la quale contiene una soluzione in fin efficace, ma che fa uso della funzione Bin( ) e di una funzione sulle Stringhe Mid( ) .

La soluzione funziona, ma.... non mi piace.
Io avrei un altro modo, più elegante e veloce, ma voglio prima sbirciare sui vostri.    :devil:

Ad ogni modo mostraci la tua soluzione con la funzione Mod, che opera sui valori numerici interi.


Comunicazione integrativa:
Ogni soluzione aggiuntiva funzionante sarà inserita in quella pagina della nostra WIKI con citazione dell'autore.

Pensavo a qualcosa del genere:
Codice: [Seleziona]
Public Sub Main()

  Dim n, b, c As Integer
 
  n = 165
  Print "La rappresentazione binaria di "; n; " è ";
  While n > 0
    b = n Mod 2
    Print b;
    If b <> 0 Then Inc c
    n = n \ 2
  Wend
  Print " e contiene "; c; " bit a uno"

End
:ciao:
Titolo: Re:Compitino per casa sui bit
Inserito da: vuott - 20 Novembre 2016, 16:46:38
Mooolto bene, Gianluigi !
Come Gianluigi ha ben dimostrato, è bastato il solo operatore aritmetico Mod per risolvere il problema.

Ho già aggiunto la tua soluzione alla pagina, che hai segnalato, della nostra WIKI.


Restiamo in attesa di altre possibili soluzioni.....
Titolo: Re:Compitino per casa sui bit
Inserito da: Top Fuel - 20 Novembre 2016, 17:44:45
Ecco la mia soluzione:

Codice: [Seleziona]
Public Sub Form_Open()
Dim numero, i, bitauno As Byte
numero = 165
For i = 0 To 7
   If BTst(numero, i) = True Then Inc bitauno
Next
Print "Il numero di bit a uno è: "; bitauno
End
Titolo: Re:Compitino per casa sui bit
Inserito da: Gianluigi - 20 Novembre 2016, 18:28:15
Ottimo e rapido  :D ma completandolo così per rimanere in scia al mio (integer) mi sono accorto di questa differenza e mi domando, c'è un errore nel mio codice?
Ad esempio con il numero 23750 il mio da "La rappresentazione binaria di 23750 è 011000110011101 e contiene 8 bit a uno"
Mentre la funzione bin da "La rappresentazione binaria di 23750 è 101110011000110 e contiene 8 bit a uno"
Vale a dire il primo zero scivola in fondo. Centra qualcosa la faccenda degli indiani?  :hatecomputer:
Codice: [Seleziona]
Public Sub Main()

  Dim numero, i, bitauno As Integer
 
  numero = 23750
  For i = 0 To 31
     If BTst(numero, i) = True Then Inc bitauno
  Next 
  Print "La rappresentazione binaria di "; numero; " è "; Bin(numero); " e contiene "; bitauno; " bit a uno"; 

End
Titolo: Re:Compitino per casa sui bit
Inserito da: vuott - 20 Novembre 2016, 18:35:38
Ecco la mia soluzione:

:o

Ottimo TopFuel !
Ho posto il tuo codice come prima soluzione nella pagina della nostra WIKI !
Titolo: Re:Compitino per casa sui bit
Inserito da: vuott - 20 Novembre 2016, 18:42:24
Vale a dire il primo zero scivola in fondo. Centra qualcosa la faccenda degli indiani?
...gli indiani ti fanno lo scherzetto di ruotare il valore scritto in bit.   :D

Prova a leggere il tuo risultato da destra verso sinistra....
Titolo: Re:Compitino per casa sui bit
Inserito da: Gianluigi - 20 Novembre 2016, 19:42:19

Prova a leggere il tuo risultato da destra verso sinistra....

 ???

Ma la differenza?
Titolo: Re:Compitino per casa sui bit
Inserito da: Gianluigi - 20 Novembre 2016, 23:13:44
Vale a dire il primo zero scivola in fondo. Centra qualcosa la faccenda degli indiani?
...gli indiani ti fanno lo scherzetto di ruotare il valore scritto in bit.   :D

Prova a leggere il tuo risultato da destra verso sinistra....

Ehhhhhh!  :donkey: finalmente ho capito  :hard:

Purtroppo la distrazione mi ha giocato un brutto scherzo, ma non solo anche il fatto che 165 in binario è uguale in tutti e due i sensi di lettura e io mi sono fidato di questo risultato.
Col mio codice occorre invertire il risultato per ottenere un binario corretto, vuott mi aveva avvertito di leggerlo alla rovescia ma io non ho afferrato il senso vero.
Non chiedetemi il perchè ottengo il binario rovesciato, non l'ho (ancora?) capito, pazienza ho perso tempo mio.
Il mio codice si allunga di molto:
Codice: [Seleziona]
' Gambas module file

Public Sub Main()

  Dim n, b, c As Integer
  Dim s As String
 
  n = 23750
  Print "La rappresentazione binaria di "; n; " è ";
  While n > 0
    b = n Mod 2
    'Print b;
    s &= CStr(b)
    If b <> 0 Then Inc c
    n = n \ 2
  Wend
  s = Inverto(s)
  Print s; " e contiene "; c; " bit a uno"

End

Private Function Inverto(valore As String) As String
 
 
  Dim a As String
  Dim l, i As Integer
 
  l = Len(valore)
 
  For i = l To 1 Step - 1
   a &= Mid(valore, i, 1)
  Next
  Return a
 
End

Aggiungo anche il codice per ottenere il decimale da un binario:
Codice: [Seleziona]
' Gambas module file

Public Sub Main()

  Dim b, t, i, e, f As Integer
  Dim s As String
 
 
  s = "101110011000110"
  t = Len(s)
  e = t
  For i = 1 To t
    b = CInt(Mid(s, i, 1))
    Dec e
   f += b * 2 ^ e
  Next
  Print f; " è la rappresentazione decimale di "; s

End



Ci sarà anche di meglio, ma questo è quanto sono riuscito a combinare oggi  ;D
 :ciao: :ciao:
Titolo: Re:Compitino per casa sui bit
Inserito da: Top Fuel - 20 Novembre 2016, 23:40:27
Ottimo TopFuel !
Ho posto il tuo codice come prima soluzione nella pagina della nostra WIKI !

Mi sento oDorato di tale oDore.  :D
Titolo: Re:Compitino per casa sui bit
Inserito da: vuott - 21 Novembre 2016, 00:40:42
... anche il fatto che 165 in binario è uguale in tutti e due i sensi di lettura e io mi sono fidato di questo risultato.
...in effetti è "palindromo"   :D
10100101


Titolo: Re:Compitino per casa sui bit
Inserito da: vuott - 21 Novembre 2016, 01:03:52
Il mio codice si allunga di molto:
Codice: [Seleziona]
........

Private Function Inverto(valore As String) As String
 
 
  Dim a As String
  Dim l, i As Integer
 
  l = Len(valore)
 
  For i = l To 1 Step - 1
   a &= Mid(valore, i, 1)
  Next
  Return a
 
End

Ci sarà anche di meglio, ma questo è quanto sono riuscito a combinare oggi

Puoi accorciare un po', usando una variabile vettoriale di tipo Byte[ ] ed in particolare il suo Metodo .Reverse( ):
Codice: [Seleziona]
Public Sub Main()

  Dim n, b, c As Integer
  Dim bb As New Byte[]
 
  n = 23750
 
  Print "La rappresentazione binaria di "; n; " è ";
  While n > 0
    b = n Mod 2
    bb.Push(b)
    If b <> 0 Then Inc c
    n = n \ 2
  Wend
 
  bb.Reverse()
 
  For b = 0 To bb.Max
    Print bb[b];
  Next

  Print " e contiene "; c; " bit a 1"

End
Titolo: Re:Compitino per casa sui bit
Inserito da: Gianluigi - 21 Novembre 2016, 13:06:38

Puoi accorciare un po', usando una variabile vettoriale di tipo Byte[ ] ed in particolare il suo Metodo .Reverse( ):
Codice: [Seleziona]
Public Sub Main()

  Dim n, b, c As Integer
  Dim bb As New Byte[]
 
  n = 23750
 
  Print "La rappresentazione binaria di "; n; " è ";
  While n > 0
    b = n Mod 2
    bb.Push(b)
    If b <> 0 Then Inc c
    n = n \ 2
  Wend
 
  bb.Reverse()
 
  For b = 0 To bb.Max
    Print bb[b];
  Next

  Print " e contiene "; c; " bit a 1"

End

 :ok: Così è meglio.

Se avessi visto prima questa (http://www.lezionidimatematica.net/Binario/lezioni/bin_lezione_03.htm) lezione, mi sarei risparmiato tanta fatica, anche se occorre dire che senza un po di fatica le cose non si capiscono a fondo.
Beh a fondo forse è troppo :) Comunque sia, per sintetizzare, così come si può riottenere un numero decimale dividendolo per 10 invertendo i suoi resti...:
Prendiamo come esempio il numero 451 :
451 / 10 = 45 Resto 1 (451 Mod 10 = 1)
45   / 10 =   4 Resto 5 (45   Mod 10 = 5)
4    / 10 =    0 Resto 4 (4     Mod 10 = 4)
...allo stesso modo possiamo ottenerne il corrispondente binario invertendo i resti della divisione per due:
451 / 2 = 225 Resto 1 (451 mod 2 = 1)
225 / 2 = 112 Resto 1 (225 Mod 2 = 1)
112 / 2 =   56 Resto 0 (112 Mod 2 = 0)
56   / 2 =   28 Resto 0 (56   Mod 2 = 0)
28   / 2 =   14 Resto 0 (28   Mod 2 = 0)
14   / 2 =     7 Resto 0 (14   Mod 2 = 0)
7     / 2 =     3 Resto 1 (7     Mod 2 = 1)
3     / 2 =     1 Resto 1 (3     Mod 2 = 1)
1     / 2 =     0 Resto 1 (1     Mod 2 = 1)
Raggiunto lo zero si termina.

Operazioni inverse (moltiplicazioni) per ottenere il decimale dal binario.

 :ciao: :ciao:
Titolo: Re:Compitino per casa sui bit
Inserito da: kicco - 21 Novembre 2016, 13:13:17
Argh!!!
Mi sono distratto un secondo e avete già fatto!! :rolleyes:
Imparo e permango in ultimo banco col cappello da asino, ma con le orecchie aperte!! :P
 :ciao: :ciao:
Titolo: Re:Compitino per casa sui bit
Inserito da: Gianluigi - 21 Novembre 2016, 13:19:11
Si, si, si fa finta di passar per bischeri!  :P :P
Il fatto è che sei un pigrone  ;D

Comunque il Maestro non ha ancora elargito completamente la sua sapienza (leggi sua soluzione)   :-\

 :ciao: :ciao:
Titolo: Re:Compitino per casa sui bit
Inserito da: kicco - 21 Novembre 2016, 14:07:36
Citazione
Il fatto è che sei un pigrone  ;D
...ehm... ho la giustifica.
Ero indisposto!  ;D

Titolo: Re:Compitino per casa sui bit
Inserito da: Top Fuel - 21 Novembre 2016, 19:05:24
Aggiungo anche il codice per ottenere il decimale da un binario:
Codice: [Seleziona]
' Gambas module file

Public Sub Main()

  Dim b, t, i, e, f As Integer
  Dim s As String
 
 
  s = "101110011000110"
  t = Len(s)
  e = t
  For i = 1 To t
    b = CInt(Mid(s, i, 1))
    Dec e
   f += b * 2 ^ e
  Next
  Print f; " è la rappresentazione decimale di "; s

End



Ci sarà anche di meglio, ma questo è quanto sono riuscito a combinare oggi  ;D
 :ciao: :ciao:

Senza tanti fronzoli:

Codice: [Seleziona]
binario = "101110011000110"
Print CInt(Val(binario))

Notare il risultato. Se ti ricordi cosa ho scritto sul libro dovresti sapere il perchè... ;)
Titolo: Re:Compitino per casa sui bit
Inserito da: Gianluigi - 21 Novembre 2016, 21:07:33

Senza tanti fronzoli:

Codice: [Seleziona]
binario = "101110011000110"
Print CInt(Val(binario))

Notare il risultato. Se ti ricordi cosa ho scritto sul libro dovresti sapere il perchè... ;)

 ???
A me non funziona  :-\
Titolo: Re:Compitino per casa sui bit
Inserito da: Top Fuel - 21 Novembre 2016, 21:15:51
Si, hai ragione, stavolta ho cannato io.
Proverò a rifarlo.
Titolo: Re:Compitino per casa sui bit
Inserito da: Top Fuel - 21 Novembre 2016, 22:35:42
Rifatto, adesso dovrebbe funzionare bene:

Codice: [Seleziona]
Public Sub Form_Open()
Dim decimale As Integer
Dim i, bit As Byte
Dim binario As String
binario = "101110011000110"
For i = Len(binario) To 1 Step -1
   bit = CByte(Mid$(binario, i, 1))
   If bit = 1 Then decimale += 2 ^ (Len(binario) - i)
Next
Print decimale
End
Titolo: Re:Compitino per casa sui bit
Inserito da: vuott - 22 Novembre 2016, 00:04:55
adesso dovrebbe funzionare bene:
L'ho aggiunto come ulteriore modalità di conversione nell'apposita pagina della nostra WIKI:

http://www.gambas-it.org/wiki/index.php?title=Convertire_un_numero_da_rappresentazione_binaria_in_decimale
Titolo: Re:Compitino per casa sui bit
Inserito da: Top Fuel - 22 Novembre 2016, 00:14:46
Ulteriore oDore. :)
Titolo: Re:Compitino per casa sui bit
Inserito da: Top Fuel - 24 Novembre 2016, 23:11:57
Versione migliorata dell'esercizio che calcola quanti bit è lungo il numero, quindi indipendente dal tipo di variabile numerica (intera, ovviamente):

Codice: [Seleziona]
Public Sub Form_Open()
Dim numero As Long
Dim i, nbit, bitauno As Byte
numero = 23750
nbit = CByte(Log2(numero) + 1)
For i = 0 To nbit
   If BTst(numero, i) = True Then Inc bitauno
Next
Print "Il numero di bit a uno è: "; bitauno
End