Newsgroup: it.comp.java
Titolo: Quando le cose facili diventano impossibili....[codice facile]

Vorrei trasformare un binario in decimale, lo so che esiste
"Integer.parseInt(digitString,2)" ma comunque questo dovrebbe funzionare!
o no?
codice-----------------------------------
    //stream e buffer per l'input da console
   InputStreamReader reader = new InputStreamReader(System.in);
   BufferedReader console = new BufferedReader(reader);
   //memorizzo il numero binario
   System.out.print("inserisci un numero in base binaria: ");
   String binaryString = console.readLine();
   //calcolo il valore posizionale massimo delle cifre del numero in base 2
   int posValue = (int)Math.pow(2,binaryString.length()-1);
   //suddivido la stringa
   StringTokenizer tokenizer = new StringTokenizer(binaryString);
   //inizializzo il numero decimale
   int decNum = 0;
   //contatore per il controllo visuale del ciclo
   int counter = 0;
   //calcolo il numero decimale corrispondente
   while (tokenizer.hasMoreTokens())
   {    //controllo valore posizionale
        System.out.print("posValue "+ posValue);
        //trasfomo ogni carattere in intero e lo moltiplico
        //per il suo valore posizionale
        decNum = decNum + Integer.parseInt(tokenizer.nextToken())*posValue;
        //dimezzo il valore posizionale
        posValue = posValue/2;
        //controllo ciclo
        System.out.println(" counter "+ ++counter);
   }
   System.out.println("corrisponde a "+ decNum +" in base decimale.");
fine codice---------------------------------------------
Perchè svolge il ciclo solo una volta ed il risultato è pure sballato?
Grazie!!!
--
ciao,   libeX

libeX wrote:

mai visto niente di piu' inefficiente!

Ciao,
a parte le osservazioni sul codice, il problema e' qui:
   //suddivido la stringa
   StringTokenizer tokenizer = new StringTokenizer(binaryString);
Con questo tipo di costruttore, StringTokenizer utilizza come
delimitatori i caratteri: " \t\n\r\f".
Andrea

______________________________________________


criticare solo non e` costruttivo. non qui.
Vista la sua premessa penso fosse un caso di studio. Magari e` alle
prime armi. Non credo proprio che l'efficienza del codice fosse un
requisito richiesto. Inoltre non ho visto il codice di libeX, quindi non
entro nel merito.
Pero` tu evidentemente l'hai fatto: perche` non gli proponi allora
un'alternativa piu` efficiente? Magari gli puo` tornare piu` utile del
commento di cui sopra...
-- 
Ciao,  |     Gott weiss ich will kein Engel sein
Matteo |                     -- Rammstein, Engel

Grazie Andrea! Mi ero fissato con quel StringTokenizer...
per pippo:
...è che non so quasi nemmeno cosa sia l'efficienza in programmazione,
sto ancora cercando di impratichirmi con le classi ed i metodi più usati.
Sapete dirmi dove posso trovare documentazioni valide sull'ottimizzazione
del codice? (mi interessano sia i trucchi più semplici che le problematiche
più complesse)
Mi servirà per quando diventerò più bravo!
Intanto...va meglio cosi?     ;o)
---------START--CODE------------
   BufferedReader console = new BufferedReader(new
InputStreamReader(System.in));
   System.out.print("Inserisci un numero binario: ");
   String binaryNum = console.readLine();
   int binLength = binaryNum.length();
   int valPosition = (int)Math.pow(2,binLength - 1);
   int decimalNum = 0;
   int counter = 0;
   while (counter<binLength)
   {    int cifra =
Integer.parseInt(binaryNum.substring(counter,counter+1));
        if(cifra == 1) decimalNum = decimalNum + valPosition;
        valPosition = valPosition/2;
        counter = counter+1;
   }
   System.out.println(decimalNum+"");
--------END---CODE---------------
ciao  libeX

         counter = counter+1;
C'e' un altro algoritmo per fare la stessa cosa.
Pensaci.

eccoci...
-----------------------------------
String binaryNum = console.readLine();
int decimalNum = 0;
int valPosition = 1;
for (int binLength = binaryNum.length(); binLength > 0; binLength--)
{  int cifra = Integer.parseInt(binaryNum.substring(binLength-1,binLength));
   decimalNum = decimalNum + cifra*valPosition;
   valPosition=valPosition*2;
}
System.out.println(decimalNum+"");
-----------------------------------
Grazie pippo per il corso pratico accelerato su Java!
ciao,   libeX

non e' questa la versione corretta??
for (int binLength = binaryNum.length(); binLength > 0; binLength--)
 {  int cifra =
Integer.parseInt(binaryNum.substring(binLength-1,binLength));
    decimalNum = decimalNum*valPosition  + cifra;
... e poi  tutto uguale...

--
Andrea GHITTINO

 System.out.println(decimalNum+"");
Ora non rimane che eliminare il parseInt: inutile scomodarlo per un solo 
carattere!

Dimenticavo:
quando aquisisci input (soprattutto da tastiera) e' sembre una buona regola 
controllare che il dato sia accettabile: nel tuo caso controlla se digitano 
0 o 1.
Segnala errore con una print (su err) in caso contrario.

     decimalNum = decimalNum*valPosition  + cifra;
no!
Il valore posizionale di una cifra dipende dalla posizione che occupa nella
configurazione rappresentante il numero:
valore posizionale = cifra n-esima * potenza n-esima della base della
configurazione
La somma dei valori posizionali è il valore totale del numero.
Ho usato un pochino impropriamente l'identificatore valPosition ma
l'espressione aritmetica era giusta.
per completezza, provo infine a concludere:
sostituisco parseInt con parseShort e poi ecco come controllo l'input:
---CODE------------
String binaryNum;
boolean done = true;
do
{  System.out.print("Inserisci un numero binario (E per uscire): ");
   binaryNum = console.readLine();
   if (binaryNum.equalsIgnoreCase("e")) System.exit(1);
   else if (binaryNum.equals("")) done = false;
   else
   {  for (int count = 0; count<binaryNum.length() ; count++)
      {  if (binaryNum.charAt(count)!='1' & binaryNum.charAt(count)!='0')
         {  done = false;
            break;
         }
         else done = true;
      }
   }
}
while (!done);
---CODE----------
è un po' abbondante tenuto conto della funzione del programma, vero?   :o)
...però sembra abbastanza funzionale anche per le mie future esercitazioni.
ciao e grazie, libeX

 sostituisco parseInt con parseShort e poi ecco come controllo l'input:
Utilizzare la vecchia tecnica per cui un carattere (preso con charAt) - '0' 
da' il valore intero del carattere?
Poi dopo testi che sia 0 <= n <= 1.
Infine + semplicemente se
int n = 0;
for (int i = 0 ; i < c.length() ; i++) {
  int ni = (int) c.charAt(i) - '0';
  if (i >=0) and (i <=1)
    n = 2 * n + ni
  else
    .........
}
Che ne pensi?


 Che ne pensi?
Volendo tornare ai vecchi tempi -e supponendo che la stringa sia di 0 e
1- si potrebbe anche fare:
  char[] c = stringa.toCharArray();
  int lun = c.length - 1;
  long risultato = 0;
  while (lun-- > 0)
    risultato = risultato << 1 | (c[n] & 1);
(in fondo, il left shift č molto meglio di una moltiplicazione per due
per ovvii motivi e un and ed un or sono piů veloci di una somma...)
Ciao,
	Stefano
----------
"X WindowSSS, teSSSoro mio... lo odieremo per SSSempre"
Bill Gollum
----------