如果问题中各数据的范围明确,那么无穷大的设定不是问题,在不明确的情况下,很多程序员都取0x7fffffff作为无穷大,因为这是32-bit int的最大值。如果这个无穷大只用于一般的比较(比如求最小值时min变量的初值),那么0x7fffffff确实是一个完美的选择,但是在更多的情况下,0x7fffffff并不是一个好的选择。
且听我慢慢道来,为什摸0x7fffffff为什摸不是个好的选择
1.但在很多情况下,0x7fffffff会出现错误,比如溢出。
这样两个无穷大数相加会变成负数,还有如在做dijkstra求最短路时,当做松弛操作,判断if (d[u]+w[u][v]<d[v]) d[v]=d[u]+w[u][v],
若u到v没有路劲,w[u][v]=0x7fffffff,这样d[u]+w[u][v]会变成负数,这就产生了错误。
无穷大加无穷大依然是无穷大”,至少两个无穷大相加不应该出现灾难性的错误,这一点上0x7fffffff依然不能满足我们
if (d[u]+w[u][v]<d[v]) d[v]=d[u]+w[u][v];
准确来说,0x7fffffff不能满足“无穷大加一个有穷的数依然是无穷大”这个条件,它会变成了一个很小的负数。
来个小测试及更明白了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include<stdio.h> #include<string.h> #define MAX1 0x7fffffff #define MAX2 0x3f3f3f3f int a[3]; int main() { memset(a,0x3f,sizeof(a)); printf("%dn",MAX1); printf("%dn",MAX1*2); printf("%dn",MAX2); printf("%dn",MAX2*2); for(int i=0;i<3;i++) printf("%d ",a[i]); printf("n"); return 0; }
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))。
所以在通常的场合下,const int INF = 0x3f3f3f3f;真的是一个非常棒的选择。
最后
以上就是忧虑墨镜最近收集整理的关于为什么无穷大总是0x3f3f3f3f而不是0x7fffffff?的全部内容,更多相关为什么无穷大总是0x3f3f3f3f而不是0x7fffffff内容请搜索靠谱客的其他文章。
发表评论 取消回复