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

作者: descent (「雄辯是銀,沉默是金」)   2017-07-18 21:36:44
※ 引述《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。
作者: PkmX (阿貓)   2017-07-18 22:13:00
32-bit int的話 1<<31 就已經是 undefined behavior 了
作者: final01 (牛頓運動定律)   2017-07-18 22:37:00
有spec說明0x80000000就是unsigned int?? 1<<31就是int這是我比較想知道的XDD
作者: remizu (remizu)   2017-07-18 22:59:00
標準規格書中有Types of integer constants的表
作者: LPH66 (-6.2598534e+18f)   2017-07-19 08:22:00
一般來說沒附字尾的整數是 int, 除非 int 裝不下裝不下的時候會有一定的程序往上試型態, 試到裝下了就用這是為什麼 0x80000000 是 unsigned int 的原因1<<31 則是 1 和 31 這兩個常數進行運算bitshift 看左邊, 1 是 int 所以結果就是 int這就是為什麼一般對 bitmask 的值會寫成 1U<<31 的原因加個 U 就是說這個 1 是 unsigned int順帶一提的是, C/C++ 沒有負 literal, 所有看起來是負數的常數都是正常數加負號, 所以某些負值會產生很意外的結果

Links booklink

Contact Us: admin [ a t ] ucptt.com