【算法设计与数据结构】为何程序员喜欢将INF设置为0x3f3f3f3f?(转)
?
摘自https://blog.csdn.net/jiange_zh/article/details/50198097
?
在算法競賽中,我們常常需要用到一個“無窮大”的值,對于我來說,大多數時間我會根據具體問題取一個99999999之類的數(顯得很不專業啊!)
在網上看別人代碼的時候,經常會看到他們把INF設為0x7fffffff,奇怪為什么設一個這么奇怪的十六進制數,一查才知道,因為這是32-bit int的最大值。如果這個無窮大只用于一般的比較(比如求最小值時min變量的初值),那么0x7fffffff確實是一個完美的選擇。
但是更多情況下,0x7fffffff并不是一個好的選擇,比如在最短路徑算法中,我們使用松弛操作:
if (d[u]+w[u][v]<d[v])d[v]=d[u]+w[u][v];
如果u,v之間沒有邊,那么w[u][v]=INF,如果我們的INF取0x7fffffff,那么d[u]+w[u][v]會溢出而變成負數,我們的松弛操作便出錯了!
準確來說,0x7fffffff不能滿足“無窮大加一個有窮的數依然是無窮大”這個條件,它會變成了一個很小的負數。
更進一步的,如果有一個數能夠滿足“無窮大加無窮大依然是無窮大”,那么就更好了!
前陣子無意中看到了一個不一樣的取值,INF=0x3f3f3f3f,這時我又郁悶了,這個值又代表的是什么?于是我去尋找答案,發現這個值的設置真的很精妙!
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(一般我們只有賦值為-1和0的時候才使用它)。現在好了,如果我們將無窮大設為0x3f3f3f3f,那么奇跡就發生了,0x3f3f3f3f的每個字節都是0x3f!所以要把一段內存全部置為無窮大,我們只需要memset(a,0x3f,sizeof(a))。
所以在通常的場合下,0x3f3f3f3f真的是一個非常棒的選擇!
轉載于:https://www.cnblogs.com/wkfvawl/p/10439382.html
總結
以上是生活随笔為你收集整理的【算法设计与数据结构】为何程序员喜欢将INF设置为0x3f3f3f3f?(转)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: nginx反向代理vue访问时浏览器加载
- 下一篇: 为什么函数式语言会火