亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

關于二分時最容易出現的溢出問題

標簽:
Java

比如我之前写的一片文章的部分代码https://blog.csdn.net/qq_34115899/article/details/79526538

  1. public int rank(int key, int n) {    

  2.        int lo = 0, hi = n - 1;    

  3.        while (lo <= hi) {    

  4.            int mid = lo + ((hi - lo) >> 1); //>>1是除以2  也可以直接(lo + hi) >>> 1  

  5.            // 为什么不直接(lo+hi)>>1呢,因为lo+hi可能溢出,而hi-lo不溢出,lo+(hi-lo)>>1是小于hi的,也不溢出,更安全    

  6.            int cmp = key - a[mid];// a为有序数组    

  7.            if (cmp < 0) {    

  8.                hi = mid - 1;    

  9.            } else if (cmp > 0) {    

  10.                lo = mid + 1;    

  11.            } else {    

  12.                return mid;    

  13.            }    

  14.        }    

  15.        return lo;    

  16.    }    

我在上面的mid处理方法就是用的

int mid = lo + ((hi - lo) >> 1); 这种方法不限于语言,是各种编程语言通用的防溢出写法

在java中有 >>> 运算符

我发现Arrays.binarySearch()方法在处理mid时

int mid = (low + high) >>> 1;


Java中的位运算符:

>>表示算术右移,如果该数为正,则高位补0,若为负数,则高位补1;

>>>表示逻辑右移,也称为无符号右移,即若该数为正,则高位补0,而若该数为负数,则右移后高位同样补0。


比如int范围 -2147483648~2147483647 

21亿多吧,如果在输入的时候超过int范围,编译器会报错,很明显就会知道自己错了。可是关键是输入的每个数字都很大,且没有超过int范围,但相加或者相乘操作超出了范围!!!这种情况很难查出来,会造成不必要的麻烦

>>>1操作非常好,举个例子

分别进行如下操作:

System.out.println(1500000000 + 1500000000);

System.out.println((1500000000 + 1500000000) >> 1);
System.out.println((1500000000 + 1500000000) >>> 1);

 显示

-1294967296  (150000000 + 1500000000  (15亿加15亿))

10110010110100000101111000000000

 -647483648  (>>1的情况)

11011001011010000010111100000000

1500000000 (>>>1的情况)

01011001011010000010111100000000    (正好就是相加除以2,也就是无符号右移一位)

再来一组例子

分别进行如下操作

System.out.println(1500000000 + 1200000000); // 15亿加12亿
System.out.println((1500000000 + 1200000000) >> 1);
System.out.println((1500000000 + 1200000000) >>> 1);

显示

-1594967296

10100000111011101011101100000000

-797483648  (>>1之后)

11010000011101110101110110000000

1350000000   (>>>1之后)

01010000011101110101110110000000  (正好就是相加除以2,也就是无符号右移一位)

综上所述,>>>1更安全,不会因为加法溢出而对结果产生影响。

但是>>>1只能解决加法溢出的问题,几乎是解决不了乘法溢出的问题(除非有类似乘以2再>>>1的巧合,高位数据是被截断的,没有保存),解决办法是选用更大的数据类型来处理乘法溢出问题。

原文出处

點擊查看更多內容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消