Bitové operace

Školení, která pořádám

Poměrně málo známou a často zcela opomíjenou schopností PHP jsou bitové operace. Ty slouží k manipulaci s čísly (a trochu netradičně také s řetězci) na úrovni jednotlivých bitů. Co jednotlivé operace představují zachycuje následující tabulka:

$a$b$a | $b$a & $b$a ^ $b~ $a
000001
011011
101010
111100

Operace se provádějí na vzájemně si odpovídajících bitech, takže např. 6 | 10 = 14 (binárně 0110 | 1010 = 1110).

V PHP se bitové operace používají nejčastěji při předávání parametrů funkcím a při nastavování konfiguračních direktiv v kombinaci s konstantami. Asi nejčastěji se používají u funkce a direktivy error_reporting. Pro sloučení více hodnot se někdy nesprávně používá operátor +, který se stejně jako | chová pouze v případě, že spojované hodnoty nemají nastavené stejné bity, navíc je o něco pomalejší.

Na uživatelské úrovni se v PHP pro předávání sady parametrů obvykle používá více proměnných nebo pole, ale i bitové operace mohou v některých případech stále dobře posloužit:

<?php
define("OPTION_A", 1);
define("OPTION_B", 2);
define("OPTION_C", 4);
define("OPTION_ALL", OPTION_A | OPTION_B | OPTION_C);

function bit_options($options) {
    $return = "";
    if ($options & OPTION_A) {
        $return .= "a";
    }
    if ($options & OPTION_B) {
        $return .= "b";
    }
    if ($options & OPTION_C) {
        $return .= "c";
    }
    return $return;
}
echo bit_options(OPTION_ALL & ~OPTION_B) . "\n";
?>

Bitové operace samozřejmě nejsou žádnou výsadou PHP, např. v MySQL je používám hlavně při práci se sloupci typu set, pro což se dá ovšem použít i funkce FIND_IN_SET.

Nejintenzivněji jsem bitové operátory v poslední době použil u alternativních cen hotelů. Jde o to, že hotel používá dvoje ceny pro různé dny v týdnu. Které dny to jsou, jsem si uložil do datového typu set('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'). Pro následné zjištění informace o tom, která cena se má použít, jsem vytvořil následující kód:

<?php
$alternativni_ceny = mysql_result(mysql_query("SELECT 1*alternativni_ceny FROM hotely WHERE id = $id"), 0);
$cena = ((1 << date("w")) & $alternativni_ceny ? $alternativni_cena : $cena);
?>

Konstrukce 1*alternativni_ceny z datového typu set vytvoří číslo s bity nastavenými podle pořadí hodnot nastavených v množině. Operátor << je bitový posun, konstrukce 1 << date("w") tedy vytvoří číslo s bitem nastaveným podle aktuálního dne v týdnu. Logický součin s dříve získanou hodnotou potom zjistí, zda den spadá do období alternativních nebo normálních cen.

Jakub Vrána, Výuka, 23.6.2006, diskuse: 2 (nové: 0)

Diskuse

@ss@ssIn:

Vdaka Jakube, som si ujasnil par veci, ktore mi neboli celkom jasne...

P.s.: Blowfish algoritmus [pouziva ho aj phpMyAdmin] tiez pracuje iba s bitmi a hlavne s operaciu XOR :))

Martin Kopta:

Ideální na práci s bitovými maskami pro ukládání předvoleb do bitového barrelu.

Diskuse je zrušena z důvodu spamu.

avatar © 2005-2024 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.