Java利用位運(yùn)算實(shí)現(xiàn)加減乘除的方法詳解
前言
我們經(jīng)常使用的加減乘除,我們所看到的只是表面的效果,那么加減乘除在底層究竟是怎么實(shí)現(xiàn)的?今天就讓我們一探究竟.今天用位運(yùn)算實(shí)現(xiàn)的加減乘除不使用任何的加減乘除符號.
一、常見位運(yùn)算
1. &運(yùn)算
&運(yùn)算二進(jìn)制每一位全1為1,否則為0
public static void main(String[] args) { int a = 1; int b = 3; System.out.println(a & b); }
2. |運(yùn)算
|運(yùn)算二進(jìn)制每一位有1為1,全0為0
public static void main(String[] args) { int a = 1; int b = 3; System.out.println(a | b); }
3. ^運(yùn)算
^運(yùn)算二進(jìn)制每一位不同為1,相同為0
public static void main(String[] args) { int a = 1; int b = 3; System.out.println(a ^ b); }
4. ~運(yùn)算
~運(yùn)算是二進(jìn)制每一位按位取反.
public static void main(String[] args) { int a = 1; System.out.println(~a); }
二、位運(yùn)算實(shí)現(xiàn)加法
public static void main(String[] args) { int a = 1; int b = 3; System.out.println(a + b); }
下來我們用位運(yùn)算實(shí)現(xiàn)一下加法.
我們進(jìn)行一次異或運(yùn)算就相當(dāng)于進(jìn)行一次無進(jìn)位加法,那這樣也不能實(shí)現(xiàn)加法,那我們得想辦法,實(shí)現(xiàn)進(jìn)位的數(shù)值.
進(jìn)行一次與運(yùn)算,只有同時(shí)為1才為1,也當(dāng)同時(shí)為1時(shí),我們需要進(jìn)位,所以我們進(jìn)行與運(yùn)算后進(jìn)行左移一位的操作,即可得到進(jìn)位后的數(shù)值.
我們對異或運(yùn)算和與運(yùn)算后左移一位的結(jié)果進(jìn)行相加即可,但我們只能進(jìn)行位運(yùn)算,所以我們只能再次進(jìn)行異或運(yùn)算與與運(yùn)算,直到云運(yùn)算的結(jié)果為0時(shí),我們的異或運(yùn)算的結(jié)果即為加法的結(jié)果.
public static int bitAdd(int a,int b) { int sum = 0; while(b != 0) { sum = a ^ b; b = (a & b) << 1; a = sum; } return sum; } public static void main(String[] args) { System.out.println(bitAdd(1,2)); }
三、位運(yùn)算實(shí)現(xiàn)減法
public static void main(String[] args) { int a = 1; int b = 3; System.out.println(a - b); }
下來我們用位運(yùn)算實(shí)現(xiàn)一下減法.
在我們有了位運(yùn)算實(shí)現(xiàn)加法的基礎(chǔ)之后,我們的減法就變得簡單了,a - b == a + ( -b ),所以我們只需要將b變?yōu)?b即可實(shí)現(xiàn)減法功能,但我們不能使用負(fù)號,那我們來用位運(yùn)算來實(shí)現(xiàn)一下.
public static void main(String[] args) { System.out.println(~3); }
我們可以發(fā)現(xiàn)一個(gè)數(shù)取反與相反數(shù)差一,我們?nèi)》醇右患纯傻玫较喾磾?shù).
public static void main(String[] args) { System.out.println(~3 + 1); }
public static int bitAdd(int a,int b) { int sum = 0; while(b != 0) { sum = a ^ b; b = (a & b) << 1; a = sum; } return sum; } public static int bitSub(int a,int b) { return bitAdd(a,~b+1); } public static void main(String[] args) { System.out.println(bitSub(1,3)); }
四、位運(yùn)算實(shí)現(xiàn)乘法
public static void main(String[] args) { int a = 1; int b = 3; System.out.println(a * b); }
我們小學(xué)的時(shí)候是怎么進(jìn)行乘法的,按位相乘,每一位和每一位相乘.
二進(jìn)制中也是一樣的,按位相乘,如果被乘數(shù)二進(jìn)制位是1則與乘數(shù)相乘.每次運(yùn)算進(jìn)行移位
public static int bitAdd(int a,int b) { int sum = 0; while(b != 0) { sum = a ^ b; b = (a & b) << 1; a = sum; } return sum; } public static int bitMul(int a,int b) { int sum = 0; while(b != 0) { if((b & 1) != 0) { sum += a; } a <<= 1; b >>>= 1; } return sum; } public static void main(String[] args) { System.out.println(bitMul(1,3)); }
五、位運(yùn)算實(shí)現(xiàn)除法
public static void main(String[] args) { int a = 7; int b = 2; System.out.println(a / b); }
我們在用位運(yùn)算實(shí)現(xiàn)除法時(shí),采用逆推的方式,a / b = c,
a = c * b。
我們只需要求出a減去b向左的移位,只要滿足a <= b的移位即可,每次移動(dòng)多少位即a / b的結(jié)果二進(jìn)制中某一位為1,以此循環(huán)倒推即可.
public static int bitAdd(int a,int b) { int sum = 0; while(b != 0) { sum = a ^ b; b = (a & b) << 1; a = sum; } return sum; } public static int negNum(int n) { //轉(zhuǎn)化為相反數(shù) return bitAdd(~n,1); } public static int minus(int a,int b) { //實(shí)現(xiàn)兩個(gè)數(shù)相減 return bitAdd(a,negNum(b)); } public static boolean isNeg(int n) { //判斷是否為負(fù)數(shù) return n < 0; } public static int bitDiv(int a,int b) { int x = isNeg(a) ? negNum(a) : a; int y = isNeg(b) ? negNum(b) : b; int res = 0; for (int i = 30; i >= 0 ; 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 static void main(String[] args) { int a = 7; int b = 2; System.out.println(bitDiv(a,b)); }
到此這篇關(guān)于Java利用位運(yùn)算實(shí)現(xiàn)加減乘除的方法詳解的文章就介紹到這了,更多相關(guān)Java位運(yùn)算 加減乘除內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
idea?http?request無法識別環(huán)境變量的解決步驟
AlibabaCloudToolkit插件安裝后在?Editor->File?Types增加?AlibabaCloudROStemplates(JSON)項(xiàng)且會配置為解析*.json?文件,導(dǎo)致http?client無法正確解析http-client.env.json文件而無法讀取環(huán)境變量,本文介紹idea?http?request無法識別環(huán)境變量問題,需要的朋友可以參考下2023-08-08java文件下載代碼實(shí)例(單文件下載和多文件打包下載)
這篇文章主要介紹了java文件下載代碼實(shí)例(單文件下載和多文件打包下載),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12java.net.MalformedURLException異常的解決方法
下面小編就為大家?guī)硪黄猨ava.net.MalformedURLException異常的解決方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-05-05云服務(wù)器環(huán)境搭建及部署(jdk、mysql、redis、nginx環(huán)境搭建)詳細(xì)步驟
這篇文章主要給大家介紹了關(guān)于云服務(wù)器環(huán)境搭建及部署(jdk、mysql、redis、nginx環(huán)境搭建)詳細(xì)步驟的相關(guān)資料,要在云服務(wù)器上搭建JDK、MySQL、Redis和Nginx的環(huán)境,可以按照以下步驟進(jìn)行操作,需要的朋友可以參考下2024-01-01淺談SpringCloud feign的http請求組件優(yōu)化方案
這篇文章主要介紹了淺談SpringCloud feign的http請求組件優(yōu)化方案,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02