【问题标题】:Algorithm for binary arithmetic in JavaJava中的二进制算术算法
【发布时间】:2011-01-25 15:19:40
【问题描述】:

在纸面上,二进制算术很简单,但作为一个初级程序员,我发现想出二进制数的加法、减法、乘法和除法算法有点困难。

我有两个二进制数存储为字符串,假设所有前导零都已被删除。我将如何对这两个数字执行这些操作?

编辑:我需要避免将它们转换为 int 或 long。

【问题讨论】:

标签: java algorithm string binary math


【解决方案1】:

二进制字符串转int:

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

那么你可以用这两个整数做任何你想做的事情,例如:

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

并将它们恢复为二进制字符串:

String s = Integer.toBinaryString(i);

【讨论】:

  • 抱歉,我应该注意到我需要避免将它们转换为 int 或 long。
【解决方案2】:

算法,来自维基百科:

加法:

最简单的算术运算 二进制是加法。添加两个 个位数的二进制数是 比较简单,使用一种形式 携带:

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”数字 digit 产生数字“1”,而 1 将不得不从 下一栏。这被称为 借贷。原理是一样的 至于携带。当一个结果 减法小于0,最少 一个数字的可能值, 程序是“借”赤字 除以基数(即 10/10) 从左边,减去它从 下一个位置值。

乘法:

二进制乘法类似于 它的十进制对应物。两个数字 A 和 B 可以乘以部分 产品:对于 B 中的每个数字, A中那个数字的乘积是 计算并写在新的一行, 向左移动,使其最右边 数字与 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 ← 对应于 B 中的零 + 1 0 1 1 ← 对应于 B 中的一个 + 0 0 0 0 + 1 0 1 1 --------------- = 1 1 0 1 1 1 0

【讨论】:

    【解决方案3】:

    下面的代码实现了二进制加法,但实际上并没有做任何算术、二进制或其他操作。实际的“加法”由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;
    }
    

    【讨论】:

      【解决方案4】:

      使用二进制算术实际上与更熟悉的以 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。这种简单性就是为什么硬件喜欢二进制系统。

      【讨论】:

        【解决方案5】:

        将二进制字符串转换为整数,然后对整数进行操作,例如

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

        【讨论】:

          【解决方案6】:

          内置的BitSet 类非常直接用于位级操作。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-02-27
            • 2014-01-16
            • 1970-01-01
            • 1970-01-01
            • 2015-09-25
            • 1970-01-01
            • 2010-10-14
            • 2019-03-25
            相关资源
            最近更新 更多