我正在编写这个python程序,以便能够理解如何实现乘法算法。我把一个'主人'复制我的所有工作和我的所有说明以及我所做的工作,以便不必浪费时间翻阅3-4个文件。我的问题是如何开始使用shift_left函数和binary_multiplaction函数。我不明白如何开始使用它。
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()
答案 0 :(得分:1)
你不远了,已经完成了添加和转移的艰难部分。
您的shift_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
你的测试很顺利......