0x3f3f3f3f...编程中无穷大常量的设置技巧
如果问题中各数据的范围明确,那么无穷大的设定不是问题,在不明确的情况下,很多程序员都取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真的是一个非常棒的选择。
0x3f3f3f3f...编程中无穷大常量的设置技巧的更多相关文章
- c# WinForm窗体编程中对窗体程序设置快捷键
c# WinForm窗体编程中对窗体程序设置快捷键http://www.cnblogs.com/bison1989/archive/2011/09/19/2180977.html /// <su ...
- Swing编程中为什么对Panel设置了位置后,它的lable位置也跟这变了呢?
总结: package com.da; //这里我不明白,我对每一个Panle里的按钮设置了位置BorderLayout.SOUTH.可是为什么Lable的位置和它一样同步设置了呢? //做一个界面 ...
- Windows2003中IIS的安全设置技巧
在Windows Server 2003中对于IIS的安全设置具有十分重要的意义,所以掌握IIS安全设置的六大技巧是一个网管员必备的基本技能.下面就是对IIS的安全设置的六大技巧. 技巧1.安装系统补 ...
- C/C++ 常量的定义与应用(编程中的常量)
常量一般定义为全局变量,且大写: 1. 字符串常量 const string EXPAND_X = "X+YF"; const string EXPAND_Y = "FX ...
- Windows Phone编程中Dispatcher.BeginInvoke的使用
在学习Windows Phone 程序开发时经常会使用到Dispatcher.BeginInvoke()的编程方法,可能许多初学者并不熟悉Dispatcher.BeginInvoke的使用方法以及为什 ...
- IDEA Intellij中vim插件使用小技巧
在 IDEA Intellij小技巧和插件 一文中简单介绍了一下IdeaVim插件.在这里详细总结一下这个插件在日常编程中的一些常用小技巧.供有兴趣使用这个插件,但对Vim还不十分熟悉的朋友参考.当然 ...
- 0x3F3F3F3F——ACM中的无穷大常量
在算法竞赛中,我们常常需要用到设置一个常量用来代表“无穷大”. 比如对于int类型的数,有的人会采用INT_MAX,即0x7fffffff作为无穷大.但是以INT_MAX为无穷大常常面临一个问题,即加 ...
- Swift语言中为外部参数设置默认值可变参数常量参数变量参数输入输出参数
Swift语言中为外部参数设置默认值可变参数常量参数变量参数输入输出参数 7.4.4 为外部参数设置默认值 开发者也可以对外部参数设置默认值.这时,调用的时候,也可以省略参数传递本文选自Swift1 ...
- Chrome 中的 JavaScript 断点设置和调试技巧 (转载)
原文地址:http://han.guokai.blog.163.com/blog/static/136718271201321402514114/ 你是怎么调试 JavaScript 程序的?最原始的 ...
随机推荐
- Mongodb PHP开发类库
<?php /** * Mongodb 基本操作API,支持基本类似关系统型数据库的操作接口 * * @version 1.0 * * [说明] * * 1:该版本API实现了 Mongodb ...
- linxu添加定时任务
1. 在需要定时执行的php文件的第一行加 也就是文件开头加 #! /bin/local/php -q 其中 /bin/local/php 是自己的php.exe 所在的位置 2. 上传要定时执行的 ...
- JS笔记 入门第一
WHY? 一.你知道,为什么JavaScript非常值得我们学习吗? 1. 所有主流浏览器都支持JavaScript. 2. 目前,全世界大部分网页都使用JavaScript. 3. 它可以让网页呈现 ...
- GCD 之 同步 异步 并发
1. dispatch_async(dispatch_get_global_queue(, ), ^{ // 处理耗时操作的代码块... //通知主线程刷新 dispatch_async(dispat ...
- TexturePacker
TexturePacker 可以免费申请,希望可以申请到.
- AngularJS Factory Service Provider
先看看http://www.cnblogs.com/mbydzyr/p/3460501.html http://www.oschina.net/translate/angularjs-factory- ...
- Delphi 的动态数组
传统的Pascal 语言其数组大小是预先确定的,当你用数组结构声明数据类型时,你必须指定数组元素的个数.专业程序员也许知道些许动态数组的实现技术,一般是采用指针,用手工分配并释放所需的内存. Delp ...
- android sdk 下载缓慢的问题
原文地址:http://www.oschina.net/question/265039_173445#tags_nav 1.在Android SDK Manager Setting 窗口设置 HTTP ...
- STM32菜鸟成长记录---RS485通讯协议的应用
写作原因:近来蛋闲?非也 ! 昨天一同事合作的项目代码出现的bug-----他的上位机每200ms给我发送命令向我这边下位机读取一些数据,在此过程会按下按键做一些另外操作并给他返回数据:(通信是通 ...
- 大数据时代之hadoop(五):hadoop 分布式计算框架(MapReduce)
大数据时代之hadoop(一):hadoop安装 大数据时代之hadoop(二):hadoop脚本解析 大数据时代之hadoop(三):hadoop数据流(生命周期) 大数据时代之hadoop(四): ...