转自 http://aikilis.tk/

如果问题中各数据的范围明确,那么无穷大的设定不是问题,在不明确的情况下,很多程序员都取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真的是一个非常棒的选择。

0x3f3f3f3f...编程中无穷大常量的设置技巧的更多相关文章

  1. c# WinForm窗体编程中对窗体程序设置快捷键

    c# WinForm窗体编程中对窗体程序设置快捷键http://www.cnblogs.com/bison1989/archive/2011/09/19/2180977.html /// <su ...

  2. Swing编程中为什么对Panel设置了位置后,它的lable位置也跟这变了呢?

    总结: package com.da; //这里我不明白,我对每一个Panle里的按钮设置了位置BorderLayout.SOUTH.可是为什么Lable的位置和它一样同步设置了呢? //做一个界面 ...

  3. Windows2003中IIS的安全设置技巧

    在Windows Server 2003中对于IIS的安全设置具有十分重要的意义,所以掌握IIS安全设置的六大技巧是一个网管员必备的基本技能.下面就是对IIS的安全设置的六大技巧. 技巧1.安装系统补 ...

  4. C/C++ 常量的定义与应用(编程中的常量)

    常量一般定义为全局变量,且大写: 1. 字符串常量 const string EXPAND_X = "X+YF"; const string EXPAND_Y = "FX ...

  5. Windows Phone编程中Dispatcher.BeginInvoke的使用

    在学习Windows Phone 程序开发时经常会使用到Dispatcher.BeginInvoke()的编程方法,可能许多初学者并不熟悉Dispatcher.BeginInvoke的使用方法以及为什 ...

  6. IDEA Intellij中vim插件使用小技巧

    在 IDEA Intellij小技巧和插件 一文中简单介绍了一下IdeaVim插件.在这里详细总结一下这个插件在日常编程中的一些常用小技巧.供有兴趣使用这个插件,但对Vim还不十分熟悉的朋友参考.当然 ...

  7. 0x3F3F3F3F——ACM中的无穷大常量

    在算法竞赛中,我们常常需要用到设置一个常量用来代表“无穷大”. 比如对于int类型的数,有的人会采用INT_MAX,即0x7fffffff作为无穷大.但是以INT_MAX为无穷大常常面临一个问题,即加 ...

  8. Swift语言中为外部参数设置默认值可变参数常量参数变量参数输入输出参数

    Swift语言中为外部参数设置默认值可变参数常量参数变量参数输入输出参数 7.4.4  为外部参数设置默认值 开发者也可以对外部参数设置默认值.这时,调用的时候,也可以省略参数传递本文选自Swift1 ...

  9. Chrome 中的 JavaScript 断点设置和调试技巧 (转载)

    原文地址:http://han.guokai.blog.163.com/blog/static/136718271201321402514114/ 你是怎么调试 JavaScript 程序的?最原始的 ...

随机推荐

  1. 常用SQL的优化

    导入数据 对于MyISAM存储引擎的表,可以通过以下方式快速地导入大量数据 alter table tbl_name disable keys;              //关闭表非唯一索引的更新 ...

  2. 别忘记给你博客的windows live writer配置 ping服务

    写好一篇博客,想要实现秒收.就必须要为文章添加ping服务. 这里介绍一下给wlw添加ping服务的办法. 点击工具---选项--ping服务器. 在右侧栏中加入以下地址 http://rpc.pin ...

  3. wordpress 首页模板变量对应表

    最近开始学习wp,这里做一些笔记. 首页模板,第一行为前台显示的html代码.第二行为 wp-content/themes/模板目录 下 head.php文件中. 其中我将变量名 html用绿色标记 ...

  4. Android 百度地图开发问题----解决地图有时候加载不出来问题

    相信很多人在开发百度地图的时候会出现百度地图有时候会加载不出来,只显示网格图. 这个问题究其原因就是申请百度key的时候填写的SHA1也就是指纹证书有问题.估计很多开发者都是照着百度开放平台上介绍的流 ...

  5. 分区 Service Bus 队列和主题

    编辑人员注释:本文章由 Windows Azure Service Bus 团队的二级项目经理 Ruppert Koch 撰写. 上周,Microsoft 发布了 Azure SDK 2.2 和 Se ...

  6. Hibernate 知识点复习

    核心接口 1  Configuration接口负责配置并启动Hibernate,创建SessionFactory对象 2  SessionFactory接口负责初始化Hibernate.它充当数据存储 ...

  7. Balanced Binary Tree --Leetcode C++

    递归 左子树是否为平衡二叉树 右子树是否为平衡二叉树 左右子树高度差是否大于1,大于1,返回false 否则判断左右子树 最简单的理解方法就是如下的思路: class Solution { publi ...

  8. swjtu 2213 A Game About Cards(模拟题)

    题目链接:http://acm.swjtu.edu.cn/JudgeOnline/showproblem?problem_id=2213 思路分析:该问题与约瑟夫问题相似:每次将前n张牌放到队列的最后 ...

  9. oracle 中的select ...connect by prior ...start with 及(+)的用法

    1.select ...connect by prior ...start with的用法: select ... from <tablename> where <condition ...

  10. 自己定义View----点击滑动选择字母列表

    因为项目须要,也不想使用网上的写好的控件,于是作死的自己定义了一个控件.特此记录下成功.效果例如以下: 首先须要把全部的字母绘制出来: private static String letters[] ...