-+  Associazione
-+  Documenti
 |-  Modern Perl
 |-  Bibliografia
 |-  Articoli
 |-  Talk
 |-  Perlfunc
 |-  F.A.Q.
 |-  F.A.Q. iclp
-+  Eventi
-+  Community
-+  Blog
-+  Link
Corso di Perl



 


indietro

[53] Come si manipolano gli array di bit?

Usate pack() e unpack() o anche vec() e le operazioni a livello di bit.

Per esempio, questo imposta ad 1 i bit di $vet le cui posizioni sono contenute in @posizioni:

    $vet = '';
    foreach(@posizioni) { vec($vet,$_,1) = 1 }

Ecco come, dato un vettore in $vet, potete ottenere quei bit nel vostro array @interi:

    sub vetbit_in_lista {
        my $vet = shift;
        my @interi;
        # Trova la densita` dei byte nulli poi seleziona l'algoritmo migliore
        if ($vet =~ tr/\0// / length $vet > 0.95) {
            use integer;
            my $i;
            # Questo metodo e` piu` veloce avendo byte in maggioranza nulli
            while($vet =~ /[^\0]/g ) {
                $i = -9 + 8 * pos $vet;
                push @interi, $i if vec($vet, ++$i, 1);
	        push @interi, $i if vec($vet, ++$i, 1);
	        push @interi, $i if vec($vet, ++$i, 1);
	        push @interi, $i if vec($vet, ++$i, 1);
	        push @interi, $i if vec($vet, ++$i, 1);
	        push @interi, $i if vec($vet, ++$i, 1);
	        push @interi, $i if vec($vet, ++$i, 1);
	        push @interi, $i if vec($vet, ++$i, 1);
            }
        } else {
            # Questo metodo e` un algoritmo veloce e generale
            use integer;
            my $i_bit = unpack "b*", $vet;
            push @interi, 0 if $i_bit =~ s/^(\d)// && $1;
            push @interi, pos $i_bit while($i_bit =~ /1/g);
        }
        return \@interi;
    }

Questo metodo va tanto più veloce quanto più sparso è il vettore di bit. (Per gentile concessione di Tim Bunce e Winfried Koenig.)

Potete rendere il ciclo while molto più breve con questo suggerimento di Benjamin Goldberg:

    while($vet =~ /[^\0]+/g ) {
       push @interi, grep vec($vet, $_, 1), $-[0] * 8 .. $+[0] * 8;
    }

Oppure usate il modulo CPAN, Bit::Vector:

    $vettore = Bit::Vector->new($numero_di_bit);
    $vettore->Index_List_Store(@interi);
    @interi = $vettore->Index_List_Read();

Bit::Vector fornisce dei metodi efficienti per vettori di bit, insiemi di piccoli interi e matematica per grandi interi.

Ecco una più estesa illustrazione dell'uso di vec():

    # dimostrazione di vec
    $vettore = "\xff\x0f\xef\xfe";
    print "La stringa di Ilya \\xff\\x0f\\xef\\xfe rappresenta il numero ",
          unpack("N", $vettore), "\n";
    $settato = vec($vettore, 23, 1);
    print "Il suo 23esimo bit vale ", $settato ? "1" : "0", ".\n";
    pvet($vettore);
    imposta_vet(1,1,1);
    imposta_vet(3,1,1);
    imposta_vet(23,1,1);
    imposta_vet(3,1,3);
    imposta_vet(3,2,3);
    imposta_vet(3,4,3);
    imposta_vet(3,4,7);
    imposta_vet(3,8,3);
    imposta_vet(3,8,7);
    imposta_vet(0,32,17);
    imposta_vet(1,32,17);
    sub imposta_vet {
        my ($posizione, $ampiezza, $valore) = @_;
	my $vettore = '';
        vec($vettore, $posizione, $ampiezza) = $valore;
        print "posizione=$posizione ampiezza=$ampiezza valore=$valore\n";
        pvet($vettore);
    }
    sub pvet {
        my $vettore = shift;
        my $i_bit = unpack("b*", $vettore);
        my $i = 0;
        my $BASE = 8;
        print "lunghezza del vettore in byte: ", length($vettore), "\n";
        @i_byte = unpack("A8" x length($vettore), $i_bit);
        print "i bit sono: @i_byte\n\n";
    }

vedi in inglese

AUTORE E COPYRIGHT

Copyright (c) 1997, 1998, 1999, 2000, 2001 Tom Christiansen e Nathan Torkington. Tutti i diritti riservati.

Questa documentazione è libera; puoi ridistribuirla e/o modificarla secondo gli stessi termini applicati al Perl.

Indipendentemente dalle modalitè di distribuzione, tutti gli esempi di codice in questo file sono rilasciati al pubblico dominio. Potete, e siete incoraggiati a farlo, utilizzare il presente codice o qualunque forma derivata da esso nei vostri programmi per divertimento o per profitto. Un semplice commento nel codice che dia riconoscimento alle FAQ sarebbe cortese ma non è obbligatorio.

D:
Progetti e documenti in rilievo
Corso di Perl Progetto pod2it
D:
La ML di Perl.it
mongers@perl.it è la lista ufficiale di Perl Mongers Italia per porre quesiti di tipo tecnico, per rimanere aggiornato su meeting, incontri, manifestazioni e novità su Perl.it.
Iscriviti!
D:
Annunci Google