Python二进制乘法算法?

Python二进制乘法算法?,python,algorithm,python-3.x,binary,multiplication,Python,Algorithm,Python 3.x,Binary,Multiplication,我写这个python程序是为了理解如何实现乘法算法。为了不浪费时间在3-4个文件之间切换,我已经将我所有的工作、所有的说明和我所做的事情整理成一份“主”副本。我的问题是如何开始使用shift_left函数和binary_Multipaction函数。我不知道如何开始 import unittest import sys def binary_addition( a, b ): """ Binary addition. :param a: the first operand - a tupl

我写这个python程序是为了理解如何实现乘法算法。为了不浪费时间在3-4个文件之间切换,我已经将我所有的工作、所有的说明和我所做的事情整理成一份“主”副本。我的问题是如何开始使用shift_left函数和binary_Multipaction函数。我不知道如何开始

import unittest
import sys


def binary_addition( a, b ):
"""
Binary addition.

:param a: the first operand - a tuple of bits
:param b: the second operand - a tuple of bits
:type a: tuple
:type b: tuple
:return: the sum, as a tuple of bits
:rtype: tuple
"""

# first, ensure that the 2 arrays have the same number of bits,
# by filling in with 0s on the left of the shortest operand
diff = len(a)-len(b)

if diff > 0:
    # concatenating a tuple of size <diff> with tuple b (all elements are 0s)
    b = ((0,) * diff) + b   
elif diff < 0:
    # concatenating a tuple of size <-diff> with tuple a (all elements are 0s)
    a = ((0,) * (-diff)) + a 

c = 0
s = [0] * (len(a)+1)
for j in reversed(range(0,  len(a))):
        d = (a[j] + b[j] + c) // 2
        s[j+1] = (a[j] + b[j] + c) - 2*d
        c = d
s[0] = c

# removing unneeded 0s on the left
if s[0] == 0:
    s.remove(0)

return tuple(s)


def shift_left(a,n):
"""
Shift an array of bits to the L, by adding n 0s on the right.

#. construct a tuple of n elements, all 0s

#. concatenate it to the tuple that has been passed in

#. return the concatenation

:param a: a tuple of bits
:param n: the number of positions over which to shift
:type a: tuple
:return: if n > 0, the L-shifted array; otherwise, the original array; *if the first parameter (`a` ) is not of the `tuple` type, the function should handle it nicely and return an empty tuple. A test in the test suite below checks that this requirement has been met.*
:rtype: tuple
"""
#
return a + (0,) * n


def binary_multiplication(a, b):
"""
Multiply arrays of bits.

#. Initialize the cumulative sum of product (a tuple with 0 as its only element)

#. Go over the bits in `b` (the second multiplicand), in *reverse order*: if current bit is 1, add to the cumulative sum the operand `a`, L-shifted by 0 for rightmost bit, by 1 for bit k-1, by 2 for bit k-2, ...

#. return the cumulative sum

:param a: first multiplicand - an array of bits
:param b: second multiplicand - an array of bits
:type a: tuple
:type b: tuple
:return: an array of bits
:rtype: tuple
"""

#



class Multiplication_unittest( unittest.TestCase):


def test_binary_addition_1(self):
    self.assertEqual( binary_addition((1,0,1),(1,1,1,1)), (1,0,1,0,0))

def test_binary_addition_2(self):
    self.assertEqual( binary_addition((1,1,1,1),(1,0,1)), (1,0,1,0,0))

def test_binary_addition_3(self):
    self.assertEqual( binary_addition((1,0,1,1),(1,1,1,1)), (1,1,0,1,0))

def test_binary_addition_4(self):
    self.assertEqual( binary_addition((0,),(1,)), (1,))

def test_binary_addition_5(self):
    self.assertEqual( binary_addition((1,),(1,)), (1,0))

def test_binary_addition_6(self):
    self.assertEqual( binary_addition((0,),(0,)), (0,))


def test_shift_left_1(self):
    """ Trying to shift a value that is _not_ a tuple (ex. an integer) returns an empty tuple """
    self.assertEqual( shift_left( 5, 3 ), () )


def test_shift_left_2(self):
    """ Shifting by 0 places returns the array that has been passed in """
    self.assertEqual( shift_left((1,1), 0 ), (1,1) )


def test_shift_left_3(self):
    """ Shifting an empty tuple by 1 place return a tuple with 0 as a single element """
    self.assertEqual( shift_left((), 1 ), (0,) )


def test_shift_left_4(self):
    """ Shifting a 1-tuple (with 0 as the only element) by 1 place """
    self.assertEqual( shift_left((0,), 1 ), (0,0) )


def test_shift_left_5(self):
    """ Shifting a 1-tuple (with 1 as the only element) by 1 place """
    self.assertEqual( shift_left((1,), 1 ), (1,0) )


def test_shift_left_6(self):
    """ Shifting 110 (6) by 3 places returns 110000 (6x8=48) """
    self.assertEqual( shift_left((1,1,0), 3 ), (1,1,0,0,0,0) )


def test_multiplication_1(self):
    """ Short operands: 0 x 0 """
    self.assertEqual( binary_multiplication( (0,),(0,)), (0,))  

def test_multiplication_2(self):
    """ Short operands: 0 x 1 """
    self.assertEqual( binary_multiplication( (0,),(1,)), (0,))  

def test_multiplication_3(self):
    """ Short operands: 1 x 0 """
    self.assertEqual( binary_multiplication( (1,),(0,)), (0,))  

def test_multiplication_4(self):
    """ Short operands: 1 x 1 """
    self.assertEqual( binary_multiplication( (1,),(1,)), (1,))  

def test_multiplication_5(self):
    """ Short operands 2 x 1"""
    self.assertEqual( binary_multiplication( (1,0),(1,)), (1,0))  

def test_multiplication_6(self):
    """ Long operands """
    self.assertEqual( binary_multiplication( (1,0,1,1,1,1,0,1),(1,1,1,0,1,1,1,1)), (1,0,1,1,0,0,0,0,0,1,1,1,0,0,1,1))  

def test_multiplication_5(self):
    """ Operands of different sizes """
    self.assertEqual( binary_multiplication( (1,0,0,1,1),(1,1,1,0,1,1,1,1)), (1,0,0,0,1,1,0,1,1,1,1,0,1)) 




def main():
  unittest.main()

if __name__ == '__main__':
   main()
导入单元测试
导入系统
def二进制_添加(a、b):
"""
二元加法。
:param a:第一个操作数-位元组
:param b:第二个操作数-位元组
:类型a:元组
:类型b:元组
:return:以位元组形式表示的总和
:rtype:tuple
"""
#首先,确保两个阵列的位数相同,
#通过在最短操作数的左侧填入0
差异=透镜(a)-透镜(b)
如果差异>0:
#将大小为的元组与元组b连接(所有元素均为0)
b=((0,)*diff)+b
elif差异<0:
#将大小为的元组与元组a连接(所有元素均为0)
a=((0,)*(-diff))+a
c=0
s=[0]*(len(a)+1)
对于反向的j(范围(0,len(a)):
d=(a[j]+b[j]+c)//2
s[j+1]=(a[j]+b[j]+c)-2*d
c=d
s[0]=c
#删除左侧不需要的0
如果s[0]==0:
s、 删除(0)
返回元组
def左换档(a,n):
"""
通过在右侧添加n0,将一个位数组移位到L。
#.构造一个包含n个元素的元组,所有元素均为0
#。将其连接到已传入的元组
#.返回连接
:param a:位的元组
:param n:要移动的位置数
:类型a:元组
:return:如果n>0,则为L移位数组;否则为原始数组;*如果第一个参数(`a`)不是`tuple`类型,则函数应该很好地处理它并返回一个空元组。下面测试套件中的测试将检查是否满足此要求*
:rtype:tuple
"""
#
返回a+(0,)*n
def二进制_乘法(a,b):
"""
将位数组相乘。
#.初始化乘积的累积和(一个元组,其唯一元素为0)
#.按*相反的顺序遍历“b”(第二个被乘数)中的位:如果当前位为1,则将操作数“a”与累积和相加,最右边的位L移位0,位k-1移位1,位k-2移位2。。。
#.返回累计金额
:param a:第一个被乘数-位数组
:param b:第二个被乘数-位数组
:类型a:元组
:类型b:元组
:return:一个位数组
:rtype:tuple
"""
#
类乘法\u unittest(unittest.TestCase):
def测试_二进制_添加_1(自身):
self.assertEqual(二元加法((1,0,1)、(1,1,1,1)),(1,0,1,0,0))
def测试_二进制_添加_2(自身):
self.assertEqual(二元加法((1,1,1,1),(1,0,1)),(1,0,1,0,0))
def测试_二进制_添加_3(自身):
self.assertEqual(二元加法((1,0,1,1)、(1,1,1)),(1,1,0,1,0))
def测试_二进制_添加_4(自身):
self.assertEqual(二元加法((0,),(1,),(1,))
def测试_二进制_添加_5(自身):
self.assertEqual(二元加法((1,),(1,),(1,0))
def测试_二进制_添加_6(自身):
self.assertEqual(二元加法((0,),(0,),(0,))
def测试\左换档\ 1(自):
“”“尝试移位非元组(例如整数)的值时返回空元组”“”
self.assertEqual(左移(5,3),())
def测试\左换档\ 2(自):
“”“按0位移位返回已传入的数组”“”
self.assertEqual(左移位((1,1,0),(1,1))
def测试_左换档_3(自):
“”“将空元组移位1位将返回一个元组,其中0作为单个元素”“”
self.assertEqual(左移((),1),(0,)
def测试换档左4(自):
“”“将1元组(0作为唯一元素)移位1位”“”
self.assertEqual(左移((0,1),(0,0))
def测试换档左5(自):
“”“将1元组(其中1是唯一的元素)移位1位”“”
self.assertEqual(左移((1,1,1,0))
def测试_左换档_6(自身):
“”“将110(6)移位3位返回110000(6x8=48)”
自组装质量(左移((1,1,0,3),(1,1,0,0,0))
def测试乘法1(自身):
“”“短操作数:0 x 0”“”
self.assertEqual(二进制乘法((0,),(0,),(0,))
def测试乘法2(自身):
“”“短操作数:0 x 1”“”
self.assertEqual(二进制乘法((0,),(1,),(0,))
def测试_乘法_3(自身):
“”“短操作数:1 x 0”“”
self.assertEqual(二进制乘法((1,),(0,),(0,))
def测试乘法4(自身):
“”“短操作数:1 x 1”“”
self.assertEqual(二进制乘法((1,),(1,),(1,)
def测试_乘法_5(自身):
“”“短操作数2 x 1”“”
self.assertEqual(二进制乘法((1,0),(1,),(1,0))
def测试_乘法_6(自身):
“长操作数”
self.assertEqual(二进制乘法((1,0,1,1,1,0,1),(1,1,1,0,1,1,1,1)),(1,0,1,1,0,0,0,0,0,1,1,1,1,0,1))
def测试_乘法_5(自身):
“”“不同大小的操作数”“”
self.assertEqual(二进制乘法((1,0,0,1,1)、(1,1,1,0,1,1,1)),(1,0,0,1,1,1,0,1,1,1))
def main():
unittest.main()
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
main()

你走得不远,已经完成了加法和移位的困难部分

对于
shift\u left
的测试中仍然存在错误,因为其中一个测试要求在当前引发异常时,移动非元组返回空元组。在这里,您可以说异常是正常的并更改测试,或者明确地测试操作数是元组

def shift_left(a,n):
    ...
    #
    if not isinstance(a, tuple): return ()
    return a + (0,) * n
完成此操作后,乘法就是将操作数1的乘积乘以操作数2的每个数字,将乘积(向左)移动到该数字的位置,然后将所有这些乘积相加。由于数字只能是0或1,它只给出:

def binary_multiplication(a, b):
    ...
    # initialize a null tuple of same size as a for the final sum
    s = (0,) * len(a)
    # take a copy of a for the intermediary products
    m = a[:]
    for i in reversed(range(len(b))):
        if b[i] != 0:     # when digit is one, add the intermediary product
            s = binary_addition(s, m)
        m = shift_left(m, 1)  # shift one per digit in b
    return s

你的考试通过得很好……

这是一个家庭作业问题吗?是的,我不知道还能去哪里。顺便告诉你,那条蟒蛇