// Implementiamo qui un contatore binario // il cui numero di bit viene fissato al // momento della costruzione. // Le operazioni previste sono: // (0) costruzione e (ri)azzeramento; // (1) incremento unitario (fino a un valore massimo stabilito al momento della costruz.); // (2) accesso progressivo ai bit del contatore, cominciando dal meno significativo; // (3) ''esposizione'', sotto forma di String, del valore corrente del contatore. // Firma dei metodi: // Costruttori: // public Contatore( int nrBit ) // public Contatore( ) // // Metodi di accesso: // public Boolean leggiRotella( ) // il prossimo bit (metaforicam. 'rotella') // public String toString( ) // versione stampabile del contatore // // Metodi di modifica dello stato: // public void azzera( ) // inizializzazione / reset // public boolean incr( ) // incremento unitario del contatore class Contatore{ private long rot; // 'rotelle' che formano il contatore final long soglia; // numero raggiunto il quale abbiamo traboccato private long r; // posizione del prossimo bit che verra` erogato // rappresentata come potenza del 2 per la quale dividere rot final static int nrRot = 8; // in mancanza d'indicaz., sara` adottato questo valore public Contatore( int nrRot ) throws IllegalArgumentException { // costruttore con indicaz. del numero di rotelle if ( nrRot <= 0 || nrRot > 62 ) throw new IllegalArgumentException(); long s = 1; for( int i = 0; i < nrRot; i++ ) s *= 2; soglia = s; azzera(); } public Contatore( ) throws IllegalArgumentException { // costruttore senza parametri this( nrRot ); } public void azzera( ){ // azzera il contatore (la 1.a volta non occorrerebbe farlo) // e ne mette a fuoco la posizione meno significativa rot = 0; r = 1; // potenza 0-esima di 2 } public Boolean leggiRotella( ){ // eroga il valore della rotella corrente if( r == soglia ){ r = 1; return null; } // l'erogazione sara` circolare boolean bit = ( rot / r ) % 2 == 1; r *= 2; // predisposizione per l'erogazione del prossimo bit return bit; // acquisisco il dato e preparo la prossima acquisiz. } public String toString( ){ // qui i bit saranno rappresentati con 0/1 String acc = ""; // for( boolean bit : rot ) acc += (bit) ? 1 : 0; for( long i = 1; i < soglia; i *= 2 ){ if ( i == r ) acc += '^'; acc += ( rot / i ) % 2; } // esercizio: costruire il risultato 'acc' sottosopra return acc; } public boolean incr( ){ r = 1; // ora che il contatore verra` aumentato, andra` ripercorso da capo rot++; if ( rot == soglia ) rot = 0; return rot != 0; // dice se non c'e` stato trabocco } }