編程中常用的幾個特殊值
一、INF=0x3f3f3f3f
我們知道計算機都是按照二進制存儲的。在日常練習過程中,我們都會遇到INF無窮大量的問題,那麽我們該怎麽定義這麽一個數字,下面便有一些說明:
- 0x3f3f3f3f的十進制是1061109567,也就是10^9級別的(和0x7fffffff一個數量級),而一般場合下的數據都是小於10^9的,所以它可以作為無窮大使用而不致出現數據大於無窮大的情形。
- 另一方面,由於一般的數據都不會大於10^9,所以當我們把無窮大加上一個數據時,它並不會溢出(這就滿足了“無窮大加一個有窮的數依然是無窮大”),事實上0x3f3f3f3f+0x3f3f3f3f=2122219134,這非常大但卻沒有超過32-bit int的表示範圍,所以0x3f3f3f3f還滿足了我們“無窮大加無窮大還是無窮大”的需求。
- 最後,0x3f3f3f3f還能給我們帶來一個意想不到的額外好處:如果我們想要將某個數組清零,我們通常會使用memset(a,0,sizeof(a))這樣的代碼來實現(方便而高效),但是當我們想將某個數組全部賦值為無窮大時(例如解決圖論問題時鄰接矩陣的初始化),就不能使用memset函數而得自己寫循環了(寫這些不重要的代碼真的很痛苦),我們知道這是因為memset是按字節操作的,它能夠對數組清零是因為0的每個字節都是0,現在好了,如果我們將無窮大設為0x3f3f3f3f,那麽奇跡就發生了,0x3f3f3f3f的每個字節都是0x3f!所以要把一段內存全部置為無窮大,我們只需要memset(a,0x3f,sizeof(a))。
所以在通常的場合下,const int INF = 0x3f3f3f3f;真的是一個非常棒的選擇。
0x7fffffff和0x3f3f3f3f區別使用:https://blog.csdn.net/rain722/article/details/51283930
二、0x7fffffff
可以算一下 0x7FFFFFFF 是多少
每個十六進制數4bit,因此8位16進制是4個字節,剛好是一個int整型
F的二進制碼為 1111
7的二進制碼為 0111
這樣一來,整個整數 0x7FFFFFFF 的二進制表示就是除了首位是 0,其余都是1
就是說,這是最大的整型數 int(因為第一位是符號位,0 表示他是正數)
用 INT_MAX 常量可以替代這個值。
三、INT_MAX和INT_MIN
C中常量INT_MAX和INT_MIN分別表示最大、最小整數,定義在頭文件limits.h中。
1. INT_MAX,INT_MIN數值大小
因為int占4字節32位,根據二進制編碼的規則,INT_MAX = 2^31-1,INT_MIN= -2^31.C/C++中,所有超過該限值的數,都會出現溢出,出現warning,但是並不會出現error。如果想表示的整數超過了該限值,可以使用長整型long long 占8字節64位。
2. 關於INT_MAX INT_MIN的運算
由於二進制編碼按原碼、補碼和反碼的規則進行運算,所有程序中對INT_MAX和INT_MIN的運算應當格外註意,在出現溢出的時候,不遵循數學規則。
INT_MAX + 1 = INT_MIN
INT_MIN - 1 = INT_MAX
abs(INT_MIN) = INT_MIN
比較有趣的是,INT_MAX + 1 < INT_MAX, INT_MIN - 1 > INT_MIN, abs(INT_MIN) < 0.
四、常用的幾個質數
因為要使字符串的哈希值各不相同,所以要取一些奇奇怪怪的質數進行MOD,比如19260817(逃)
常見的質數 1e9+7,1e9+9,233,19260817,196608131e9+7,1e9+9,233,19260817,19660813 等
為了防止相同,經常會使用雙膜數,即取兩次模,判斷是否相等,就能使運算更加精確。
編程中常用的幾個特殊值