C 位操作 左移32位 錯誤
阿新 • • 發佈:2019-01-01
搬磚拼接64位數字,因高32位long未先強轉64,導致拼接失敗,順便發現個問題,32位變數左移32位等於原數值。C下位移操作為邏輯位移,全部左移補零後,數值應為零,結果和預期不符,遂查詢癥結所在。
程式碼如下:
long i = 512;
i = i << 32;
結果i == 512
作為對比:32次i << 1結果是0
short i = 512;
i = i << 16;
結果i == 0
所以,第一種情況是個特例。
彙編程式碼上,shl 20h,shl 1,都是shl
經過一系列對比發現:
初始值512不是重點,初始其他值也是一樣效果。;
short 左移32也會出問題,char左移32也會出問題,而二者左移對應的16位和8位都不會有問題,所以問題出在左移32?????!!!!(除了64位的long long ,左移32位才不是原數字,64位是)
GCC編譯測試
警告:<<操作達到或者超過型別大小
這個warning也很詭異,針對的不是運算元的型別,還是32位。
例如,long 左移32,會提示這個,short左移16,不會提示。
網上資料
基本都是根據結果猜答案的,型別大小模運算都出來了,那你照顧過16位數的感受嗎?16位數左移17位為什麼不等於左移1位??(後來仔細看了這段,吐槽一下,自己說了不確定其他編譯器,然後還下了定論。)
雖然和我的實操結果相同,但是這種拿經驗倒推理論的說法還是不敢太認同。所以去查了一下。
英文版資料如下:
型別強轉,這也解釋了char和short都只有左移32才異常!!!!!!!即使我用(char)i << 32也是徒勞!!!
原文是說你左移超過32這種操作未定義,也就是說,不支援,不確定,可能因你用的編譯器不同而不同!既然答案如此,沒辦法,只能儘量避免這種操作了!!!!