Τελεστές κατά bit#

Οι λογικοί τελεστές εφαρμοσμένοι σε κάθε ζεύγος bits παράλληλα, επιπλέον οι δύο ολισθήσεις. Ένας ακέραιος 32 ή 64 bit είναι, από τη σκοπιά αυτών των τελεστών, ένα διάνυσμα ανεξάρτητων τιμών ενός bit.

Τελεστής

Πράξη

Κανόνας ανά bit

&

AND κατά bit

κάθε bit εξόδου = a b

|

OR κατά bit

κάθε bit εξόδου = a b

^

XOR κατά bit

κάθε bit εξόδου = a b

~

NOT κατά bit

κάθε bit εξόδου = ¬a (μοναδιαίος)

<<

αριστερή ολίσθηση

ολίσθηση bit προς τα αριστερά, γέμισμα με μηδενικά από τα δεξιά

>>

δεξιά ολίσθηση

ολίσθηση bit προς τα δεξιά

Οι τελεστέοι εξαναγκάζονται σε ακεραίους (στρογγυλοποίηση προς το μηδέν, με προειδοποιήσεις αν παρέχεται μη ακέραια συμβολοσειρά υπό use warnings).

0xFF & 0x0F           # 0x0F     -- mask to low nibble
0x10 | 0x01           # 0x11     -- combine flag bits
0xFF ^ 0xAA           # 0x55     -- toggle alternating bits
~0                    # -1 (or all-ones, depending on integer width)
1  << 4               # 16
32 >> 2               # 8

Θέση, καθάρισμα, εναλλαγή, έλεγχος μιας σημαίας#

Οι τέσσερις βασικές πράξεις σημαίας σε ένα μόνο bit:

use constant FLAG_VERBOSE  => 0x01;
use constant FLAG_DRY_RUN  => 0x02;
use constant FLAG_RECURSE  => 0x04;
use constant FLAG_FORCE    => 0x08;

my $flags = 0;

$flags |=  FLAG_VERBOSE;       # SET    -- OR with the bit
$flags |=  FLAG_DRY_RUN;       # SET another
$flags &= ~FLAG_DRY_RUN;       # CLEAR  -- AND with the inverted bit
$flags ^=  FLAG_VERBOSE;       # TOGGLE -- XOR with the bit
my $on = $flags & FLAG_RECURSE;# TEST   -- AND, then test truthiness

Καθεμία είναι εφαρμογή ενός bit ενός λογικού τελεστή: ενεργοποίηση είναι bit flag, απενεργοποίηση είναι bit ¬flag, εναλλαγή είναι bit flag, έλεγχος είναι bit flag.

Σύνθετη ανάθεση#

Και οι έξι δυαδικοί τελεστές κατά bit έχουν σύνθετες μορφές:

$bits  &= $mask;       # AND-assign
$flags |= 0x01;        # OR-assign  (set bit)
$x     ^= $y;          # XOR-assign (toggle bits where $y is 1)
$x   <<= 1;            # multiply-by-2 (with overflow caveats)
$x   >>= 1;            # divide-by-2 (toward -∞ for signed values)

Ολισθήσεις#

Ο << ολισθαίνει αριστερά· ο >> ολισθαίνει δεξιά. Ο αριθμός θέσεων bit προς ολίσθηση είναι ο δεξιός τελεστέος. Η ολίσθηση κατά αρνητικό ποσό, ή κατά ποσό ίσο ή μεγαλύτερο του πλάτους bit του ακεραίου, είναι ορισμένη από την υλοποίηση - μη βασίζεστε σε αυτό.

Για μη προσημασμένη αριθμητική, η αριστερή ολίσθηση είναι πολλαπλασιασμός με 2 ** $n (modulo υπερχείλιση):

$x << 1               # like $x * 2
$x << 8               # like $x * 256

Για μη προσημασμένη αριθμητική, η δεξιά ολίσθηση είναι ακέραια διαίρεση με 2 ** $n:

$x >> 1               # like int($x / 2)   (for non-negative $x)
$x >> 8               # like int($x / 256)

Για προσημασμένες τιμές, ο >> είναι ορισμένος από την υλοποίηση - η Perl δεν εγγυάται αριθμητική έναντι λογικής ολίσθησης. Εφαρμόστε μάσκα ρητά όταν έχει σημασία το πρόσημο:

($x >> 8) & 0xFF      # extract a byte at offset 8, regardless of sign

Αριθμητική έναντι bytewise λειτουργία#

Οι τελεστές κατά bit της Perl δρουν σε ακεραίους από προεπιλογή. Με use feature 'bitwise'use v5.22+), οι μορφές με επίθημα &., |., ^., ~. δρουν σε συμβολοσειρές byte-προς-byte:

use feature 'bitwise';
"\x80" |. "\x01"      # "\x81"  -- single-byte string OR
"abc"  ^. "abc"       # "\0\0\0" -- bytewise XOR

Οι χωρίς διακόσμηση τελεστές &, |, ^, ~ κάνουν πάντα ακέραια αριθμητική, και οι τελεστέοι συμβολοσειράς εξαναγκάζονται πρώτα σε αριθμούς. Οι μορφές με επίθημα . είναι ο τρόπος να ζητήσετε ρητά πράξεις σε συμβολοσειρές byte.

Ανταλλαγή XOR#

Η XOR έχει δύο ιδιότητες - a a = 0 και a b b = a - που συνδυάζονται στο γνωστό τέχνασμα ανταλλαγής χωρίς προσωρινή μεταβλητή:

my ($a, $b) = (0xFEED, 0xBEEF);

$a ^= $b;             # a := a ⊕ b
$b ^= $a;             # b := b ⊕ (a ⊕ b)  = a
$a ^= $b;             # a := (a ⊕ b) ⊕ a  = b

# $a == 0xBEEF, $b == 0xFEED

Δεν είναι ταχύτερο από ($a, $b) = ($b, $a) στην Perl. Αξίζει να γνωρίζετε επειδή εμφανίζεται σε φολκλόρ συνεντεύξεων και ενσωματωμένο κώδικα, και επειδή είναι καθαρή απεικόνιση της ταυτότητας XOR.

Συνηθισμένα τεχνάσματα bit#

Μοτίβα που θα δείτε σε κώδικα ευαίσθητο στην απόδοση:

$x &  ($x - 1)            # $x with its lowest set bit cleared
($x & ($x - 1)) == 0      # true when $x is a power of two (and non-zero)
1 << $n                   # the integer with only bit $n set
$x & (1 << $n)            # is bit $n set in $x?
$x | (1 << $n)            # set bit $n
$x & ~(1 << $n)           # clear bit $n
$x ^ (1 << $n)            # toggle bit $n
($x >> $n) & 0xFF         # extract a byte at offset $n

Καθένα είναι μια άσκηση στην παρακολούθηση τι κάνει κάθε bit - καθαρή λογική συλλογιστική εφαρμοσμένη 32 (ή 64) φορές παράλληλα.

Παραπομπή σε οδηγό#

Ο οδηγός λογικής τιμών έχει εκτενέστερη αντιμετώπιση του μοντέλου bitwise-ως-παράλληλη-λογική και των παραπάνω μοτίβων εφαρμογής:

Δείτε επίσης#

  • Logical - οι ίδιοι λογικοί τελεστές σε ολόκληρες τιμές.

  • Precedence - οι &, |, ^ βρίσκονται μεταξύ σύγκρισης και &&/||. Σχεδόν πάντα βάζετε παρενθέσεις γύρω τους.

  • pack, unpack, vec - εργαλεία perlfunc για εργασία σε επίπεδο bit πέρα από αυτά που προσφέρουν οι ωμοί τελεστές.