GalaxyPilot —— D.S


                  生命不熄,戰斗不止
          數據加載中……

          java位操作zt

          Java中的位操作指定包括:
          ~????????????????????按位非(NOT)
          &???????????????????按位與(AND)
          |????????????????????按位或(OR)
          ^???????????????????按位異或(XOR)
          >>?????????????????右移
          >>>???????????????無符號右移
          <<?????????????????左移
          前面幾個都非常簡單,主要是移位操作比較容易出錯.

          首先要搞清楚參與運算的數的位數,如int的是32位。long的是64位。
          如int?i?=?1;
          i的二進制原碼表示為:
          00000000000000000000000000000001

          long?l?=?1;
          l的二進制原碼表示為:
          0000000000000000000000000000000000000000000000000000000000000001

          二、
          正數沒有反碼、補碼,也可以說正數的反碼、補碼跟原碼一樣。
          負數的反碼為原碼逐位取反,
          如int?i?=?-1;
          10000000000000000000000000000001,最高位是符號位。正數為0,負數為1。
          逐位取反后:
          01111111111111111111111111111110即反碼。
          反碼加1:
          01111111111111111111111111111111即補碼。
          負數都是用補碼參與運算的。得到的也是補碼,需要減1取反獲得原碼。

          三、常用的位運算符--0在位運算中是比較特殊的。
          ^??異或。??????相同為0,相異為1;???任何數與0異或都等于原值。 
          &??與。????????全1為1,?有0為0;  任何數與0異或都等于0。  
          |??或。????????有1為1,?全0為0。  任何數與0或都等于原值。
          <<?左移。??????補0。
          >>?右移。??????符號位是0補0,是1補1。
          >>>無符號右移。補0。
          ~??非??????????逐位取反

          四、負數參與的運算,得到的是補碼,需要將補碼先減1,然后逐位取反,得到原碼。即為運算結果。
          0例外,如果得到的是0,則不需減1和取反。
          另外,兩個正數運算后得到的就是原碼,不需減1和取反。


          舉例:
          1^-1,
          -1
          10000000000000000000000000000001--原碼
          01111111111111111111111111111110--反碼
          01111111111111111111111111111111--補碼
          1
          00000000000000000000000000000001--原碼

          則1^-1等于
          01111111111111111111111111111111^
          00000000000000000000000000000001=
          01111111111111111111111111111110--補碼
          01111111111111111111111111111101--反碼
          10000000000000000000000000000010--原碼==-2
          即1^-1=-2

          舉例:
          1^-2
          -2
          10000000000000000000000000000010--原碼
          01111111111111111111111111111101--反碼
          01111111111111111111111111111110--補碼
          1
          00000000000000000000000000000001--原碼
          則1^-2等于
          01111111111111111111111111111110^
          00000000000000000000000000000001=
          01111111111111111111111111111111--補碼
          01111111111111111111111111111110--反碼
          10000000000000000000000000000001--原碼==-1


          1.<<
          邏輯左移,右邊補0,符號位和其他位一樣.
          正數:
          x<<1一般相當于2x,但是可能溢出.
          溢出范圍:?230~(231-1)?二進制表示?010000...000到01111....1111,移位后最高為變為1了,變成負數了.
          負數:
          x<<1一般也相當于2x,也有可能溢出.所以,?x*32可以寫成x<<5
          溢出范圍:?-231~-(230+1)二進制表示10000...000到101111...1111,移位后最高為變成0了,變成正數了.

          2.>>
          算術右移,和上面的不對應,為正數時左邊補0,為負數時左邊補1.
          x>>1,相當于x/2,余數被舍棄,因為這個是縮小,所以不會溢出.
          不過有一點要注意:?-1右移多少位都是-1.
          另外舍棄的余數是正的,?3>>1=1?舍棄的余數是1.
          -3>>1=-2?舍棄的余數也是1,而不是-1.
          對于正數?x>>1和x/2相等
          對于負數?x>>1和x/2不一定相等.

          3.>>>
          邏輯右移,這個才是和<<對應的
          這個把符號位一起移動,左邊補0
          對于正數,>>>和>>是一樣的
          對于負數,右移之后就變成正數了.

          可以使用Integer.toBinaryString(int?i)來看01比特,更加直觀.


          考慮下面的代碼:?
          for?(val?=?0;?val?<?100000;?val?+=5)?{?alterX?=?val?*?8;?myResult?=?val?*?2;?}?


          用移位操作替代乘法操作可以極大地提高性能。下面是修改后的代碼:?

          for?(val?=?0;?val?<?100000;?val?+=?5)?{?alterX?=?val?<<?3;?myResult?=?val?<<?1;?}?

            修改后的代碼不再做乘以8的操作,而是改用等價的左移3位操作,每左移1位相當于乘以2。相應地,右移1位操作相當于除以2。值得一提的是,雖然移位操作速度快,但可能使代碼比較難于理解,所以最好加上一些注釋。?

          posted on 2007-02-12 10:03 舵手 閱讀(2771) 評論(4)  編輯  收藏

          評論

          # re: java位操作zt  回復  更多評論   

          在Java中,位操作往往被忽視 :(
          多謝您的文章 :)
          2007-02-12 19:02 | 山風小子

          # re: java位操作zt  回復  更多評論   

          -2
          10000000000000000000000000000010--原碼
          01111111111111111111111111111101--反碼
          01111111111111111111111111111110--補碼
          算錯了吧,負數取補時符號位是不變了,暈死了
          2007-10-09 18:10 | me

          # re: java位操作zt  回復  更多評論   

          @me
          同意
          2008-03-26 13:16 | me2

          # re: java位操作zt  回復  更多評論   

          這篇文章提醒了我負數在計算機中是以補碼形式存儲的...某一個課后的習題迎刃而解...謝謝啦
          2008-04-05 18:07 | Cys

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 西乡县| 乌拉特前旗| 梁河县| 南阳市| 方正县| 长丰县| 洱源县| 长春市| 通城县| 定安县| 兰西县| 龙海市| 诸城市| 耒阳市| 铜陵市| 黑河市| 绥芬河市| 涿州市| 庄河市| 新巴尔虎右旗| 康乐县| 岑溪市| 新昌县| 花莲县| 夏津县| 绥宁县| 通河县| 龙州县| 图木舒克市| 儋州市| 天祝| 四平市| 衡阳市| 班戈县| 阿巴嘎旗| 南城县| 马鞍山市| 南丰县| 蚌埠市| 云和县| 长治市|