Re: C/C++ 語言新手十三誡 -- Ver. 2016

看板C_and_CPP (C/C++)作者 (私は幸せです)時間8年前 (2016/06/08 15:37), 8年前編輯推噓11(11024)
留言35則, 3人參與, 最新討論串2/6 (看更多)
※ 引述《wtchen (沒有存在感的人)》之銘言: : : INT_MIN -2147483647 // compiler實作時最小值不可大於 -(2147483648-1) : ^ ^^^^^^^^^^^^ ^^^^^^^^^^^^^^ : INT_MAX 2147483647 // compiler實作時最小值不可小於 (2147483648-1) : ^^^^^^^^^^^^ ^^^^^^^^^^^^^^ : 不過由於32bit能顯示的範圍就是2**32種,所以一般作業系統會把 : ^^^^^^^ ^^^^^^^^^^^^^^^^^^^^ : INT_MIN多減去1,也就是int 的顯示範圍為-2147483648 ~ +2147483647。 : 當程式跑到abs(-2147483648)>0時,由於int不存在2147483648, : 於是正確結果無法被有限的數位顯示(undefined behavior) 解釋奇怪的地方 :         ^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ 不知道這樣有沒有比較好:   INT_MIN = -2147483648   INT_MAX = 2147483647   由於 integer literal 會被視為 int 整數型態   所以 #define INT_MIN -2147483648 是行不通的(超過 int 上界)   因此編譯器標頭檔實作時可以定義成 #define INT_MIN (-INT_MAX - 1) -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 140.113.68.118 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1465371461.A.A9C.html ※ 編輯: Hazukashiine (140.113.68.118), 06/08/2016 15:44:49

06/08 15:45, , 1F
這裡其實還牽扯到一個細節是 C/C++ 沒有負的 literal
06/08 15:45, 1F

06/08 15:45, , 2F
所以直接寫 -2147483648 基本上是行不通的
06/08 15:45, 2F
嗯 沒錯 我再編輯補充一下 www

06/08 15:52, , 3F
我好一陣子前寫了一個小題目來講解這回事:
06/08 15:52, 3F

06/08 15:53, , 4F

06/08 16:38, , 5F
我這邊列的INT_MIN/INT_MAX是Standard制定的
06/08 16:38, 5F
哪一份的 Standard 定義 INT_MIN 是 -2147483647 了?

06/08 16:38, , 6F
當然OS實作或user define可以有別的方法
06/08 16:38, 6F
還有 INT_MIN 定義跟 OS 實作有什麼關係?是編譯器標頭檔實作。 還有置底的 C/C++ 語言新手十三誡有很多用詞沒有很精確的地方。

06/08 16:48, , 7F
一般linux會做成#define INT_MIN (-INT_MAX - 1)
06/08 16:48, 7F

06/08 16:51, , 8F
稍微改了一下....
06/08 16:51, 8F

06/08 17:23, , 9F
看看有沒有好些....
06/08 17:23, 9F

06/08 21:53, , 10F
如果你去看C99/C11 Standard,你會發現long int (4 bytes)...
06/08 21:53, 10F

06/08 21:53, , 11F
INT_MIN...
06/08 21:53, 11F

06/08 21:54, , 12F
為何我看到的, long int 應該是對應 LONG_MIN 和 LONG_MAX ?
06/08 21:54, 12F

06/08 21:55, , 13F
然後 int 才是對應 INT_MIN 和 INT_MAX ... @@
06/08 21:55, 13F

06/08 22:08, , 14F
如果 ... "long int" <== 原文 488 行.
06/08 22:08, 14F

06/08 22:13, , 15F
然後C99/C11中, INT_MIN/INT_MAX 的 "範例" 是 -32767/+32767
06/08 22:13, 15F
好神奇... http://www.cplusplus.com/reference/climits/ 就是保證 int 至少有 2 bytes 那麼大,而不是 4 bytes... ※ 編輯: Hazukashiine (140.113.68.118), 06/08/2016 22:19:08

06/08 22:21, , 16F
一開始我也發現這點,所以如果有人更早看到我的更新會發現
06/08 22:21, 16F

06/08 22:22, , 17F
我一開始是用short作例子(因為int有int跟long int兩種)
06/08 22:22, 17F

06/08 22:22, , 18F
不過short好像不存在abs,所以才改用int(汗)
06/08 22:22, 18F

06/08 22:25, , 19F
我還是把例子改成long好了(汗)
06/08 22:25, 19F

06/08 22:26, , 20F
不過long有一樣的問題,64bit是8byte
06/08 22:26, 20F

06/08 22:31, , 21F
改成long了,這次應該好多了
06/08 22:31, 21F

06/08 22:37, , 22F
用字我也想儘量精準,所以有任何意見請不吝指正
06/08 22:37, 22F
嗯嗯 看起來蠻認真編輯的 晚一點再指出是哪邊吧 QQ ※ 編輯: Hazukashiine (140.113.68.118), 06/08/2016 22:58:56

06/08 23:11, , 23F
嗯. C99/C11 的 5.2.4.2.1 提到是 implementation-defined,
06/08 23:11, 23F

06/08 23:12, , 24F
而數值的絕對值要大於等於該值(比方INT_MAX不可小於+32767).
06/08 23:12, 24F

06/08 23:24, , 25F
Standard給的都是"範圍至少要怎樣",編譯器實作只要比較大
06/08 23:24, 25F

06/08 23:25, , 26F
就OK(我有特別註明)
06/08 23:25, 26F

06/08 23:25, , 27F
但是因為範圍不對稱(差1的情況下)造成像abs這樣突然超過
06/08 23:25, 27F

06/08 23:26, , 28F
範圍的情況下會出現啥就是未定義
06/08 23:26, 28F

06/08 23:32, , 29F
嗯, 因為提到 standard, 就應該照抄, 不能亂改數值 :P
06/08 23:32, 29F

06/08 23:32, , 30F
另外, (4 bytes) 也許可以改移到備註, 說明在多數 16-bits
06/08 23:32, 30F

06/08 23:33, , 31F
和 32-bits 編譯器可能採用; 而 64-bits 可能不同之類.
06/08 23:33, 31F

06/08 23:34, , 32F
因為我手上只有Linux-64bit,Win我不熟不知道狀況是否不同
06/08 23:34, 32F

06/08 23:35, , 33F
16bit...我多久沒用了....
06/08 23:35, 33F

06/08 23:40, , 34F
把16/32/64bit的可能情形加進去了
06/08 23:40, 34F

06/09 01:08, , 35F
各位教訓的是....
06/09 01:08, 35F
文章代碼(AID): #1NLyj5gS (C_and_CPP)
文章代碼(AID): #1NLyj5gS (C_and_CPP)