日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

只用位运算不用算术运算实现

發布時間:2025/4/5 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 只用位运算不用算术运算实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目

  給定兩個32位整數a和b,可正、可負、可0.不能使用算術運算符,分別實現a和b的加減乘除。

要求

  如果給定的a和b執行加減乘除的某些結果本來就會導致數據的溢出,那么你實現的函數不必對那些結果負責。

基本思路

 加法運算

  使用位運算實現加法運算主要分為兩個部分。先計算完全不考慮進位進行相加的結果,再計算只考慮進位的產生值。將兩個結果相加就是最終的結果。

  例如:?
  a:    001010101?
  b:    000101111

首先不考慮進位進行相加,結果為001111010,該結果其實就是a ^ b。

再考慮進位的產生值,結果為000001010,該結果其實就是(a & b)<< 1。

將1、2產生的結果再相加,此時依然要考慮兩部分:不考慮進位和只考慮進位。

一直重復上述步驟,直到進位產生的值全部消失。
?

private int add(int a,int b){int sum = a;while(b!=0){sum = a^bb = (a&b) << 1a = sum}return sum}

減法運算

實現a - b只要實現a + (-b)即可。所以只要將a和b的相反數調用add函數就行。根據二進制數在機器中表達的規則,得到一個數的相反數,就是這個數的二進制數表達取反加1(補碼)的結果

public int negNum(int n){return add(~n,1) }public int minus(int a,int b){return add(a,negNum(b)) }

乘法運算

用位運算實現乘法運算。a × b的結果可以寫成 a?20?b0+a?21?b1+...a?2i?bi+...a?231?b31a?20?b0+a?21?b1+...a?2i?bi+...a?231?b31. 其中bibi為0或1表示整數b的二進制表達中第i位的值(從右往左數)。該過程有點類似于求整數的N次方問題。具體實現參照如下代碼
?

public int multi(int a,int b){int res = 0;while(b!=0){if((b&1)!=0){res = add(res,a);}a <<= 1;b >>= 1;}return res; }

除法運算

  用位運算實現除法運算其實就是乘法的逆運算。定義 res 表示除法的結果。首先將a向右移位31位,然后看能不能容下b,如果能,說明a/231a/231可以包含一個b,等價于a可以包含一個b?231b?231,令res的第31位為1,此時a的值應該為a?b?231a?b?231;如果不能容下b,令res的第31位為0,a的值不變;接下來將a向右移位30位是否能容下b……重復步驟直到a?b?2i=0a?b?2i=0。?
  以上過程只適用于a和b都不是負數的情況下,當a或b為負數時,可以先將a和b轉成正數,計算完之后再判斷res的真實符號就行。?
  除法實現到這一步已經可以解決絕大多數情況了。但是我們知道,32位最小整數的絕對值要比最大整數大,所以如果a或b等于最小值,是不能轉換成相對應的正數的。這時候需要分情況考慮:

如果a和b都為最小值,直接返回1

如果a不為最小值,而b為最小值,那么a/b = 0,直接返回0

如果a為最小值,而b不為最小值。這時我們對a無能為力,但是我們可以讓a增大一點點,計算出一個結果然后再修正一下就可以得到最終的結果。處理過程如下:

  <1>計算(a+1)/b(a+1)/b,結果記為c?
  <2>計算c?bc?b?
  <3>計算(a?c?b)/b(a?c?b)/b,結果記為rest?
  <4>計算c+rest
?

public boolean isNeg(int n){return n<0; }public int div(int a,int b){int x = isNeg(a) ? negNum(a):a;int y = isNeg(b) ? negNum(b):b;int res = 0;for (int i = 31;i>-1;i=minus(i,1)){if ((x>>i)>=y){res |= (1<<i);x = minus(x,y<<i);}}return isNeg(a)^isNeg(b) ? negNum(res):res; }public int divide(int a,int b){if(b==0){throw new RuntimeException("divisor is 0");}if (a == Integer.MIN_VALUE && b == Integer.MIN_VALUE){return 1;}else if (b == Integer.MIN_VALUE){return 0;}else if (a == Integer.MIN_VALUE){int res = div(add(a,1),b);return add(res,div(minus(a,multi(res,b)),b));}else{return div(a,b);} }

?

總結

以上是生活随笔為你收集整理的只用位运算不用算术运算实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。