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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

位运算实现加减乘除四则运算(Java)

發布時間:2023/12/2 java 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 位运算实现加减乘除四则运算(Java) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文是繼《一文了解有趣的位運算》的第二篇文章.

我們知道,計算機最基本的操作單元是字節(byte),一個字節由8個位(bit)組成,一個位只能存儲一個0或1,其實也就是高低電平。無論多么復雜的邏輯、龐大的數據、酷炫的界面,最終體現在計算機最底層都只是對0101的存儲和運算。因此,了解位運算有助于提升我們對計算機底層操作原理的理解。

一、加法

兩個二進制數異或運算的結果是不考慮進位時的結果,

兩個二進制數與運算的結果中含有1的位是有進位的位。

以0101 + 0001 = 0110為例分析如下:

//計算 0101 + 0001 0101 ^ 0001 = 0100 //異或結果表明,如果不考慮進位,那么結果為0100 0101 & 0001 = 0001 //與運算結果表明,最低位需要向次低位進1 0001 << 1 = 0010 //與運算結果左移一位,將進位加到高位上//遞歸計算 0100 + 0010,直到+號右側數字為0

java代碼:

遞歸

public static int add(int a, int b) {if (b == 0) {return a;} else {return add(a ^ b, (a & b) << 1);} }

循環

public static int add2(int a, int b) {int sum = a;while (b != 0) {sum = a ^ b;b = (a & b) << 1;a = sum;}return sum; }

二、減法

與加法的思路一致,只不過減去一個數等于加一個數的相反數。

例如:5-1 = 5+(-1)。所以,我們只需要求出被減數的相反數即可。

如何求出一個數的相反數?

計算機中存儲的是二進制的補碼形式,正數的補碼與原碼相同,負數的補碼為對該數的原碼除符號位外各位取反,然后在最后一位加1。

例如:

1在計算機中的二進制表示為:0000 0001

-1在計算機中的二進制表示為:1111 1111

計算過程為:

-1的原碼:1000 0001

-1的反碼:1111 1110

-1的補碼:1111 1111

其中,由1的原碼(0000 0001)取反可得-1的反碼(1111 1110)

總結,一個數的相反數的求法就是該數每一位取反,末位加一。

java代碼:

public static int minus(int a, int b) {return add(a, add(~b, 1)); }

三、乘法

如果沒有思路,可以先在紙上筆算二進制乘法的過程:

0101 a× 0110 b----------------0000 0101 0101 + 0000 ----------------00011110

梳理下筆算二進制乘法的過程:

初始化乘積結果為0,依次遍歷數字b的末位 0→1→1→0,當末位為0時,乘積結果加上0,也就是乘積不變,A左移一位;當末位為1時,乘積結果加上A,A再左移一位。

如何遍歷數字b的末位呢?

根據前面所學,我們可以使用與運算取一個數的末位,并不斷右移數字b,直到數字b==0,即可結束位移。

需要注意的是正負數的符號問題,此處是先對a、b兩數的絕對值計算其乘積,最后再確定其符號。

java代碼為:

public static int multiply(int a, int b) {//將乘數和被乘數都取絕對值int A = a < 0 ? add(~a, 1) : a;int B = b < 0 ? add(~b, 1) : b;//計算絕對值的乘積int P = 0;while (B != 0) {if ((B & 1) != 0) { //取乘數的二進制的最后一位,0 or 1P = add(P, A);}A = A << 1;B = B >> 1;}//計算乘積的符號if ((a ^ b) < 0) {P = add(~P, 1);}return P; }

四、除法

最簡單的除法實現就是不停的用除數去減被除數,直到被除數小于除數時,此時所減的次數就是我們需要的商,而此時的被除數就是余數。

唯一需要注意的就是商的符號和余數的符號。商的符號確定方式也乘法是一樣,即同號為正,異號為負。而余數的符號和被除數的符號是一樣的。

和簡單的乘法實現一樣,這里我們要先對兩數的絕對值求商,求余數。最后再確定符號。

public static int[] divide(int a, int b) {//對被除數和除數取絕對值int A = a < 0 ? add(~a, 1) : a;int B = b < 0 ? add(~b, 1) : b;//對被除數和除數的絕對值求商int C = A; // 余數Cint N = 0; // 商Nwhile (C >= B) {C = minus(C, B); // C-BN = add(N, 1); // N+1}// 求商的符號if ((a ^ b) < 0) {N = add(~N, 1);}// 求余數的符合if (a < 0) {C = add(~C, 1);}return new int[]{N, C}; }

需要指出的是,這種算法在A很大、B很小的情況下效率很低,那該如何優化算法減少while循環的次數呢?

不難想到,除法是由乘法的過程逆推而來的。例如 9÷4=2...1,也就是2*4+1=9。假設用9去減4*2,可以得出結果等于1,因為1小于4,那么就可以得出9÷4的商是2,余數是1。

如何確定4的倍數是逼近最終結果的關鍵。我們知道,int 整型有32位,除首位表示符號位,每一位的大小是 [2^0, 2^1, 2^2, , , 2^30],最大的int整數是2^31-1。所以,我們可以依次將被除數與2^31, 2^30, ...2^3, 2^2, 2^1, 1相乘,如果除數大于它們的乘積,除數就與之相減,并用相減得到的余數繼續作為除數,直到循環結束。

java代碼:

public static int[] divide(int a, int b) {// 對被除數和除數取絕對值int A = a < 0 ? add(~a, 1) : a;int B = b < 0 ? add(~b, 1) : b;int N = 0; // 商 Nfor (int i = 31; i >= 0; i--) {// 未使用A>=(B<<i)進行判斷,因為只有左移B時舍棄的高位不包含1,才相當于該數乘以2的i次方.if ((A >> i) >= B) { // A ÷ 2^i >= BN += (1 << i); // N = N + 2^iA -= (B << i); // A = A - B*2^i}}int C = A; // 余數C// 求商的符號if ((a ^ b) < 0) {N = add(~N, 1);}// 求余數的符號if (a < 0) {C = add(~C, 1);}return new int[]{N, C}; }

轉載于:https://www.cnblogs.com/yueshutong/p/11481724.html

總結

以上是生活随笔為你收集整理的位运算实现加减乘除四则运算(Java)的全部內容,希望文章能夠幫你解決所遇到的問題。

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