《
代码执行的效率》裡頭提到一個效率問題,
這個看似聰明的改法帶來了什麼樣難以察覺的陷阱呢?
不想看答案的可以先想想看。
哇! 真的可以計算正確結果耶! 估計你開始佩服想出這個寫法的人了。再來看看另外的例子 a.cpp。
發現結果不正確了, 僅僅是 type 的不同, 程式就不正確了。你願意用這個演算法嗎? 這個演算法在某些時候是對的, 某些時候是錯的, 你能掌握在什麼時機才是正確的嗎?
第一點: 這寫法很難懂
第二點: 不一定總是正確
如果你能掌握型別的話, 那還有一個規則是你不能掌握的。最後在提醒一個 c 語言規則,
有號數的右移運算, 是 implementation-defined (ref:
1.2. 移位运算)。
當然查閱 c 規格書最具有權威性, 但那個不好看, 如果要在精確一點的中文資料, 可以參考《标准C语言指南》6.18 (p341), 將移位運算式做了詳細的說明, 看完之後應該會覺得, 嗯 ... c 真難。
相信這麼一來, 之前的佩服感應該是完全消失了, c 沒有這麼簡單, 她是程式語言, 不是數學。
我不熟習 java, 有人可以說說 java 的行為嗎?
既然談到 Bitshift Operators 順便說說之前遇到的一個問題。
t.c 看似理所應當的程式碼, c 編譯器發出了 warning:
怎麼回事? 1 的 type 是 int, 不是 uint_64_t, 也不是其他 type, 就是 int, 在我的平台, 是 32bit, 而 shift 32 bit 超出了 32bit 的範圍, 這是 Undefined (ref:
1.2. 移位运算), 這回我參考了 c 標準規格書 (ref: figure 1, 第 3 點), 而不是如人所想因為等號左邊有個 uint64_t temp 就會將結果轉型成 uint64_t, 這是 c 語言很難相處之道。
|
figure 1. N1570 6.5.7 |
解法: 1ul << 32, 明白告訴 c 編譯器, 我的 1 是 unsigned long (在我的環境是 64bit)
沒有留言:
張貼留言
使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。
我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。