// 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 max; // valore di ''trabocco'' private int r; // una potenza del 2 indicante il prossimo bit da erogare: // consentendo (tramite divisione di rot per r) // il mascheramento dei bit meno significativi 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 int max = 1; for( int q = 0; q < nrRot; q++ ) max *= 2; this.max = max; azzera( ); } public Contatore( ) throws IllegalArgumentException { // costruttore senza parametri this( nrRot ); } public void azzera( ){ // azzera il contatore e ne mette a fuoco // la posizione meno significativa rot = 0; r = 1; } public Boolean leggiRotella( ){ // eroga il valore della rotella corrente if( r == max ){ r = 1; return null; } // l'erogazione sara` circolare short bit = (short) ((rot / r) % 2); r *= 2; return bit == 1; } public String toString( ){ // qui i bit saranno rappresentati con 0/1 String acc = ""; long copiaRot = rot; for( int qui = 1; qui != max; copiaRot /= 2, qui *= 2 ){ if (qui == r && qui != 1 ) acc += '^'; acc += copiaRot % 2; } return acc; } public boolean incr( ){ // dopo aver modificato lo stato dell'oggetto, // incrementandolo di 1, // dice se *non* c'e` stato ''trabocco'' rispetto al // valore massimo previsto (al momento della costruzione) r = 1; if ( ++rot != max ) return true; rot = 0; return false; } }