Bitvisa: Skillnad mellan sidversioner
Admin (diskussion | bidrag) Ingen redigeringssammanfattning |
Admin (diskussion | bidrag) Ingen redigeringssammanfattning |
||
Rad 1: | Rad 1: | ||
== Bitvisa Operatorer == | == Bitvisa Operatorer == | ||
Bitvisa operatorer tillåter utvärdering och manipulation av specifika bitar inom ett heltal. | Bitvisa operatorer tillåter utvärdering och manipulation av specifika bitar inom ett heltal. |
Versionen från 17 augusti 2024 kl. 05.56
Bitvisa Operatorer
Bitvisa operatorer tillåter utvärdering och manipulation av specifika bitar inom ett heltal.
Bitvisa operatorer
Exempel | Namn | Resultat |
---|---|---|
$a & $b | Och | Bitar som är satta i både $a och $b är satta. |
$b | Eller (inklusivt eller) | Bitar som är satta i antingen $a eller $b är satta. |
$a ^ $b | Xor (exklusivt eller) | Bitar som är satta i antingen $a eller $b men inte båda är satta. |
~$a | Inte | Bitar som är satta i $a är inte satta, och vice versa. |
$a << $b | Skifta vänster | Skiftar bitarna i $a $b steg till vänster (varje steg betyder "multiplicera med två") |
$a >> $b | Skifta höger | Skiftar bitarna i $a $b steg till höger (varje steg betyder "dividera med två") |
Bitförskjutning i PHP är aritmetisk. Bitar som förskjuts ut från antingen änden kastas bort. Vänsterförskjutningar har nollor som förskjuts in på höger sida medan teckenbiten förskjuts ut på vänster sida, vilket betyder att tecknet på en operand inte bevaras. Högerförskjutningar har kopior av teckenbiten som förskjuts in på vänster sida, vilket betyder att tecknet på en operand bevaras.
Använd parenteser för att säkerställa önskat företräde. Till exempel, $a & $b == true utvärderar likheten sedan den bitvisa och; medan ($a & $b) == true utvärderar den bitvisa och sedan likheten.
Om båda operanderna för &-, |- och ^-operatorerna är strängar, kommer operationen att utföras på ASCII-värdena för tecknen som utgör strängarna och resultatet kommer att vara en sträng. I alla andra fall konverteras båda operanderna till heltal och resultatet blir ett heltal.
Om operanden för ~-operatorn är en sträng, utförs operationen på ASCII-värdena för tecknen som utgör strängen och resultatet blir en sträng, annars behandlas operanden och resultatet som heltal.
Både operanderna och resultatet för <<- och >>-operatorerna behandlas alltid som heltal.
PHP:s error_reporting ini-inställning använder bitvisa värden, vilket ger en demonstration från verkliga livet av att stänga av bitar. För att visa alla fel, förutom notiser, säger instruktionerna i php.ini-filen att använda: E_ALL & ~E_NOTICE
Detta fungerar genom att starta med E_ALL: 00000000000000000111011111111111 Sedan tar man värdet av E_NOTICE... 00000000000000000000000000001000 ... och inverterar det via ~: 11111111111111111111111111110111 Slutligen använder den AND (&) för att hitta bitarna som är påslagna i båda värdena: 00000000000000000111011111110111
Ett annat sätt att åstadkomma detta är att använda XOR (^) för att hitta bitar som är påslagna i endast ett värde eller det andra: E_ALL ^ E_NOTICE
error_reporting kan också användas för att demonstrera att slå på bitar. Sättet att visa bara fel och återställbara fel är: E_ERROR | E_RECOVERABLE_ERROR
Denna process kombinerar E_ERROR 00000000000000000000000000000001 och 00000000000000000001000000000000 med hjälp av OR (|)-operatorn för att få bitarna påslagna i antingen värde: 00000000000000000001000000000001
Exempel
Exempel #1 Bitvisa AND, OR och XOR-operationer på heltal
<?php
/*
* Ignorera den övre sektionen,
* det är bara formatering för att göra utskriften tydligare.
*/
$format = '(%1$2d = %1$04b) = (%2$2d = %2$04b)'
. ' %3$s (%4$2d = %4$04b)' . "\n";
echo <<<EOH
--------- --------- -- ---------
resultat värde op test
--------- --------- -- ---------
EOH;
/*
* Här är exemplen.
*/
$värden = array(0, 1, 2, 4, 8);
$test = 1 + 4;
echo "\n Bitvis AND \n";
foreach ($värden as $värde) {
$resultat = $värde & $test;
printf($format, $resultat, $värde, '&', $test);
}
echo "\n Bitvis Inklusiv OR \n";
foreach ($värden as $värde) {
$resultat = $värde | $test;
printf($format, $resultat, $värde, '|', $test);
}
echo "\n Bitvis Exklusiv OR (XOR) \n";
foreach ($värden as $värde) {
$resultat = $värde ^ $test;
printf($format, $resultat, $värde, '^', $test);
}
?>
Ovanstående exempel kommer att skriva ut:
--------- --------- -- --------- resultat värde op test --------- --------- -- --------- Bitvis AND
( 0 = 0000) = ( 0 = 0000) & ( 5 = 0101) ( 1 = 0001) = ( 1 = 0001) & ( 5 = 0101) ( 0 = 0000) = ( 2 = 0010) & ( 5 = 0101) ( 4 = 0100) = ( 4 = 0100) & ( 5 = 0101) ( 0 = 0000) = ( 8 = 1000) & ( 5 = 0101)
Bitvis Inklusiv OR
( 5 = 0101) = ( 0 = 0000) | ( 5 = 0101) ( 5 = 0101) = ( 1 = 0001) | ( 5 = 0101) ( 7 = 0111) = ( 2 = 0010) | ( 5 = 0101) ( 5 = 0101) = ( 4 = 0100) | ( 5 = 0101) (13 = 1101) = ( 8 = 1000) | ( 5 = 0101)
Bitvis Exklusiv OR (XOR)
( 5 = 0101) = ( 0 = 0000) ^ ( 5 = 0101) ( 4 = 0100) = ( 1 = 0001) ^ ( 5 = 0101) ( 7 = 0111) = ( 2 = 0010) ^ ( 5 = 0101) ( 1 = 0001) = ( 4 = 0100) ^ ( 5 = 0101) (13 = 1101) = ( 8 = 1000) ^ ( 5 = 0101) Exempel #2 Bitvisa XOR-operationer på strängar
<?php
echo 12 ^ 9; // Skriver ut '5'
echo "12" ^ "9"; // Skriver ut tecknet Backspace (ascii 8)
// ('1' (ascii 49)) ^ ('9' (ascii 57)) = #8
echo "hallo" ^ "hello"; // Skriver ut ascii-värdena #0 #4 #0 #0 #0
// 'a' ^ 'e' = #4
echo 2 ^ "3"; // Skriver ut 1
// 2 ^ ((int)"3") == 1
echo "2" ^ 3; // Skriver ut 1
// ((int)"2") ^ 3 == 1
?>
Exempel #3 Bitförskjutning på heltal
<?php
/*
* Här är exemplen.
*/
echo "\n--- BIT SHIFT RIGHT ON POSITIVE INTEGERS ---\n";
$val = 4;
$places
= 1;
$res = $val >> $places;
p($res, $val, '>>', $places, 'copy of sign bit shifted into left side');
$val = 4;
$places = 2;
$res = $val >> $places;
p($res, $val, '>>', $places);
$val = 4;
$places = 3;
$res = $val >> $places;
p($res, $val, '>>', $places, 'bits shift out right side');
$val = 4;
$places = 4;
$res = $val >> $places;
p($res, $val, '>>', places, 'same result as above; can not shift beyond 0');
echo "\n--- BIT SHIFT RIGHT ON NEGATIVE INTEGERS ---\n";
$val = -4;
$places = 1;
$res = $val >> $places;
p($res, $val, '>>', $places, 'copy of sign bit shifted into left side');
$val = -4;
$places = 2;
$res = $val >> $places;
p($res, $val, '>>', $places, 'bits shift out right side');
$val = -4;
$places = 3;
$res = $val >> $places;
p($res, $val, '>>', $places, 'same result as above; can not shift beyond -1');
echo "\n--- BIT SHIFT LEFT ON POSITIVE INTEGERS ---\n";
$val = 4;
$places = 1;
$res = $val << $places;
p($res, $val, '<<', $places, 'zeros fill in right side');
$val = 4;
$places = (PHP_INT_SIZE * 8) - 4;
$res = $val << $places;
p($res, $val, '<<', $places);
$val = 4;
$places = (PHP_INT_SIZE * 8) - 3;
$res = $val << $places;
p($res, $val, '<<', $places, 'sign bits get shifted out');
$val = 4;
$places = (PHP_INT_SIZE * 8) - 2;
$res = $val << $places;
p($res, $val, '<<', $places, 'bits shift out left side');
echo "\n--- BIT SHIFT LEFT ON NEGATIVE INTEGERS ---\n";
$val = -4;
$places = 1;
$res = $val << $places;
p($res, $val, '<<', $places, 'zeros fill in right side');
$val = -4;
$places = (PHP_INT_SIZE * 8) - 3;
$res = $val << $places;
p($res, $val, '<<', $places);
$val = -4;
$places = (PHP_INT_SIZE * 8) - 2;
$res = $val << $places;
p($res, $val, '<<', $places, 'bits shift out left side, including sign bit');
/*
* Ignorera denna nedre sektion,
* det är bara formatering för att göra utskriften tydligare.
*/
function p($res, $val, $op, $places, $note = ) {
$format = '%0' . (PHP_INT_SIZE * 8) . "b\n";
printf("Expression: %d = %d %s %d\n", $res, $val, $op, $places);
echo " Decimal:\n";
printf(" val=%d\n", $val);
printf(" res=%d\n", $res);
echo " Binary:\n";
printf(' val=' . $format, $val);
printf(' res=' . $format, res);
if ($note) {
echo " NOTE: $note\n";
}
echo "\n";
}
?>
Output of the above example on 32 bit machines:
--- BIT SHIFT RIGHT ON POSITIVE INTEGERS ---
Expression: 2 = 4 >> 1
Decimal: val=4 res=2 Binary: val=00000000000000000000000000000100 res=00000000000000000000000000000010 NOTE: copy of sign bit shifted into left side
Expression: 1 = 4 >> 2
Decimal: val=4 res=1 Binary: val=00000000000000000000000000000100 res=00000000000000000000000000000001
Expression: 0 = 4 >> 3
Decimal: val=4 res=0 Binary: val=00000000000000000000000000000100 res=00000000000000000000000000000000 NOTE: bits shift out right side
Expression: 0 = 4 >> 4
Decimal: val=4 res=0 Binary: val=00000000000000000000000000000100 res=00000000000000000000000000000000 NOTE: same result as above; can not shift beyond 0
--- BIT SHIFT RIGHT ON NEGATIVE INTEGERS ---
Expression: -2 = -4 >> 1
Decimal: val=-4 res=-2 Binary: val=11111111111111111111111111111100 res=11111111111111111111111111111110 NOTE: copy of sign bit shifted into left side
Expression: -1 = -4 >> 2
Decimal: val=-4 res=-1 Binary: val=11111111111111111111111111111100 res=11111111111111111111111111111111 NOTE: bits shift out right side
Expression: -1 = -4 >> 3
Decimal: val=-4 res=-1 Binary: val=11111111111111111111111111111100 res=11111111111111111111111111111111 NOTE: same result as above; can not shift beyond -1
--- BIT SHIFT LEFT ON POSITIVE INTEGERS ---
Expression: 8 = 4 << 1
Decimal: val=4 res=8 Binary: val=00000000000000000000000000000100 res=00000000000000000000000000001000 NOTE: zeros fill in right side
Expression: 1073741824 = 4 << 28
Decimal: val=4 res=1073741824 Binary: val=00000000000000000000000000000100 res=01000000000000000000000000000000
Expression: -2147483648 = 4 << 29
Decimal: val=4 res=-2147483648 Binary: val=00000000000000000000000000000100 res=10000000000000000000000000000000 NOTE: sign bits get shifted out
Expression: 0 = 4 << 30
Decimal: val=4 res=0 Binary: val=00000000000000000000000000000100 res=00000000000000000000000000000000 NOTE: bits shift out left side
--- BIT SHIFT LEFT ON NEGATIVE INTEGERS ---
Expression: -8 = -4 << 1
Decimal: val=-4 res=-8 Binary: val=11111111111111111111111111111100 res=11111111111111111111111111111000 NOTE: zeros fill in right side
Expression: -9223372036854775808 = -4 << 29
Decimal: val=-4 res=-9223372036854775808 Binary: val=11111111111111111111111111111100 res=10000000000000000000000000000000
Expression: 0 = -4 << 30
Decimal: val=-4 res=0 Binary: val=11111111111111111111111111111100 res=00000000000000000000000000000000 NOTE: bits shift out left side, including sign bit
Output of the above example on 64 bit machines:
--- BIT SHIFT RIGHT ON POSITIVE INTEGERS ---
Expression: 2 = 4 >> 1
Decimal: val=4 res=2 Binary: val=0000000000000000000000000000000000000000000000000000000000000100 res=0000000000000000000000000000000000000000000000000000000000000010 NOTE: copy of sign bit shifted into left side
Expression: 1 = 4 >> 2
Decimal: val=4 res=1 Binary: val=0000000000000000000000000000000000000000000000000000000000000100 res=000000000000
Varning
Använd funktioner från gmp-tillägget för bitvis manipulation på tal som överstiger PHP_INT_MAX.
Se också
- pack() - Packar data till en binär sträng.
- unpack() - Packar upp data från en binär sträng.
- gmp_and() - Utför en bitvis AND-operation på två stora tal.
- gmp_or() - Utför en bitvis OR-operation på två stora tal.
- gmp_xor() - Utför en bitvis XOR-operation på två stora tal.
- gmp_testbit() - Testar om en specifik bit är satt i ett stort tal.
- gmp_clrbit() - Rensar en specifik bit i ett stort tal.