转的一个jdk bug
来源:互联网 发布:c语言取反运算符 编辑:程序博客网 时间:2024/06/06 11:04
原文:http://tb.blog.csdn.net/TrackBack.aspx?PostId=776965
Joshua Bloch, 获得过Jolt最畅销奖的《Effective Java》的作者, 是Sun Microsystems的杰出工程师和Transarc的资深系统设计师, J2SE 5.0 Tiger的代言人和领路人, 也是还是JSR166的发起人之一..
后来, Joshua Bloch去了Google, 成为了Google的首席工程师
Joshua Bloch拥有卡耐基.梅隆大学(CMU)计算机科学的博士学位。
在最近Joshua Bloch的一篇文章里, Joshua Bloch回忆了当年在CMU上课的时候, vividly Jon Bentley 第一节算法课, 就要求所有刚进来的PHD学生, 每人都写一个二分查找算法. 然后发现, 多数人的算法都存在BUG, 这在当时给了Joshua Bloch 一个很深的印象..
在之后, Joshua Bloch 负责java.util.Arrays 代码编写的时候, 采用了Bentley 在<<Programming Pearls >>一书中的二分查找算法, 结果在8年后的今天, Joshua Bloch 发现, 这里面原来还是有一个BUG.
问题到底是出在哪里? 竟然逃过了Bentley 和Joshua Bloch 的双重检测?
一起来看看java.util.Arrays的代码:
1: public static int binarySearch(int[] a, int key) {
2: int low = 0;
3: int high = a.length - 1;
4:
5: while (low <= high) {
6: int mid = (low + high) / 2; //jdk1.5:int mid = (low + high) >> 1;
7: int midVal = a[mid];
8:
9: if (midVal < key)
10: low = mid + 1;
11: else if (midVal > key)
12: high = mid - 1;
13: else
14: return mid; // key found
15: }
16: return -(low + 1); // key not found.
17: }
这是很经典的一个二分查找算法.
bug出现在第6行:
6: int mid =(low + high) / 2;
在一般情况下, 这个语句是不会出错的, 但是, 当low+high的值超过了最大的正int值 (231- 1) 的时候, mid会变成负值, 这个时候, 会抛出ArrayIndexOutOfBoundsException 异常.
所以当一个数组包含超过2的30次方 个元素的时候, 就很可能会带来问题... 当然, 在一般的应用里面, 很少数组会包含那么多元素, 但是现在这样的情况已经越来越多了, 比如Google的海量运算..
那如何解决这个问题?
很简单, 修改这行语句为:
6: int mid = low + ((high - low) / 2);
或者
6: int mid = (low + high) >>> 1;
在c或者c++中, 则可以如下实现:
6: mid = ((unsigned) (low + high)) >> 1;
- 转的一个jdk bug
- Sun JDK 1.6中String Constructor的一个bug
- Sun JDK 1.6中String Constructor的一个bug
- [转] smarttemplate 的一个BUG
- [转] smarttemplate 的一个BUG
- [转] smarttemplate 的一个BUG
- jdk版本导致的bug
- 安装jdk遇上的bug
- JDK中Stack的bug
- 打算写一个文章对 Sun JDK 的 bug 进行分析
- jdk bug
- 微软的一个bug?
- OracleParameter 的一个bug
- FireFox的一个bug
- 微软的一个BUG
- Tencent 的一个Bug
- 一个ComboBox的Bug
- WindowsXP的一个Bug
- 读心术(C)
- 查看ORACLE哪条SQL占资源最大
- 如何把oracle中的select sysdate from dual转化为SQL Server中的语句?
- windows Server 2003更改序列号
- xsl中循环取数据的问题
- 转的一个jdk bug
- c#.net 中压缩access并且更名
- 用VC写Assembly代码(6)--附录3[X86指令使用详解]
- SQLSERVER的排序规则
- 3G的前世今生
- c#.net下对获短路径
- 这届世界杯'不太冷'
- namespace和异常处理
- 奇怪的Tomcat