java反码算术运算求和,位运算的妙用,运算妙用
位運算的妙用,運算妙用
最近在學java,其實僅僅是在命令行里寫程序跟C語言沒有太大的區別,思想都是一樣的。遇到了一個比較新鮮(后來知道原來C中也有)的東西——位元算(又叫位操作)。多新鮮啊,畢向東老師說這次(現在正在學習的這次)使用位元算符將會是你們今后使用的唯一的一次,因為在開發中根本用不著。其實也差不多。不過見到了幾個應用,還是蠻有意思的,這里總結一下(萬一考試就考到了呢,呵呵)。
Java中共有7個位運算符:~(取反)、&(與)、|(或)、^(異或)、>>(右移)、<>>(無符號右移)。這里不在解釋位運算,只是談談幾種位運算的有趣用法。(不知道位運算?看看這里)
加密
1 一個數異或同一個數兩次還是原數;
2 計算機中的文件都是以二進制的形式來存儲的;
利用這兩個特性,我們就可以用^運算來給文件加密。例如將一個二進制文件中所有的數據都異或42這個數字,就得到了一個加密后的文件,“42”就是這個文件的“鑰匙”。將這個文件中的所有數據再異或42,就完成了“解密”的過程。
不增加新的變量來交換a b兩個變量的值
交換a b兩個變量的值,幾乎是每一個人在學編程的時候都要接觸的。現在我們想這個問題,我有兩個瓶子,A瓶裝著果汁,B瓶裝著醋,要是A瓶裝醋,B瓶裝果汁,如何做呢?通常,我們會用下面這段代碼:
int temp;
temp = a;
a = b;
b = temp;
這就像我們找來一個新瓶子C,先將果汁倒入新瓶子,然后醋倒入A,果汁再倒入B。這是很容易想到的辦法。那么如果沒有別的瓶子了呢?看看這個:
a = a + b; //此時a包含a 和 b
b = a - b;
a = a - b;
只有兩個瓶子,那么我們只好把它們倒在一起,然后將混合物中的果汁倒入B。不可思議是嗎?別急,我們將果汁和醋倒在一起的時候,B瓶還在,這可是程序呀,B瓶仍然裝著醋,這時我們就可以將(混合-醋)的值給B,也就是果汁,再將(混合-果汁)的值給A,完成!但是,這種方式有一個弊端:有可能a+b的值會超出int型的范圍。
基于同樣的想法,我們還可以用一下的代碼:
a = a ^ b;
b = a ^ b; //實際上是(a^b)^b 也就是a異或了b兩次,等號右邊是a的值
a = a ^ b; //此時b里面已經是“果汁”,實際上是(a^b)^a,也就是b異或了a兩次,是b
第一步之后,原來a占用了多少位依舊是多少位,絕對不會發生數據的溢出。
ps:為了程序的可讀性,真正開發時要慎用后兩種!
進制的轉換(10進制轉16進制為例)
接觸位運算之前,進制轉換我是這么操作的:
class turn10_16{
public static void main(String[] args){
int n=200; //n就是代轉換的數字
boolean out_turn=false; //輸出時用,去掉輸出時候高位上的‘0’
int[] s=new int[20]; //將轉換后的十六進制數存放在s[]數組中
while(n>0){
int i=0;
s[i]++;
while(s[i]>15){ //逢16進一,并且檢查下一位
//是不是16,如果是,再進一
s[i]=0;
i++;
s[i]++;
}
n--; //數完一個之后n--,知道數完n個數
}
for(int i=19;i>=0;i--){
if(out_turn == false){ //這個if是為了去掉最高位上的0,
// 其中out_turn作為開關;
if(s[i]==0)
continue;
else{
out_turn=true;
i++;
}
}
else{ //輸出轉換之后的結果,10輸出A,類推
if(s[i]<10)
System.out.print(s[i]);
else
System.out.print((char)('A'+(s[i]-10)));
}
}
System.out.println();
}
}
這種轉換就像數數,一共有多少個,我來用十六進制的方法再數一遍,逢16進1,數完為止。這種方法的弊端就是效率低,而且不能轉換負數。
我們知道,10進制的數據在計算機中使用2進制來存儲的,而16進制的出現也是為了閱讀性強,使4個位置放在一起計數。那么理論上,用“位運算”來操作,效率肯定會高。
class turn10_16{
public static void main(String[] args){
int n=200; //n就是代轉換的數字
boolean out_turn=false; //輸出時用,去掉輸出時候高位上的‘0’
int[] s=new int[20]; //將轉換后的十六進制數存放在s[]數組中
for(int i=0;i<=8;i++){ //int型占用了8個byte位置,每個byte即一個16進制,
//每次保留一個byte并且轉換成16進制,至少要8次(可以優化)
int temp= n & 15; //與0000-0000 0000-0000 0000-0000 0000-1111進
// 行&運算,只保留最后4個位置即“個位”上的數
s[i]=temp; //將這個數賦給個位
n=n>>>4; //無符號右移4個位置,再保留出十位上的數
}
for(int i=19;i>=0;i--){
if(out_turn == false){ //這個if是為了去掉最高位上的0,其中out_turn作為
//開關;
if(s[i]==0)
continue;
else{
out_turn=true;
i++;
}
}
else{ //輸出轉換之后的結果,10輸出A,類推
if(s[i]<10)
System.out.print(s[i]);
else
System.out.print((char)('A'+(s[i]-10)));
}
}
System.out.println();
}
}
總結:如此看來,位元算還是很有必要學習的?;谟嬎銠C只認識0和1,很多關于內存的操作用位運算效率會提高不少,畢竟我們是與計算機打交道。像 *2/2運算、取絕對值運算,取相反數運算等等,直接對內存進行移位或者反碼,快了不少。
無論學習什么東西,基礎、原理性質的東西一定要好好學。不要以為用的少了就不重視。
更多位元算的功能:911博客??csdn/人在江湖
總結
以上是生活随笔為你收集整理的java反码算术运算求和,位运算的妙用,运算妙用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vue上传文件到php,vue+axio
- 下一篇: java 没有提示信息,ActionEr