Re: [問題] C unsigned long的問題

看板C_and_CPP作者 (「雄辯是銀,沉默是金」)時間6年前 (2017/07/18 21:36), 6年前編輯推噓2(2011)
留言13則, 4人參與, 最新討論串2/2 (看更多)
※ 引述《final01 (牛頓運動定律)》之銘言: : 開發平台(Platform): (Ex: Win10, Linux, ...) : Linux : 編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出) : GCC : 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) : 問題(Question): : #include <stdio.h> : void print_x(unsigned long x) : { : printf("=> 0x%lx\n",x); : } : int main() : { : print_x(0x80000000); : print_x((1<<31)); : } : 想問為何同樣是數字一個不會overflow 一個會?? : 餵入的資料(Input): : 0x80000000 : 1<<31 我猜測你平台的 long 是 64bit。 0x80000000 的 type 是 unsigned int, 所以是 2147483648。 1<<31 運算後結果 0x80000000 的 type 是 int, 所以是 -2147483648。 很奇怪, 一個是 unsigned int, 一個卻是 int 是吧! 把 int -2147483648 傳給 unsigned long 時, 16 進位便是 0xffffffff80000000, 而不是 80000000。 -- 紙上得來終覺淺,絕知此事要躬行。 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 117.19.8.137 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1500385012.A.4DE.html

07/18 22:13, , 1F
32-bit int的話 1<<31 就已經是 undefined behavior 了
07/18 22:13, 1F
感謝, ref N1570 p95 第4點, 還真的不容易看, 英文不好, 請大家幫忙確認一下。

07/18 22:37, , 2F
有spec說明0x80000000就是unsigned int?? 1<<31就是int
07/18 22:37, 2F

07/18 22:37, , 3F
這是我比較想知道的XDD
07/18 22:37, 3F
ref N1570 6.4.4.1 integer constants

07/18 22:59, , 4F
標準規格書中有Types of integer constants的表
07/18 22:59, 4F

07/19 08:22, , 5F
一般來說沒附字尾的整數是 int, 除非 int 裝不下
07/19 08:22, 5F

07/19 08:22, , 6F
裝不下的時候會有一定的程序往上試型態, 試到裝下了就用
07/19 08:22, 6F

07/19 08:22, , 7F
這是為什麼 0x80000000 是 unsigned int 的原因
07/19 08:22, 7F

07/19 08:23, , 8F
1<<31 則是 1 和 31 這兩個常數進行運算
07/19 08:23, 8F

07/19 08:23, , 9F
bitshift 看左邊, 1 是 int 所以結果就是 int
07/19 08:23, 9F

07/19 08:24, , 10F
這就是為什麼一般對 bitmask 的值會寫成 1U<<31 的原因
07/19 08:24, 10F

07/19 08:24, , 11F
加個 U 就是說這個 1 是 unsigned int
07/19 08:24, 11F

07/19 08:25, , 12F
順帶一提的是, C/C++ 沒有負 literal, 所有看起來是負數的
07/19 08:25, 12F

07/19 08:26, , 13F
常數都是正常數加負號, 所以某些負值會產生很意外的結果
07/19 08:26, 13F
※ 編輯: descent (175.98.141.254), 07/19/2017 09:32:57
文章代碼(AID): #1PRWxqJU (C_and_CPP)
文章代碼(AID): #1PRWxqJU (C_and_CPP)