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

Posted on 2012 年 11 月 21 日 by Aikilis

如 果问题中各数据的范围明确,那么无穷大的设定不是问题,在不明确的情况下,很多程序员都取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,最严谨的办法当然是对无穷大进行特别处理而不是找一个很大很大的常量来代替它(或者说模拟
它),但是这样会让我们的编程过程变得很麻烦。在我读过的代码中,最精巧的无穷大常量取值是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真的是一个非常棒的选择。

© 2012, Aikilis. 版权所有. 转载请注明出自http://aikilis.tk/.

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

时间: 2024-08-25 09:17:24

编程中无穷大常量的设定技巧的相关文章

编程中无穷大常量的设定技巧【0x3f3f3f3f】

编程中无穷大常量的设定技巧 如 果问题中各数据的范围明确,那么无穷大的设定不是问题,在不明确的情况下,很多程序员都取0x7fffffff作为无穷大,因为这是32-bit int的最大值.如果这个无穷大只用于一般的比较(比如求最小值时min变量的初值),那么0x7fffffff确实是一个完美的选择,但是在更多的情况 下,0x7fffffff并不是一个好的选择. 很多时候我们并不只是单纯拿无穷大来作比较,而是会运算后再做比较,例如在大部分最短路径算法中都会使用的松弛操作: if (d[u]+w[u]

0x3f3f3f3f...编程中无穷大常量的设置技巧

转自 http://aikilis.tk/ 如果问题中各数据的范围明确,那么无穷大的设定不是问题,在不明确的情况下,很多程序员都取0x7fffffff作为无穷大,因为这是32-bit int的最大值.如果这个无穷大只用于一般的比较(比如求最小值时min变量的初值),那么0x7fffffff确实是一个完美的选择,但是在更多的情况下,0x7fffffff并不是一个好的选择. 很多时候我们并不只是单纯拿无穷大来作比较,而是会运算后再做比较,例如在大部分最短路径算法中都会使用的松弛操作:if (d[u]

编程中无穷大常量的设置技巧(转)

0x3f3f3f3f… 如果问题中各数据的范围明确,那么无穷大的设定不是问题,在不明确的情况下,很多程序员都取0x7fffffff作为无穷大,因为这是32-bit int的最大值.如果这个无穷大只用于一般的比较(比如求最小值时min变量的初值),那么0x7fffffff确实是一个完美的选择,但是在更多的情况下,0x7fffffff并不是一个好的选择. 很多时候我们并不只是单纯拿无穷大来作比较,而是会运算后再做比较,例如在大部分最短路径算法中都会使用的松弛操作:if (d[u]+w[u][v]<d

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

如果问题中各数据的范围明确,那么无穷大的设定不是问题,在不明确的情况下,很多程序员都取0x7fffffff作为无穷大,因为这是32-bit int的最大值.如果这个无穷大只用于一般的比较(比如求最小值时min变量的初值),那么0x7fffffff确实是一个完美的选择,但是在更多的情况下,0x7fffffff并不是一个好的选择. 很多时候我们并不只是单纯拿无穷大来作比较,而是会运算后再做比较,例如在大部分最短路径算法中都会使用的松弛操作:if (d[u]+w[u][v]<d[v]) d[v]=d[

编程中无穷大的设定

如果问题中各数据的范围明确,那么无穷大的设定不是问题,在不明确的情况下,很多程序员都取0x7fffffff作为无穷大,因为这是32-bit int的最大值.如果这个无穷大只用于一般的比较(比如求最小值时min变量的初值),那么0x7fffffff确实是一个完美的选择,但是在更多的情况下,0x7fffffff并不是一个好的选择. 很多时候我们并不只是单纯拿无穷大来作比较,而是会运算后再做比较,例如在大部分最短路径算法中都会使用的松弛操作: if (d[u]+w[u][v]<d[v]) d[v]=d

网络编程中的指令号命名技巧

package com.catstudio.interstellar.net; public class CMD { // 模块类型 public static final int TYPE_USER = 1001; // 用户 public static final int TYPE_RANK = 1002; // 排行 public static final int TYPE_BROADCAST = 1004; // 广播 public static final int TYPE_AWARD

IDEA Intellij中vim插件使用小技巧

在 IDEA Intellij小技巧和插件 一文中简单介绍了一下IdeaVim插件.在这里详细总结一下这个插件在日常编程中的一些常用小技巧.供有兴趣使用这个插件,但对Vim还不十分熟悉的朋友参考.当然基本的hjkl移动光标和几种常见模式等等基本概念就略过不提了. 为了确保只包含常用操作,这里提到的技巧都没有从现成文档里抄,而是凭记忆列出(不常用自然就不记得了).估计会有所遗漏,慢慢再补充. 1. 切换Vim模拟器状态 这个插件允许设置一个快捷键一键开启或关闭,在切换模式时会同时自动切换keyma

程序员在编程开发中的10个实用技巧

程序员在编程开发中的10个实用技巧,下面是我自己在工作中学到的一些简单的技巧和策略,希望能对各位有用.1.     橡皮鸭调试法不知道各位有没有这样的经历,当你正在给别人描述问题的时候,突然灵机一动想到了解决方案?这种情况的产生是有科学依据的.高谈阔论能让我们的大脑重新有条理地组织问题.在这种情况下,你的聊天对象就是“橡皮鸭”.团队中的每个人都应该积极主动乐意地成为彼此的“橡皮鸭”.有时候,如果你幸运的话,你的“橡皮鸭”搞不好还能给出有效的建议呢.2.     快速信息反馈一旦写好代码就要尽快得

Thinkphp编程中几种常见的实用技巧讲解

在Thinkphp编程中集成了很多用起来非常方便的方法.对于刚接触的编程人员来说,可谓是只要掌握并灵活运用了,那么就可以达到事半功倍的效果了,下面就来为大家详细的讲解一下. 1. getField getField的方便之处在于可以获取一个值,一个数组,或者一组键值对. 接下来举三个例子简单说明. A. 获取一个值. 在修改密码的方法中,要验证旧密码是否匹配.现已知用户id为$uid. 则$old_pass = $Model->where("uid='$uid'")->ge