2010-03-09 60 views
5

在論文中,二進制運算很簡單,但作爲一個初學程序員,我發現想出二進制數的加法,減法,乘法和除法算法有點困難。Java中的二元運算算法

我有兩個二進制數作爲字符串存儲,假設任何前導零被刪除。我將如何去執行這兩個數字的這些操作?

編輯:我需要避免將它們轉換爲int或long。

+1

你想了解如何實現實際的算法或只是用這些字符串做算術運算嗎? – Daff 2010-03-09 21:19:42

+2

http://stackoverflow.com/questions/1218149/arbitrary-precision-arithmetic-explanation – paxdiablo 2010-03-09 21:24:10

+0

達夫,我想學習如何實現算法。 – 2010-03-09 21:37:25

回答

4

下面的代碼實現二進制加法,但實際上並沒有做任何算術,二進制或其他。實際的「添加」是由lookupTable完成的,其他一切都是直接的字符串操作。我寫它的目的是使其儘可能具有指導性,強調過程而不是效率。希望能幫助到你。

public class BinaryArithmetic { 
    static String[] lookupTable = { 
     "0+0+0=00", 
     "0+0+1=01", 
     "0+1+0=01", 
     "0+1+1=10", 
     "1+0+0=01", 
     "1+0+1=10", 
     "1+1+0=10", 
     "1+1+1=11", 
    }; 
    static String lookup(char b1, char b2, char c) { 
     String formula = String.format("%c+%c+%c=", b1, b2, c); 
     for (String s : lookupTable) { 
      if (s.startsWith(formula)) { 
       return s.substring(s.indexOf("=") + 1); 
      } 
     } 
     throw new IllegalArgumentException(); 
    } 
    static String zeroPad(String s, int length) { 
     while (s.length() < length) { 
      s = "0" + s; 
     } 
     return s; 
    } 
    static String add(String s1, String s2) { 
     int length = Math.max(s1.length(), s2.length()); 
     s1 = zeroPad(s1, length); 
     s2 = zeroPad(s2, length); 
     String result = ""; 
     char carry = '0'; 
     for (int i = length - 1; i >= 0; i--) { 
      String columnResult = lookup(s1.charAt(i), s2.charAt(i), carry); 
      result = columnResult.charAt(1) + result; 
      carry = columnResult.charAt(0); 
     } 
     if (carry == '1') { 
      result = carry + result; 
     } 
     return result; 
    } 
    public static void main(String args[]) { 
     System.out.println(add("11101", "1001")); 
    } 
} 

雖然我們在這,我還不如做multiply了。

static String multiply(String s1, String s2) { 
    String result = ""; 
    String zeroSuffix = ""; 
    for (int i = s2.length() - 1; i >= 0; i--) { 
     if (s2.charAt(i) == '1') { 
      result = add(result, s1 + zeroSuffix); 
     } 
     zeroSuffix += "0"; 
    } 
    return result; 
} 
11

二進制字符串爲int:

int i = Integer.parseInt("10101011", 2); 
int j = Integer.parseInt("00010", 2); 

然後,你可以做任何你與兩個整數討好,如:

i = i + j; 
i = i - j; 

而且讓他們回到一個二進制字符串:

String s = Integer.toBinaryString(i); 
+0

對不起,我應該注意到我需要避免將它們轉換爲int或long。 – 2010-03-09 21:32:52

1

將二進制字符串轉換爲整數,然後對整數進行操作,例如

String add(String s1, String s2) { 
    int i1 = Integer.parseInt(s1); 
    int i2 = Integer.parseInt(s2); 
    return Integer.toBinaryString(i1 + i2); 
} 
5

的算法,維基百科:

增加:

在 二進制最簡單的算術運算是加法。添加兩個 個位數的二進制數是 相對簡單,使用 攜帶的一種形式:

0 + 0 → 0 
0 + 1 → 1 
1 + 0 → 1 
1 + 1 → 0, carry 1 (since 1 + 1 = 0 + 1 × 10 in binary) 

添加兩個「1」的位數產生一個數字 「0」,而1將具有被添加到 下一列。

減法

減法工作在幾乎相同的 方式:

0 − 0 → 0 
0 − 1 → 1, borrow 1 
1 − 0 → 1 
1 − 1 → 0 

減去從 「0」 數字 「1」 位產生數字「1 「,而1 必須從 下一列中減去。這被稱爲 借用。原理與攜帶的原理相同。當減法的結果小於0,數字的最小可能值 過程是「借」赤字 除以左邊的基數(即,10/10) ,減去它從 下一個位置值。

乘法

乘法二進制類似於 十進制對口。兩個數字甲 和B可通過部分 產品相乘:在B中的每個位,在阿那位的 產物 計算並寫在一個新行, 向左移動,使得其最右邊 位線與已使用B 中的數字。所有這些 部分產品的總和給出了最終的 結果。

由於僅存在兩個在 二進制數字,僅存在兩個每個部分 乘法的可能 的結果:

* If the digit in B is 0, the partial product is also 0 
* If the digit in B is 1, the partial product is equal to A 

例如,二進制數1011 和1010相乘如下:

 

      1 0 1 1 (A) 
      × 1 0 1 0 (B) 
      --------- 
      0 0 0 0 ← Corresponds to a zero in B 
    +  1 0 1 1  ← Corresponds to a one in B 
    + 0 0 0 0 
    + 1 0 1 1  
    --------------- 
    = 1 1 0 1 1 1 0 
0

內置BitSet類是很直接給我們e用於位級操作。

2

二進制運算作業比更熟悉基座10確實沒有不同讓我們除了例如

    (1)  (1) 
182  182  182  182  182 
845  845  845  845  845 
--- + --- + --- + --- + --- + 
      7  27  027  1027 

所以,你做了什麼?您將要添加的數字對齊,然後從右向左進行操作,每次添加一位數字,並根據需要向左移+1。

在二進制中,過程完全相同。事實上,它更簡單,因爲你現在只有2個「數字」,0和1!

   (1)       (1)  (1) 
11101  11101  11101  11101  11101  11101  11101 
1001  1001  1001  1001  1001  1001  1001 
----- + ----- + ----- + ----- + ----- + ----- + ----- + 
       0   10  110  0110  00110  100110 

操作的其餘部分的工作同樣也:您使用的基地10相同的過程,適用於基地2.再次,由於只有2個「數字」 0和1,它實際上更簡單。這種簡單性就是爲什麼硬件喜歡二進制系統。