最大值的选取

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

此文转自  http://t.cn/zjyTuab

如果问题中各数据的范围明确,那么无穷大的设定不是问题,在不明确的情况下,很多程序员都取0x7fffffff作为无穷大,因为这是32-bit int的最大值。如果这个无穷大只用于一般的比较(比如求最小值时min变量的初值),那么0x7fffffff确实是一个完美的选择,但是在更多的情况下,0x7fffffff并不是一个好的选择。

  1. 很多时候我们并不只是单纯拿无穷大来作比较,而是会运算后再做比较,例如在大部分最短路径算法中都会使用的松弛操作:
    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不能满足“无穷大加一个有穷的数依然是无穷大”,它变成了一个很小的负数。
  2. 除了要满足加上一个常数依然是无穷大之外,我们的常量还应该满足“无穷大加无穷大依然是无穷大”,至少两个无穷大相加不应该出现灾难性的错误,这一点上0x7fffffff依然不能满足我们。

即,0x7fffffff不能满足无穷大 + 常数 = 无穷大  且 不能满足无穷大 + 无穷大 = 无穷大

所以我们需要一个更好的家伙来顶替0x7fffffff,最严谨的办法当然是对无穷大进行特别处理而不是找一个很大很大的常量来代替它(或者说模拟它),但是这样会让我们的编程过程变得很麻烦。在我读过的代码中,最精巧的无穷大常量取值是0x3f3f3f3f,我不知道是谁最先开始使用这个精妙的常量来做无穷大,不过我的确是从一位不认识的ACMer(ID:Staginner)的博客上学到的,他/她的很多代码中都使用了这个常量,于是我自己也尝试了一下,发现非常好用,而当我对这个常量做更深入的分析时,就发现它真的是非常精巧了。

  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))。

即,0x3f3f3f3f能表示无穷大 且 满足无穷大 + 常数 = 无穷大  且 满足无穷大 + 无穷大 = 无穷大 且 易初始化

所以在通常的场合下,0x3f3f3f3f真的是一个非常棒的选择。



【竞赛】为啥用0x3f代表无穷大 以及memset用法简析 解释为啥用0x3f代表无穷大 以及memset用法简析 阅读详情

相关推荐

【C语言学习笔记】MEMSET函数的使用

MEMSET函数的使用 要使用memset函数首先要预加载库<string.h> 函数的使用 memset(*p, int c, n) 函数名(要操作的数组首地址, 要替换的字符, 要替换的长度) *要替换的值虽然以int形式传递,但在执行填充替换操作时使用的是该值的无符号字符形式。 *要填换的长度n指的是前n项,一般是全部替换,特殊情况除外。 通过实际例题来感受下用法 #include <stdio.h> #include <string.h> int main()

z 656

编程中无穷大常量的设定技巧

本文转自:http://aikilis.tk/2471.html 编程中无穷大常量的设定技巧 如果问题中各数据的范围明确,那么无穷大的设定不是问题,在不明确的情况下,很多程序员都取0x7fffffff作为无穷大,因为这是32-bit int的最大值。如果这个无穷大只用于一般的比较(比如求最小值时min变量的初值),那么0x7fffffff确实是一个完美的选择,但是在更多的情况下,0x7

Bob Lee's Blog For CS 5208

深度学习中nan和inf的解决

1、 nan 和inf产生原因 搭建神经网络后产生的,在训练早期,模型参数可能不是很合适,会出现梯度消失和爆炸的情况,特别是有lstm,rnn这类网络的情况。nan 是not a number ,inf是无穷大。比如求损失函数会用到log,如果输入接近0,那么结果就是inf。 2、解决方法 2.1 学习率要设置小一些 2.2使用带上限的激活函数,如tf.nn.relu6 也就是对输出做了限制 2.2 检查输入数据中是否有nan或inf x = tf.constant([5.0, 4.8, 6

ytusdc的博客 5333

【关于无穷大0x3f3f3f的一些知识】

【关于无穷大0x3f3f3f的一些知识】 0x3f3f3f3f的十进制是1061109567,也就是109级别的(和0x7fffffff一个数量级),而一般场合下的数据都是小于109的,所以它可以作为无穷大使用而不致出现数据大于无穷大的情形。 另一方面,由于一般的数据都不会大于109,所以当我们把无穷大加上一个数据时,它并不会溢出(这就满足了“无穷大加一个有穷的数依然是无穷大”),事实上0x3f3f3f3f+0x3f3f3f3f=2122219134,这非常大但却没有超过32-bit int的表示范围,所以

weixin_52115456的博客 1196

R语言 选取某一行的最大值

可以先自定义函数,也可以用的时候再定义。>mat<-matrix(c(1:3,7:9,4:6),byrow=T,nc=3) >mat [,1][,2][,3] [1,]123 [2,]789 [3,]456 >apply(mat,2,fu...

weixin_34220963的博客 2万+

ACM中关于最大值选取

原博文:  http://blog.csdn.net/hnust_xiehonghao/article/details/8223104 如果问题中各数据的范围明确,那么无穷大的设定不是问题,在不明确的情况下,很多程序员都取0x7fffffff作为无穷大,因为这是32-bit int的最大值。如果这个无穷大只用于一般的比较(比如求最小值时min变量的初值),那么0x7fffffff确实

我的指针和我一样找不到对象 1291

论OI中最大值选取

为什么我的Floyd会输出负数啊? 为什么我的代码写对了却全都爆零了啊? 那么很可能是你的INF取大/小了! 那么inf到底应该取什么值呢? 首先,inf应该要比一般的题目中出现的数据要大,但是又不能超过max_int。 1e9是一个好选择! 为什么不是0x7fffffff呢?这不是int的最大值吗 因为有的时候(例如Floyd等算法)会出现两个inf相加的情况,如果inf取max_int则加法会...

weixin_30877755的博客 96

MYSQL基础上机练习题(七)选取最大值、最小值、连续值、缺失值、重复值的综合应用

MYSQL中特殊值如最大值、最小值、连续值、缺失值、重复值的选取

CheyenneLam的博客 2142

选取拥有某个列的最大值的行

任务:找出最贵物品的编号、销售商和价格。 这很容易用一个子查询做到: SELECT article, dealer, price FROM   shop WHERE  price=(SELECT MAX(price) FROM shop); 另一个解决方案是按价格降序排序所有行并用MySQL 特定LIMIT 子 句只得到第一行: SELECT a...

指点江山 429

python groupby函数实现分组后选取最大值或者最小值

python分组之后选取最大值或最小值

vergil_zsh的博客 6091

选取一列数据最大值的一种写法

在看某种机器学习算法时看到的一种写法: np.array([delta[t - 1, j] * self.A[j, i] for j in range(self.N)]).max()运用for i in range(n)表示这个变量的一列数据

YZXnuaa的博客 1300

mysql选取分组后每个分组最大值_mysql获取分组后每组的最大值实例详解

mysql获取分组后每组的最大值实例详解1. 测试数据库表如下:create table test(`id` int not null auto_increment,`name` varchar(20) not null default '',`score` int not null default 0,primary key(`id`))engine=InnoDB CHARSET=UTF8;2....

weixin_30476033的博客 1085

数组选取最大值最小值 求总和平均分

任务要求: 1、 定义一个整型数组,并赋初值 61, 23, 4, 74, 13, 148, 20 2、 定义变量分别保存最大值、最小值、累加值和平均值,并假设数组中的第一个元素既为最大值又为最小值 3、 使用 for 循环遍历数组中的元素,分别与假定的最大值和最小值比较。如果比假定的最大值要大,则替换当前的最大值;如果比假定的最小值要小,则替换当前的最小值 4、 循环执行过程中对数组中的元素进行累加求和 5、 循环结束根据累加值计算平均值,并打印输出相关内容 package com.imooc; imp

SunerGo_Alex的博客 862
上一篇: 编辑距离
下一篇: 背包问题九讲笔记_01背包
insistGoGo
博客等级 码龄15年 768粉丝 207原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值