Bitwise operators allow evaluation and manipulation of specific bits within an integer. ... Example #1 Bitwise AND, OR and XOR operations on integers. >$b
Shiftright
Shiftthebitsof$a$bstepstotheright(eachstepmeans
"dividebytwo")
BitshiftinginPHPisarithmetic.
Bitsshiftedoffeitherendarediscarded.
Leftshiftshavezerosshiftedinontherightwhilethesign
bitisshiftedoutontheleft,meaningthesignofanoperand
isnotpreserved.
Rightshiftshavecopiesofthesignbitshiftedinontheleft,
meaningthesignofanoperandispreserved.
Useparenthesestoensurethedesired
precedence.
Forexample,$a&$b==trueevaluates
theequivalencythenthebitwiseand;while
($a&$b)==trueevaluatesthebitwiseand
thentheequivalency.
Ifbothoperandsforthe&,|and
^operatorsarestrings,thentheoperationwillbe
performedontheASCIIvaluesofthecharactersthatmakeupthestringsand
theresultwillbeastring.Inallothercases,bothoperandswillbe
convertedtointegers
andtheresultwillbeaninteger.
Iftheoperandforthe~operatorisastring,the
operationwillbeperformedontheASCIIvaluesofthecharactersthatmake
upthestringandtheresultwillbeastring,otherwisetheoperandandthe
resultwillbetreatedasintegers.
Bothoperandsandtheresultforthe<>operatorsarealwaystreatedasintegers.
PHP'serror_reportinginisettingusesbitwisevalues,
providingareal-worlddemonstrationofturning
bitsoff.Toshowallerrors,exceptfornotices,
thephp.inifileinstructionssaytouse:
E_ALL&~E_NOTICE
ThisworksbystartingwithE_ALL:
00000000000000000111011111111111
ThentakingthevalueofE_NOTICE...
00000000000000000000000000001000
...andinvertingitvia~:
11111111111111111111111111110111
Finally,itusesAND(&)tofindthebitsturned
oninbothvalues:
00000000000000000111011111110111
AnotherwaytoaccomplishthatisusingXOR(^)
tofindbitsthatareoninonlyonevalueortheother:
E_ALL^E_NOTICE
error_reportingcanalsobeusedtodemonstrateturningbitson.
Thewaytoshowjusterrorsandrecoverableerrorsis:
E_ERROR|E_RECOVERABLE_ERROR
ThisprocesscombinesE_ERROR
00000000000000000000000000000001
and
00000000000000000001000000000000
usingtheOR(|)operator
togetthebitsturnedonineithervalue:
00000000000000000001000000000001
Example#1BitwiseAND,ORandXORoperationsonintegers
Theaboveexamplewilloutput:
-----------------------------
resultvalueoptest
-----------------------------
BitwiseAND
(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)
BitwiseInclusiveOR
(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)
BitwiseExclusiveOR(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)
Example#2BitwiseXORoperationsonstrings
Example#3Bitshiftingonintegers
> $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 <
Outputoftheaboveexampleon32bitmachines:
---BITSHIFTRIGHTONPOSITIVEINTEGERS---
Expression:2=4>>1
Decimal:
val=4
res=2
Binary:
val=00000000000000000000000000000100
res=00000000000000000000000000000010
NOTE:copyofsignbitshiftedintoleftside
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:bitsshiftoutrightside
Expression:0=4>>4
Decimal:
val=4
res=0
Binary:
val=00000000000000000000000000000100
res=00000000000000000000000000000000
NOTE:sameresultasabove;cannotshiftbeyond0
---BITSHIFTRIGHTONNEGATIVEINTEGERS---
Expression:-2=-4>>1
Decimal:
val=-4
res=-2
Binary:
val=11111111111111111111111111111100
res=11111111111111111111111111111110
NOTE:copyofsignbitshiftedintoleftside
Expression:-1=-4>>2
Decimal:
val=-4
res=-1
Binary:
val=11111111111111111111111111111100
res=11111111111111111111111111111111
NOTE:bitsshiftoutrightside
Expression:-1=-4>>3
Decimal:
val=-4
res=-1
Binary:
val=11111111111111111111111111111100
res=11111111111111111111111111111111
NOTE:sameresultasabove;cannotshiftbeyond-1
---BITSHIFTLEFTONPOSITIVEINTEGERS---
Expression:8=4<<1
Decimal:
val=4
res=8
Binary:
val=00000000000000000000000000000100
res=00000000000000000000000000001000
NOTE:zerosfillinrightside
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:signbitsgetshiftedout
Expression:0=4<<30
Decimal:
val=4
res=0
Binary:
val=00000000000000000000000000000100
res=00000000000000000000000000000000
NOTE:bitsshiftoutleftside
---BITSHIFTLEFTONNEGATIVEINTEGERS---
Expression:-8=-4<<1
Decimal:
val=-4
res=-8
Binary:
val=11111111111111111111111111111100
res=11111111111111111111111111111000
NOTE:zerosfillinrightside
Expression:-2147483648=-4<<29
Decimal:
val=-4
res=-2147483648
Binary:
val=11111111111111111111111111111100
res=10000000000000000000000000000000
Expression:0=-4<<30
Decimal:
val=-4
res=0
Binary:
val=11111111111111111111111111111100
res=00000000000000000000000000000000
NOTE:bitsshiftoutleftside,includingsignbit
Outputoftheaboveexampleon64bitmachines:
---BITSHIFTRIGHTONPOSITIVEINTEGERS---
Expression:2=4>>1
Decimal:
val=4
res=2
Binary:
val=0000000000000000000000000000000000000000000000000000000000000100
res=0000000000000000000000000000000000000000000000000000000000000010
NOTE:copyofsignbitshiftedintoleftside
Expression:1=4>>2
Decimal:
val=4
res=1
Binary:
val=0000000000000000000000000000000000000000000000000000000000000100
res=0000000000000000000000000000000000000000000000000000000000000001
Expression:0=4>>3
Decimal:
val=4
res=0
Binary:
val=0000000000000000000000000000000000000000000000000000000000000100
res=0000000000000000000000000000000000000000000000000000000000000000
NOTE:bitsshiftoutrightside
Expression:0=4>>4
Decimal:
val=4
res=0
Binary:
val=0000000000000000000000000000000000000000000000000000000000000100
res=0000000000000000000000000000000000000000000000000000000000000000
NOTE:sameresultasabove;cannotshiftbeyond0
---BITSHIFTRIGHTONNEGATIVEINTEGERS---
Expression:-2=-4>>1
Decimal:
val=-4
res=-2
Binary:
val=1111111111111111111111111111111111111111111111111111111111111100
res=1111111111111111111111111111111111111111111111111111111111111110
NOTE:copyofsignbitshiftedintoleftside
Expression:-1=-4>>2
Decimal:
val=-4
res=-1
Binary:
val=1111111111111111111111111111111111111111111111111111111111111100
res=1111111111111111111111111111111111111111111111111111111111111111
NOTE:bitsshiftoutrightside
Expression:-1=-4>>3
Decimal:
val=-4
res=-1
Binary:
val=1111111111111111111111111111111111111111111111111111111111111100
res=1111111111111111111111111111111111111111111111111111111111111111
NOTE:sameresultasabove;cannotshiftbeyond-1
---BITSHIFTLEFTONPOSITIVEINTEGERS---
Expression:8=4<<1
Decimal:
val=4
res=8
Binary:
val=0000000000000000000000000000000000000000000000000000000000000100
res=0000000000000000000000000000000000000000000000000000000000001000
NOTE:zerosfillinrightside
Expression:4611686018427387904=4<<60
Decimal:
val=4
res=4611686018427387904
Binary:
val=0000000000000000000000000000000000000000000000000000000000000100
res=0100000000000000000000000000000000000000000000000000000000000000
Expression:-9223372036854775808=4<<61
Decimal:
val=4
res=-9223372036854775808
Binary:
val=0000000000000000000000000000000000000000000000000000000000000100
res=1000000000000000000000000000000000000000000000000000000000000000
NOTE:signbitsgetshiftedout
Expression:0=4<<62
Decimal:
val=4
res=0
Binary:
val=0000000000000000000000000000000000000000000000000000000000000100
res=0000000000000000000000000000000000000000000000000000000000000000
NOTE:bitsshiftoutleftside
---BITSHIFTLEFTONNEGATIVEINTEGERS---
Expression:-8=-4<<1
Decimal:
val=-4
res=-8
Binary:
val=1111111111111111111111111111111111111111111111111111111111111100
res=1111111111111111111111111111111111111111111111111111111111111000
NOTE:zerosfillinrightside
Expression:-9223372036854775808=-4<<61
Decimal:
val=-4
res=-9223372036854775808
Binary:
val=1111111111111111111111111111111111111111111111111111111111111100
res=1000000000000000000000000000000000000000000000000000000000000000
Expression:0=-4<<62
Decimal:
val=-4
res=0
Binary:
val=1111111111111111111111111111111111111111111111111111111111111100
res=0000000000000000000000000000000000000000000000000000000000000000
NOTE:bitsshiftoutleftside,includingsignbit
Warning
Usefunctionsfromthegmpextensionfor
bitwisemanipulationonnumbersbeyondPHP_INT_MAX.
SeeAlso
pack()
unpack()
gmp_and()
gmp_or()
gmp_xor()
gmp_testbit()
gmp_clrbit()
up
down
112
wbcartsatjunodotcom¶10yearsago
BITWISEFLAGSforCustomPHPObjectsSometimesIneedacustomPHPObjectthatholdsseveralbooleanTRUEorFALSEvalues.Icouldeasilyincludeavariableforeachofthem,butasalways,codehasawaytogetunweildyprettyfast.Amoreintelligentapproachalwaysseemstobetheanswer,evenifitseemstobeoverkillatfirst.Istartwithanabstractbaseclasswhichwillholdasingleintegervariablecalled$flags.Thissimpleintegercanhold32TRUEorFALSEbooleanvalues.AnotherthingtoconsideristojustsetcertainBITvalueswithoutdisturbinganyoftheotherBITS--soincludedintheclassdefinitionisthesetFlag($flag,$value)function,whichwillsetonlythechosenbit.Here'stheabstractbaseclassdefinition:flags&$flag)==$flag); } protectedfunctionsetFlag($flag,$value) { if($value) { $this->flags|=$flag; } else { $this->flags&=~$flag; } }}?>Theclassaboveisabstractandcannotbeinstantiated,soanextensionisrequired.BelowisasimpleextensioncalledUser--whichisseverelytruncatedforclarity.NoticeIamdefiningconstvariablesANDmethodstousethem.isFlagSet(self::FLAG_REGISTERED); } publicfunctionisActive(){ return$this->isFlagSet(self::FLAG_ACTIVE); } publicfunctionisMember(){ return$this->isFlagSet(self::FLAG_MEMBER); } publicfunctionisAdmin(){ return$this->isFlagSet(self::FLAG_ADMIN); } publicfunctionsetRegistered($value){ $this->setFlag(self::FLAG_REGISTERED,$value); } publicfunctionsetActive($value){ $this->setFlag(self::FLAG_ACTIVE,$value); } publicfunctionsetMember($value){ $this->setFlag(self::FLAG_MEMBER,$value); } publicfunctionsetAdmin($value){ $this->setFlag(self::FLAG_ADMIN,$value); } publicfunction__toString(){ return'User['. ($this->isRegistered()?'REGISTERED':''). ($this->isActive()?'ACTIVE':''). ($this->isMember()?'MEMBER':''). ($this->isAdmin()?'ADMIN':''). ']'; }}?>Thisseemslikealotofwork,butwehaveaddressedmanyissues,forexample,usingandmaintainingthecodeiseasy,andthegettingandsettingofflagvaluesmakesense.WiththeUserclass,youcannowseehoweasyandintuitivebitwiseflagoperationsbecome.setRegistered(true);$user->setActive(true);$user->setMember(true);$user->setAdmin(true);echo$user; //outputs:User[REGISTEREDACTIVEMEMBERADMIN]?>
up
down
32
graydadotNOSPAMatDONTSPAMdotsolidincdotorg¶13yearsago
Initially,Ifoundbitmaskingtobeaconfusingconceptandfoundnouseforit.SoI'vewhippedupthiscodesnippetincaseanyoneelseisconfused:Andyoucanapplythistoalotofthings,forexample,security:Onceyougetyourheadaroundit,it'sVERYuseful!Justremembertoraiseeachvaluebythepoweroftwotoavoidproblems
up
down
5
m0shathotmaildotcom¶13yearsago
@greenone-nicefunction,thanks.I'veadapteditforkeyusage:
up
down
13
frankemeks77atyahoodotcom¶9yearsago
JustlearningBitwiseShiftOperators.
Theeasiestwaytoresolveabitwise shiftoperatorsismymultiplyordividingeachstepbytwoforleftshiftorrightshiftrespectively
Example:
LEFTSHIFT
//sameas
RIGHTSHIFT
>3;//1?>
//sameas
//Solvingonapaper8/2=4/2=2/2=1
up
down
8
zlelgrxnslxves13athotmaildotcom~=s/x/ee/g¶16yearsago
IrefertoEricSwanson'spostonPerlVSPHP'simplementationofxor.Actually,thisisnotanissuewiththeimplementationofXOR, butalotmoretodowiththelose-typingpolicythatPHPadopts.Freelyswitchingbetweenintandfloatisgoodformostcases,butproblemshappenwhenyourvalueisnearthewordsizeofyourmachine.Whichistosay,32-bitmachineswillencounterproblemswithvaluesthathoveraround0x80000000-primarilybecausePHPdoesnotsupportunsignedintegers.usingbindec/decbinwouldaddressthisissueasawork-aroundtodounsigned-intxor,buthere'stherealpicture(i'mnotclaimingthatthiscodewillperformbetter,butthiswouldbeabetterpedagogicalcode):Thisisthevaluewewant";echo"
3851262585";echo"
Theresultofanativexoroperationonintegervaluesistreatedasasignedinteger";echo"
".($x^$y);echo"
WethereforeperformtheMSBseparately";echo"
".unsigned_xor32($x,$y);?>Thisisreallyfoundationstuff,butforthoseofyouwhomissedthisincollege,thereseemstobesomethingon2'scomplementhere:http://www.evergreen.edu/biophysics/technotes/program/2s_comp.htm
up
down
14
S?b.¶17yearsago
Abitwiseoperatorspracticalcase:>16; $green=($color&0x00FF00)>>8; $blue=$color&0x0000FF; printf('Red:%X(%d),Green:%X(%d),Blue:%X(%d)', $red,$red,$green,$green,$blue,$blue); //Willdisplay... //Red:FE(254),Green:A9(169),Blue:46(70)?>
up
down
8
zewtathotmaildotcom¶15yearsago
ifyouusebitwiseyouMUSTmakesureyourvariablesareintegers,otherwiseyoucangetincorrectresults.IrecommendALWAYS(int)$var&(int)$var2Thiswillsaveyoumanyheadacheswhentroubleshootingacompletelyillogicalresult.
up
down
6
zoolyatglobmidotcom¶12yearsago
Hereisanexampleforbitwiseleftrotateandrightrotate.Notethatthisfunctionworksonlywithdecimalnumbers-othertypescanbeconvertedwithpack().
up
down
8
Silver¶13yearsago
RegardingwhatBobsaidaboutflags,I'dliketopointoutthere'sa100%safewayofdefiningflags,whichisusinghexadecimalnotationforintegers:IalwaysavoidusingdecimalnotationwhenIhavealargeamountofdifferentflags,becauseit'sveryeasytomisspellnumberslike2^20(1048576).
up
down
6
vivekananddotpathak25atgmaildotcom¶9yearsago
$a= 9;$b= 10;echo$a&$b;placevalue 128 64 32 16 8 4 2 1$a 0 0 0 0 1 0 0 1 =9$b 0 0 0 0 1 0 1 0 =10result 8 onlybittheysharetogetheristhe8bit.So8getsreturned. $a= 36;$b= 103;echo$a&$b;placevalue 128 64 32 16 8 4 2 1$a 0 0 1 0 0 1 0 0 =36$b 0 1 1 0 0 1 1 1 =103result 32+4=36theonlybitsthesetwosharetogetherarethebits32and4whichwhenaddedtogetherreturn36.$a= 9;$b= 10;echo$a|$b;placevalue 128 64 32 16 8 4 2 1$a 0 0 0 0 1 0 0 1 =9$b 0 0 0 0 1 0 1 0 =10result8+2+1=113bitsset,inthe8,2,and1column.addthoseup8+2+1andyouget11$a= 9;$b= 10;echo$a^$b;placevalue 128 64 32 16 8 4 2 1$a 0 0 0 0 1 0 0 1 =9$b 0 0 0 0 1 0 1 0 =10result 2+1=3the2bitandthe1bitthattheyeachhavesetbutdon'tshare.Soooo2+1=3
up
down
1
ASchmidtatAnameradotnet¶2yearsago
Setting,unsettingandtestingsingleandmultiplebitsinabitmask:bitmask[$key]|=1<bitmask[$key]&=~(1<bitmask[$key]) unset($this->bitmask[$key]); } publicfunctiontoggle($bit)//Togglesomebit { $key=(int)($bit/INTEGER_LENGTH); $bit=(int)fmod($bit,INTEGER_LENGTH); $this->bitmask[$key]^=1<bitmask[$key]) unset($this->bitmask[$key]); } publicfunctionread($bit)//Readsomebit { $key=(int)($bit/INTEGER_LENGTH); $bit=(int)fmod($bit,INTEGER_LENGTH); return$this->bitmask[$key]&(1<bitmask=array(); $array=str_split(strrev($string),INTEGER_LENGTH); foreach($arrayas$key=>$value) { if($value=bindec(strrev($value))) $this->bitmask[$key]=$value; } } publicfunctionstringout()//Printoutastringofyournicelittlebits { $string=""; $keys=array_keys($this->bitmask); sort($keys,SORT_NUMERIC); for($i=array_pop($keys);$i>=0;$i--) { if($this->bitmask[$i]) $string.=sprintf("%0".INTEGER_LENGTH."b",$this->bitmask[$i]); } return$string; } publicfunctionclear()//Purge! { $this->bitmask=array(); } publicfunctiondebug()//Seewhat'sgoingoninyourbitmaskarray { var_dump($this->bitmask); }}?>Ittreatsapositiveintegerinputasabit,soyoudon'thavetodealwiththepowersof2yourself.set(8979879);//Whatever$bitmask->set(888);if($bitmask->read(888)) print'Happy!\n';$bitmask->toggle(39393);//Yaddayadda$bitmask->remove(888);$bitmask->debug();$bitmask->stringin("10010100010100100010101001010101000000001000001");print$bitmask->stringout()."\n";$bitmask->debug();$bitmask->clear();$bitmask->debug();?>Wouldproduce:Happy!array(2){ [289673]=> int(65536) [1270]=> int(8388608)}00000000000000010010100010100100010101001010101000000001000001array(2){ [0]=> int(355106881) [1]=> int(37970)}array(0){}
up
down
1
forlampatmsndotcom¶14yearsago
two'scomplementlogicaloperationfor32-bit.$xmustbe(int)whenpassingittothisfunctiontoworkproperly.functioncomp2($x) //32bitbitwisecomplement{ $mask=0x80000000; if($x<0) { $x&=0x7FFFFFFF; $x=~$x; return$x^$mask; } else { $x=$x^0x7FFFFFFF; return$x|$mask; }}
up
down
4
ivorasatgmaildotcom¶11yearsago
Asanadditionalcuriosity,forsomereasontheresultoftheoperation("18"&"32")is"10".Inotherwords,tryavoidingusingthebinaryoperatorsonstrings:)
up
down
5
spencer-p-moyatexampledotcom¶10yearsago
TheNOTorcomplementoperator(~)andnegativebinarynumberscanbeconfusing.~2=-3 becauseyouusetheformula ~x=-x-1 Thebitwisecomplementofadecimalnumberisthenegationofthenumberminus1.NOTE:justusing4bitsherefortheexamplesbelowbutinrealityPHPuses32bits.Convertinganegativedecimalnumber(ie:-3)intobinarytakes3steps:1)convertthepositiveversionofthedecimalnumberintobinary(ie:3=0011)2)flipsthebits(ie:0011becomes1100)3)add1(ie:1100 +0001=1101)Youmightbewonderinghowdoes1101=-3.WellPHPusesthemethod"2'scomplement"torendernegativebinarynumbers.Iftheleftmostbitisa1thenthebinarynumberisnegativeandyouflipthebitsandadd1.Ifitis0thenitispositiveandyoudon'thavetodoanything.So0010wouldbeapositive2.Ifitis1101,itisnegativeandyouflipthebitstoget0010.Add1andyouget0011whichequals-3.
up
down
3
joshatjoshstrikedotcom¶11yearsago
Morereferencingthisformyselfthananything...ifyouneedtoiteratethrougheverypossiblebinarycombinationwhere$nnumberofflagsaresetto1inamaskof$bitslength:
0){
$z=numflags($u);
if($z==$n)array_push($masks,$u);
$u--;
}
return($masks);
}
functionnumflags($n){
$k=0;
while($n){
$k+=$n&1;
$n=$n>>1;
}
return($k);
// alternately:
// $u=0;
// for($k=1;$k<=$n;$k*=2){
// $u+=($n&$k?1:0);
// }
// return($u);
}
?>
up
down
3
cw3theophilusatgmaildotcom¶13yearsago
ForthosewhoarelookingforacircularbitshiftfunctioninPHP(especiallyusefulforcryptographicfunctions)thatworkswithnegtivevalues,hereisalittlefunctionIwrote:(Note:Ittookmealmostawholedaytogetthistoworkwithnegative$numvalues(Icouldn'tfigureoutwhyitsometimesworkedandothertimesdidn't),becausePHPonlyhasanarithmaticandnotalogicalbitwiserightshiftlikeIamusedto.I.e.0x80000001>>16willouputs(inbinary)"11111111111111111000000000000000"insteadof"00000000000000001000000000000000"likeyouwouldexpect.Tofixthisyouhavetoapplythemask(bybitwise&)equalto0x7FFFFFFFrightshiftedonelessthantheoffsetyouareshiftingby.)0){ $num=($num<>(32-$offset%32))&($mask>>(31-$offset%32))); } elseif($offset<0){ $offset=abs($offset); $num=(($num>>$offset%32)&($mask>>(-1+$offset%32)))|($num<
up
down
2
erichatseachawaiidotcom¶9yearsago
Justanoteregardingnegativeshiftvalues,asthedocumentationstateseachshiftisanintegermultiplyordivide(leftorrightrespectively)by2. Thatmeansanegativeshiftvalue(therighthandoperand)effectsthesignoftheshiftandNOTthedirectionoftheshiftasIwouldhaveexpected. FE.0xff>>-2resultsin0x0and0xff<isdifferentthanandthelatterofthetwoshouldbeused.
up
down
2
sagatichdotnet¶8yearsago
mereimplementforbitwiseNOT(~) protectedfunctionflipBin($number){ $bin=str_pad(base_convert($number,10,2),32,0,STR_PAD_LEFT); for($i=0;$i<32;$i++){ switch($bin{$i}){ case'0': $bin{$i}='1'; break; case'1': $bin{$i}='0'; break; } } returnbindec($bin); }thebenefitis,itworkswithnumbersgreaterMAX_INT
up
down
3
abaatexampledotcom¶10yearsago
Itistruethatifboththeleft-handandright-handparametersarestrings,thebitwiseoperatorwilloperateonthecharacters'ASCIIvalues.However,acomplementisnecessarytocompletethissentence.Itisnotirrelevanttopointoutthatthedecimalcharacter'sASCIIvaluehavedifferentbinaryvalues.
up
down
1
Anonymous¶12yearsago
BewarethatPHP's<>operators,unliketheotherbitwiseoperatorsdonotworkonASCIIvalues;<>casttheiroperandstointeger(whenpossible)beforeshiftingandwillalwaysreturnanintegerresult.Forexample:
up
down
2
Tbrendstrup¶16yearsago
notethattheshiftoperatorsarearithmetic,notlogiclikeinC.Youmaygetunexpectedresultswithnegativenumbers,seehttp://en.wikipedia.org/wiki/Bitwise_operationhere'safunctiontodologicrightshifts.>($amt-1); return($var>>$amt)|$mask; } return$var>>$amt;}$val=-10;printf("arithmeticshiftonanegativeinteger
%1\$032b
%2\$032b
%1\$0d
%2\$0d
",$val,$val>>1);printf("logicshiftonanegativeinteger
%1\$032b
%2\$032b
%1\$0d
%2\$0d
",$val,lshiftright($val,1));printf("logicshiftonapositiveinteger
%1\$032b
%2\$032b
%1\$0d
%2\$0d
",-$val,lshiftright(-$val,1));?>givestheoutput:arithmeticshiftonanegativeinteger1111111111111111111111111111011011111111111111111111111111111011-10-5logicshiftonanegativeinteger1111111111111111111111111111011001111111111111111111111111111011-102147483643logicshiftonapositiveinteger0000000000000000000000000000101000000000000000000000000000000101105
up
down
2
EricSwanson¶16yearsago
Perlvs.PHPimplementationofthe^operator:AfterattemptingtotranslateaPerlmoduleintoPHP,IrealizedthatPerl'simplementationofthe^operatorisdifferentthanthePHPimplementation. Bydefault,PerltreatsthevariablesasfloatsandPHPasintegers. IwasabletoverifythePHPuseoftheoperatorbystating"useinteger;"withinthePerlmodule,whichoutputtheexactsameresultasPHPwasusing.Thelogicaldecisionwouldbetocasteveryvariableas(float)whenusingthe^operatorinPHP. However,thiswillnotyieldthesameresults. Afteraboutahalfhourofbangingmyheadagainstthewall,Idiscoveredagemandwroteafunctionusingthebinary-decimalconversionsinPHP./*nothavingmuchexperiencewithbitwiseoperations,IcannottellyouthatthisistheBESTsolution,butitcertainlyisasolutionthatfinallyworksandalwaysreturnstheEXACTsameresultPerlprovides.*/functionbinxor($a,$b){ returnbindec(decbin((float)$a^(float)$b));}//normalPHPcodewillnotyeildthesameresultasPerl$result=3851235679^43814;//=-443704711//togetthesameresultasPerl$result=binxor(3851235679,43814);//=3851262585//YIPPEE!!!//toseethedifferences,trythefollowing$a=3851235679XOR43814;$b=3851235679^43814;//integerresult$c=(float)3851235679^(float)43814;//sameas$b$d=binxor(3851235679,43814);//sameasPerl!!echo("A:$a
");echo("B:$b
");echo("C:$c
");echo("D:$d
");
up
down
1
CoreXii¶11yearsago
BeverycarefulwhenXOR-ingstrings!Ifoneofthevaluesisempty(0,'',null)theresultwillalsobeempty!Thisseemsratherinconsistentbehavior.AnintegerXOR'dwithzeroresultstheoriginalinteger.ButastringXOR'dwithanemptyvalueresultsanemptyvalue!Mypasswordhashingfunctionwasalwaysreturningthesamehash...BecauseIwasXOR-ingitwithasaltthatwassometimesempty!
up
down
1
Anonymous¶10yearsago
Tomakeveryclearwhy("18"&"32")is"10".1)theytheyarebothstrings,2)"&"operatorworksonstringsbytakingeach!Character!fromeachstringandmakeabitwise&betweenthemandaddthisvaluetotheresultingstringSo:"18"ismadeupoftwocharacters:0x31,0x38"32"ismadeupoftwocharacters:0x33,0x32----RESULT-----0x31&0x33=0x31=>"1"0x38&0x32=0x30=>"0"andtheresultis"10"whichis100%correct.
up
down
-1
biziclopatvipmaildothu¶2yearsago
Afastalgorithm(BrianKernighan's)tocountallbitssetto1inaninteger,modifiedtoworkwithsignedints.Itdoesthesameashttps://php.net/gmp_popcountexceptforordinaryintegers.=0){ for($count=0; $n; ++$count) $n&=$n-1; } else{ for($count=1; $n<<1; ++$count) $n&=$n-1; } return$count;}echo'ThisPHPuses'.count_set_bits(-1).'-bitintegers.';?>
up
down
0
joey¶6yearsago
Ifyouwantaquickonelinerforreversingbinaryandperformance/sanityisn'tanissue: functionreverse_bits($n){ return(int)base_convert(strrev(str_pad(base_convert($n,10,2),PHP_INT_SIZE*8,0,STR_PAD_LEFT)),2,10); }Expectittobehavestrangelyforthesignedbit.BesttouseforIshouldpointout:yourflagsarestoredinasingleinteger.Youcanstoreloadsofflagsinasingleinteger.Tousemyfunctions,sayyouwantedtosetMYFLAGONEandMYFLAGTHREE,youwoulduse:Note:youcanpassset_bitflags()asmanyflagstosetasyouwant.Whenyouwanttotestlaterifacertainflagisset,usee.g.:Theonlytrickypartisdefiningyourflags.Hereistheprocess:1. Writealistofyourflags2. Countthem3. Definethelastflaginyourlistas1times2tothepowerofminusone.(I.E.1*2^(-1))3.Workingbackwardsthroughyourlist,fromthelasttothefirst,defineeachoneashalfofthepreviousone.Youshouldreach1whenyougettothefirstIfyouwanttounderstandbinarynumbers,bitsandbitwiseoperationbetter,thewikipediapageexplainsitwell-http://en.wikipedia.org/wiki/Bitwise_operation.
up
down
0
bartbonsatdebster.nl¶14yearsago
@kendsnyderatgmaildotcomThanxforyourgreatfunction.Butyourfunctionisnot100%correct.Itshouldbe:functionsafeBitCheck($number,$comparison){ if($number<2147483647){ return($number&$comparison)==$comparison; }else{ $binNumber=strrev(base_convert($number,10,2)); $binComparison=strrev(base_convert($comparison,10,2)); for($i=0;$i0){ $amount%=32; $value=($value<>(32-$amount)); }elseif($amount<0){ $amount=-$amount%32; $value=($value>>$amount)|($value<>(31-$bits):0xffffffff; if($amount>0){ $amount%=$bits; $value=($value<>($bits-$amount)); }elseif($amount<0){ $amount=-$amount%$bits; $value=($value>>$amount)|($value<",$value);}?>
up
down
-1
luisatrosetydotcom¶6yearsago
Exampleoffunctionusingbitwiseoperationsforconvertinghexadecimalcolor(usuallygivenas6hexadecimaldigitstring,intoseparatedRGBintegers)>16,$g>>8,$b); //Shiftfullrighteachcolorfromitsoriginalposition}?>ExampleofuseWouldproduce:red:17 green:34blue:51Since:dechex(17)='#11'dechex(34)='#22'dechex(51)='#33'
up
down
-5
J.Ketting¶7yearsago
@zoolyDon'tforgettheleadingzeros.It'sveryimportantifyouwanttowriteafunctionsimilartotheassemblyinstructions'ror'and'rol'(RotateonRightandRotateonLeft),becauseofdwordvalue;rotatingthebinaryalwaystakes32positionsandincludestheleadingzeros!Sothisistherightway:Lookatthisassemblycode:movedx,1bf5616croredx,8Afterthisoperation:edx=0x6c1bf561(binary:1101100000110111111010101100001)Butyourcodereturns0x0d9bf561(binary:1101100110111111010101100001)Inordertogettherightvalueyouhavetoaddtheleadingzerosbyaddingthatlinewithstrpad()(seeabove).Veryimportant!
+addanote
Operators
OperatorPrecedence
ArithmeticOperators
AssignmentOperators
BitwiseOperators
ComparisonOperators
ErrorControlOperators
ExecutionOperators
Incrementing/DecrementingOperators
LogicalOperators
StringOperators
ArrayOperators
TypeOperators