0x3f3f3f3f和0x7fffffff所代表的无穷大
如果问题中各数据的范围明确,那么无穷大的设定不是问题,在不明确的情况下,很多程序员都取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不能满足“无穷大加一个有穷的数依然是无穷大”,它变成了一个很小的负数。
除了要满足加上一个常数依然是无穷大之外,我们的常量还应该满足“无穷大加无穷大依然是无穷大”,至少两个无穷大相加不应该出现灾难性的错误,这一点上0x7fffffff依然不能满足我们。
所以我们需要一个更好的家伙来顶替0x7fffffff,最严谨的办法当然是对无穷大进行特别处理而不是找一个很大很大的常量来代替它(或者说模拟它),但是这样会让我们的编程过程变得很麻烦。在我读过的代码中,最精巧的无穷大常量取值是0x3f3f3f3f,我不知道是谁最先开始使用这个精妙的常量来做无穷大,不过我的确是从一位不认识的ACMer(ID:Staginner)的博客上学到的,他/她的很多代码中都使用了这个常量,于是我自己也尝试了一下,发现非常好用,而当我对这个常量做更深入的分析时,就发现它真的是非常精巧了。
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))。
0x3f3f3f3f和0x7fffffff所代表的无穷大相关推荐
- 0x3f3f3f3f,0x7fffffff 用于赋值
1. memset函数 memset函数是按字节进行赋值的,经常用于赋值0或者-1, 但正规的用法应该是用于char数组的, 即只能赋值为0x00到0xFF, 例如memset(,0xff,sizeo ...
- 0x3f3f3f3f和0x3f3f3f3f3f3f3f3f分别代表
对于一些变量的初始化,我们希望它足够大,但是却又不希望它稍微变换一下就超出了数据范围,因此我们巧妙的用一个接近数据最大值的一个值INF. 若数据是int4位则定义#define INF 0x3f3f3 ...
- C/C++无穷大的表示 0x7fffffff + 0x7fffffff= 负数
C/C++中无穷大的表示 一.为什么用0x3f3f3f3f(十进制:1061109567)表示无穷大 1.C/C++中int型的最大值是2^31-1,十进制:2147483647.16进制:0x7ff ...
- 关于0x3f和0x3f3f3f3f
在做题时经常将0x3f3f3f3设为INF(正无穷) #define INF 0x3f3f3f3f 相比0x7fffffff,0x3f3f3f3f在做图论题时,(如Dijkstra算法) 相加时不会使 ...
- 算法训练营学习笔记1
算法训练营学习笔记 贪心算法 心算法总是做出当前最好的选择,期望通过局部最优选择得到全局最优的解决方案.从问题的初始解开始,一步歩地做出当前最好的选择,逐步逼近问题的目标,尽可能得到最优解: 贪心本质 ...
- 图论 —— 最短路 —— Floyd 算法
[概述] Floyd 算法又称为插点法,是一种用于寻找给定的加权图中多源点之间最短路径的算法. 其最大特点是可以计算出现负边权时的最短路,实际应用中,很多题目不是问如何用 Floyd 求最短路,而是用 ...
- 0x3f3f3f3f_《羊卓的杨的算法笔记》_Quentin
为什么要用0x3f3f3f3f? 我们有时需要取一个无穷大,但是我们该取什么值呢? 首先可以取int的最大值0x7fffffff,但是这个数只能用来进行大小比较.因为如果我们想正常进行运算,使 ...
- Tarjan相关最全(附训练题和答案)
Tarjan相关最全(附训练题和答案) 算法思想 Tarjan 强连通分量 割点 割桥 缩点 Kosaraju Garbow 训练 POJ2186 POJ1236 POJ2375 Luogu P338 ...
- postgresql 删除触发器_PostgreSQL:我没有带闪,不讲武德
前言 今天有个业务的妹子问我"在吗?" 我说什么事? 给我发个截图,我一看!噢,原来是把数据删除了,想让我把数据找回来. 他说,大哥你能不能帮我. 我说可以! 很快啊,我就打开终端 ...
最新文章
- 一文读懂图像局部特征点检测算法
- 如何看待「TensorFlow就是一颗定时炸弹」的说法?
- 无法查找网络工作组计算机,XP系统弹出“无法查看工作组计算机”提示怎么办?...
- EF通用数据层封装类(支持读写分离,一主多从)
- WEB攻击手段及防御-扩展篇
- js使用hover事件做一个“个人中心”的浮动层
- 决策树php,决策树模型组合之随机森林与GBDT
- 滴滴、小米启动造车,特斯拉的护城河还能守多久?
- Meteor在手机上运行
- ubuntu记录pdf手写笔记: 数位板(硬件)+xournal(软件)
- 打造可用的梅花6硬键盘
- 如何 接收消息服务器url,(读书笔记)网络是怎样连接的——浏览器生成消息...
- python项目:打印输出平行四边形和三角形(多种样式)
- 美团热修复 Android适配,美团热修复Robust用法和实践
- python爬财务数据_会计终于不用被老板催着做报表,现在95%的财务都在悄悄办这事了!...
- 计算机英语写一封邮件给汤姆作文,英语作文带翻译写一封电子邮件
- 三菱PLC通过CC LINK IE通讯控制2个三菱伺服的测试 程序,里面有JOG HOME,定位,适合你入门参考。包合IO规划,伺候参数,PLC程序。
- 类里面的成员函数指针使用
- 关于Eth-Trunk接口与IP-Trunk接口
- 沈阳大雨部分地区积水情况