Bitwise Operators - Manual - PHP

文章推薦指數: 80 %
投票人數:10人

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



請為這篇文章評分?