Bitové operace na 64 bitech

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

Ve výpočtu Google Toolbar PageRanku se vedle sebe provádí aritmetické i bitové operace a spoléhá se na to, že celé číslo v PHP zabere 32 bitů. To ale bohužel není pravda, protože velikost čísla je v PHP stejně jako třeba v C závislá na platformě. Na 64bitových procesorech tedy výpočty nesouhlasí a vzhledem k tomu, že v PHP nelze explicitně vytvořit proměnnou typu 32bitové číslo, je potřeba se do problematiky ponořit trochu hlouběji.

Pokud při aritmetické operaci dojde k překročení maximální velikosti 32bitového čísla, je situace poměrně jednoduchá – stačí v čísle nechat spodních 32 bitů, což se provede např. bitovým součinem s 0xFFFFFFFF.

Horší je situace při opačném převodu, tady už potřebujeme vědět, co jednotlivé bity v čísle reprezentují. Nejdůležitější informace je, že vrchní bit reprezentuje znaménko – pokud tedy zjistíme, že je 32. bit nastaven, musíme z hodnoty vytvořit záporné číslo nastavením všech jeho bitů na pozici vyšší než 32. To můžeme provést logickým součtem s ~0xFFFFFFFF.

<?php
function arit2bit($a) {
    return $a & 0xFFFFFFFF;
}

function bit2arit($a) {
    return ($a & 0x80000000 ? $a | ~0xFFFFFFFF : $a);
}
?>

Stejný problém má mimochodem i Google Toolbar v 64bitovém Firefoxu.

Jakub Vrána, Výuka, 15.9.2006, diskuse: 3 (nové: 0)

Diskuse

MazeGen:

Nevím jak v PHP, ale třeba v assembleru a C je zvykem číslovat bity od nuly, tzn. znaménkový (nejvyšší) bit v 32bitovém čísle je bit číslo 31.

thingwath:

Bit číslo 31 je 32. v pořadí :-) Nultý jako řadová číslovka se mi moc nezdá.

Farin:

zdat se ti to nemusi ale dobry duvod to ma, nebot bity reprezentuji mocniny 2 a zacina se 2^0 a konci 2^31, od toho cislovani od nuly

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.