2014年3月12日 星期三

【Java】位移運算...消失的位元...請不要強制讀取它!否則.....活不過七天

坦白說,在Java之下用位元運算的方式來處理「乘以二」這件事情,感覺不太出有明顯的效能差異。

(我用百億次的方式累積差異,但還是沒有明顯的差。)

但就算不討論效能上的差異,位元運算是很多工業用或商業用程式設計技巧的基礎,只是一直被JAVA(的標準教程)給忽略了。

原因或許不難理解,因為除非為了特殊理由,──例如加密──位元運算的意義在JAVA中很雞肋。



【以下開始為無厘頭的內容,有點像是我個人的自言自語。不建議點進來的人認真看待。反正知道Java中用位移方式做「乘以二」並沒有塊到哪裡去就好,願意自己做實驗更好。】

所以「講」一些很基本的東西好了...(這其實是筆記,並不是教材,路過看到的人...見笑了。)

byte值的上下限是-128~127。

問題是如果將127在加一,會如何呢?



位元運算的基礎原理就是在二進位的表示法中,將所有的1和0左右移動。

例如在二進位中的110其實是6,如果乘以二變成12,二進位表示法是1100。

它只是往左移動一位,並補上一個零。

如果是基數,例如7,二進位表示法111,除以二則是往右移位,變成011,但零可以省去,變成11。

結果...如果是乘法,或是往左位移,除了數字增加以外,還會增大這個數值得「單位」

例如本來是Integer長整數,往左移動幾次後就變成了long...



但有個問題是...如果將一個負數做往左或往右位移呢?

正數位移最後會變成0,但是負數卻會變成....-1。(1再往右位一,一樣會變成零。)



這就是上面要問將127在加一會如何的道理。

假設127是01111111,加一後會變成10000000,也就是-128。

不要懷疑!

10000000是負128。

也就是說00000001+11111111會得到00000000....(1消失了)......也就是零。

1加多少會是零?...當然是-1啊!

所以......-128不停的往右位移...不是補0,因為它從10000000到最後變成11111111。



(驚恐!!!!!!!)

除非編譯器的程式有特別判斷,這是否可以表示...往右位移其實是將「第一個位元繁殖」。

所以第一個位元若為0(同時表示這是個正數),所以往右位移後補上的是0,若為1(同時表示這是個負數),所以往右位移後補上的是1。

那往左位移呢?

除非程式又設定為「一律補零」,否則這是否表示其實在最右邊的位元之外,還有一個位元,只是設計者/使用者/人類永遠無法讀取修改它?



就好像七夜怪談中的錄影帶一樣......強制讀取的後果,蒼蠅會跑出來。

2014年3月10日 星期一

【Android】Activity中的Thread

一堆範例寫到Android中的Thread控制,都會寫一堆「怎麼把Thread關閉」的程式碼。

但其實...因為在Android中,有「Activity的生命週期」這件事,還有所謂的「APP之間的界線」,所以大家變得不太敢用一些理所當然的方法去操作Thread。



其實Thread並不會介意是哪個Activity在呼叫它、操縱它、管理它,就好像Thread根本不會介意設計者把操縱的程式寫在Activity之外。

把Thread的屬性設定為「public static」,然後大膽的關掉啟動它的Activity、並切換到另一個Activity。



程式意外的繼續順暢運作!

如果程式運作不順暢,絕對不是因為這樣切換Activity,更不是因為忘了把Thread關掉。



但...當你/妳確定這次按下「返回」後,APP的每個Activity都會退出執行狀態,那還是確保每個ˊThread都關掉吧!



講得很籠統?...連個程式碼都沒有,只有Thread/Activity/publi/static.....就別要求太多了。

(思考一下Thread設計的方式,思考一下Thread對各個Activity的意義。

如果是我,我會在Thread中留個Handler做為常數,讓各Activity不定時丟個Handler進去讓Thread來觸發/send......

如果是我,我會寫個統一的資料物件,讓各Activity去指揮Thread上網路接收資料,把資料轉入物件中,再讓Activity取用......

Google的Android API中,有些東西是寶,有些東西只有參考價值,但也有很多根本是渣。)