LINUX.ORG.RU

Битовые сдвиги в php


0

0

<?php
$x=ip2long("192.168.50.1");
echo $x."\n";
echo sprintf("%X\n", $x);
echo sprintf("%X",$x).">>8=".sprintf("%X\n", $x>>8);
echo sprintf("%X",$x).">>16=".sprintf("%X\n", $x>>16);
echo sprintf("%X",$x).">>24=".sprintf("%X\n", $x>>24);
echo sprintf("%X",$x).">>32=".sprintf("%X\n", $x>>32);
echo sprintf("%X",$x)."<<8=".sprintf("%X\n", $x<<8);
echo sprintf("%X",$x)."<<16=".sprintf("%X\n", $x<<16);
echo sprintf("%X",$x)."<<24=".sprintf("%X\n", $x<<24);
echo sprintf("%X",$x)."<<32=".sprintf("%X\n", $x<<32);
?>
запускаю и получаю:
-1062718975
C0A83201
C0A83201>>8=FFC0A832
C0A83201>>16=FFFFC0A8
C0A83201>>24=FFFFFFC0
C0A83201>>32=C0A83201
C0A83201<<8=A8320100
C0A83201<<16=32010000
C0A83201<<24=1000000
C0A83201<<32=C0A83201

Откуда взялись "FF" при сдвиге вправо, и почему неправильно работает сдвиг влево??? Я понимаю что это связано с отсутствием беззнаковых типов, но объяснить почему именно так работает не могу..

Ну при сдвиге вправо произошло знакорасширение. Если сдвигать что-то со старшим битом равным нулю, то все будет ок. Влево вроде все правильно, кроме 32, но это уже от реализации зависит.

А что в PHP нет беззнаковых типов???

alexru ★★★★
()

До меня дошло :).
выражения типа $x<<$n в php вычисляются как
$x*settype(pow(2,$n),"integer"), а $x<<$n в php вычисляются как
$x/settype(pow(2,$n),"integer"), тогда всё сходится :).
Вообще как-то тупо..

TaranSergey
() автор топика
Ответ на: комментарий от TaranSergey

В исходниках php написан обычный сдвиг двух long-ов.
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_operators.c?revision=1.208.2.5...
см. функции shift_left_function и shift_right_function
Согласно "Intel&#174; 64 and IA-32 Architectures
Software Developer&#8217;s Manual" на инструкции битового сдвига.
--cut--
The count operand
can be an immediate value or the CL register. The count is masked to 5 bits (or 6 bits
if in 64-bit mode and REX.W is used). The count range is limited to 0 to 31 (or 63 if
64-bit mode and REX.W is used).
--cut--
поэтому сдвиг на 32 в 32-битном режиме эквивалентен сдвигу на 0, т.е. исходное число не изменяется.

cobold ★★★★★
()
Ответ на: комментарий от cobold

По поводу сдвига на 32 теперь понятно, но откуда берутся FF я так и не понял. А то что можно перейти на 64-ю платформу я понимаю, меня просто интересовало, почему так происходит.

TaranSergey
() автор топика
Ответ на: комментарий от TaranSergey

Всё понял по поводу FF. Стындо за глупость :).

TaranSergey
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.