c++算法關於常整型INF定義形式的解釋


概念解釋

單詞:infinite的意思是無窮大
INF就是infinite的簡寫,表示無窮大常數

  • 0x表示十六進制,后面的3f3f3f3f表示一個十六進制數
  • 一般都是用0x3f3f3f3f作值,不怎么出錯

0x7ffffff

如果問題中各數據的范圍明確,那么無窮大的設定不是問題,在不明確的情況下,取0x7ffffff作為無窮大,這是32-bit int的最大值,如果這個無窮大只用於一般的比較,比如求最小值時min變量的初值,更多的情況下選擇0x3f3f3f3f

  • 1.很多時候我們並不只是單純拿無窮大作比較,而是會運算后再做比較,
    例如在大部分最短路徑算法中都會使用松弛操作:

    if(d[u]+w[u][v]<d[v])
    d[v]=d[u]+w[u][v];
    

    若u,v,之間沒有邊,那么w[u][v]=INF,INF=0x7ffffff, 那么d[u]+w[u][v]會溢出而變成負數,松弛操作便出錯了

  • 2.不能滿足無窮大加上無窮大依然是無窮大,而且會發生災難性的錯誤

0x3f3f3f3f

鑒於以上兩點,需要一個更好的INF來替代0x7ffffff,最嚴謹的辦法是對無窮大
進行特別處理而不是找一個很大的常量來代替他(或者說模擬它),但是這樣會讓編程過程麻煩
最精巧的無窮大常量取值是0x3f3f3f3f

  • 1.0x3f3f3f3f的十進制是1061109567,也就是10^9級別的(和0x7fffffff一個數量級), 而一般場合下的數據都是小於10^9的,所以它可以作為無窮大使用而不致出現數據大於無窮大的情形。

  • 2.由於一般的數據都不會大於10^9,所以當我們把無窮大加上一個數據時,它並不會溢出(這就滿足了“無窮大加一個有窮的數依然是無窮大”),事實上0x3f3f3f3f+0x3f3f3f3f=2122219134,這非常大但卻沒有超過32-bit int的表示范圍,所以0x3f3f3f3f還滿足了我們“無窮大加無窮大還是無窮大”的需求。

  • 3.0x3f3f3f3f還能給我們帶來一個意想不到的額外好處:

    如果我們想要將某個數組清零,我們通常會使用memset(a,0,sizeof(a))這樣的代碼來實現(方便而高效)
    但是當我們想將某個數組全部賦值為無窮大時(例如解決圖論問題時鄰接矩陣的初始化)
    就不能使用memset函數而得自己寫循環了(寫這些不重要的代碼真的很痛苦)
    我們知道這是因為memset是按字節操作的,它能夠對數組清零是因為0的每個字節都是0
    如果我們將無窮大設為0x3f3f3f3f,那么奇跡就發生了,0x3f3f3f3f的每個字節都是0x3f
    所以要把一段內存全部置為無窮大,我們只需要memset(a,0x3f,sizeof(a))


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM