def test_Multi_pad_to_digits_with_variable_inputs(self): """Checks that Multi arrays are padded to the specified number of digits, instances of equal length are returned unchanged, and that a digit that is too low will return the original Multi instances""" three4 = Multi([zero, zero, one, one]) zero3 = Multi([zero, zero, zero]) zero4 = Multi([zero, zero, zero, zero]) one4 = Multi([zero, zero, zero, one]) self.assertEquals(tuple([str(m) for m in pad_to_digits(m_zero, 3)]), (str(zero3), )) self.assertEquals(tuple([str(m) for m in pad_to_digits(m_three, 4)]), (str(three4), )) self.assertEquals(tuple([str(m) for m in pad_to_digits(m_one, 1)]), (str(m_one), )) self.assertEquals(tuple([str(m) for m in pad_to_digits(m_three, 4)]), (str(three4), )) self.assertEquals( tuple([str(m) for m in pad_to_digits(m_zero, 4, m_one, m_eight)]), (str(zero4), str(one4), str(m_eight))) self.assertEquals( tuple([str(m) for m in pad_to_digits(m_eight, 4, m_one, m_eight)]), (str(m_eight), str(one4), str(m_eight))) self.assertEquals( tuple([str(m) for m in pad_to_digits(m_fourteen, 4, m_fifteen)]), (str(m_fourteen), str(m_fifteen)))
def from_num(num): "Helper function to create a 16-bit Multi instance using a number" bnum = bin(num) b = bnum.index('b') + 1 pos = Multi(Bit(digit) for digit in bnum[b:]) pos.insert(0, Bit(0)) pos = pad_to_digits(16, pos)[0] if bnum[0] == '-': neg = inc(~pos) if len(neg) > 16: return neg[1:] return Multi(neg) return Multi(pos)
def add_multi(m1, m2): "Adds two Multi instances by doing partial adds of the individual bits (indexed from the right), and returns a 16-bit Multi instance" m1, m2 = pad_to_digits(16, m1, m2) sum, carry = half_adder(m1[15], m2[15]) s = [sum] for i in range(14, -1, -1): sum = full_adder(m1[i], m2[i], carry)[0] # disjointed so that sum can use the old carry value instead of the new one carry = full_adder(m1[i], m2[i], carry)[1] s.append(sum) if len(s) > 16: assert len(s[1:]) == 16 return Multi(reversed(s[1:])) return Multi(reversed(s))
def add_multi(m1, m2): "Adds two Multi instances by doing partial adds of the individual bits (indexed from the right), and returns a 16-bit Multi instance" m1, m2 = pad_to_digits(16, m1, m2) sum, carry = half_adder(m1[15], m2[15]) s = [sum] for i in range(14, -1, -1): sum = full_adder( m1[i], m2[i], carry )[0] # disjointed so that sum can use the old carry value instead of the new one carry = full_adder(m1[i], m2[i], carry)[1] s.append(sum) if len(s) > 16: assert len(s[1:]) == 16 return Multi(reversed(s[1:])) return Multi(reversed(s))
def test_Multi_pad_to_digits_with_two_inputs(self): """Checks that Multi arrays are padded to the specified number of digits, instances of equal length are returned unchanged, and that a digit that is too low will return the original Multi instances""" three4 = Multi([zero, zero, one, one]) zero3 = Multi([zero, zero, zero]) zero4 = Multi([zero, zero, zero, zero]) one4 = Multi([zero, zero, zero, one]) self.assertEquals(tuple([str(m) for m in pad_to_digits(m_eight, 4, m_one)]), (str(m_eight), str(one4))) self.assertEquals(tuple([str(m) for m in pad_to_digits(m_one, 4, m_eight)]), (str(one4), str(m_eight))) self.assertEquals(tuple([str(m) for m in pad_to_digits(m_zero, 3, m_one)]), (str(zero3), str(m_one))) self.assertEquals(tuple([str(m) for m in pad_to_digits(m_three, 4, m_zero)]), (str(three4), str(zero4))) self.assertEquals(tuple([str(m) for m in pad_to_digits(m_one, 1, m_zero)]), (str(m_one), str(m_zero))) self.assertEquals(tuple([str(m) for m in pad_to_digits(m_three, 4, m_one)]), (str(three4), str(one4)))
def inc(m): "Increases a Multi instance and returns a 16-bit value" m, one = pad_to_digits(16, m, Multi([Bit(1)])) return add_multi(m, one)
def test_Multi_pad_to_digits_with_variable_inputs(self): """Checks that Multi arrays are padded to the specified number of digits, instances of equal length are returned unchanged, and that a digit that is too low will return the original Multi instances""" three4 = Multi([zero, zero, one, one]) zero3 = Multi([zero, zero, zero]) zero4 = Multi([zero, zero, zero, zero]) one4 = Multi([zero, zero, zero, one]) eight6 = Multi([zero, zero, one, zero, zero, zero]) one6 = Multi([zero, zero, zero, zero, zero, one]) zero6 = Multi([zero, zero, zero, zero, zero, zero]) zero8 = Multi([zero, zero, zero, zero, zero, zero, zero, zero]) three6 = Multi([zero, zero, zero, zero, one, one]) neg_one5 = Multi([one, one, one, one, one]) neg_one6 = Multi([one, one, one, one, one, one]) neg_one8 = Multi([one, one, one, one, one, one, one, one]) neg_two6 = Multi([one, one, one, one, one, zero]) neg_two8 = Multi([one, one, one, one, one, one, one, zero]) neg_three8 = Multi([one, one, one, one, one, one, zero, one]) # Checks output with two positive inputs self.assertEquals([str(m) for m in pad_to_digits(4, m_eight, m_one)], [str(m_eight), str(one4)]) self.assertEquals([str(m) for m in pad_to_digits(4, m_one, m_eight)], [str(one4), str(m_eight)]) self.assertEquals([str(m) for m in pad_to_digits(6, m_eight, m_one)], [str(eight6), str(one6)]) self.assertEquals([str(m) for m in pad_to_digits(6, m_one, m_eight)], [str(one6), str(eight6)]) self.assertEquals([str(m) for m in pad_to_digits(3, m_zero, m_one)], [str(zero3), str(m_one)]) self.assertEquals([str(m) for m in pad_to_digits(4, m_three, m_zero)], [str(three4), str(zero4)]) self.assertEquals([str(m) for m in pad_to_digits(4, m_three, m_one)], [str(three4), str(one4)]) # Checks that an exception is raised if digits is lower than the length of one or more Multi instances self.assertRaises(ValueError, pad_to_digits, *(1, m_one, m_zero)) self.assertRaises(ValueError, pad_to_digits, *(1, neg_three)) self.assertRaises(ValueError, pad_to_digits, *(6, m_eight, zero4, neg_two8)) self.assertRaises(ValueError, pad_to_digits, *(6, neg_two8, m_eight, zero4)) self.assertRaises(ValueError, pad_to_digits, *(6, neg_two8, neg_three8, zero4)) # Checks output with variable positive inputs self.assertEquals([str(m) for m in pad_to_digits(6, m_zero)], [str(zero6)]) self.assertEquals([str(m) for m in pad_to_digits(4, m_three)], [str(three4)]) self.assertEquals([str(m) for m in pad_to_digits(4, m_zero, m_one, m_eight)], [str(zero4), str(one4), str(m_eight)]) self.assertEquals([str(m) for m in pad_to_digits(4, zero3, m_three, m_eight)], [str(zero4), str(three4), str(m_eight)]) self.assertEquals([str(m) for m in pad_to_digits(6, m_eight, m_three, m_eight)], [str(eight6), str(three6), str(eight6)]) # Checks output with negative inputs self.assertEquals([str(m) for m in pad_to_digits(6, neg_one5)], [str(neg_one6)]) self.assertEquals([str(m) for m in pad_to_digits(8, neg_two6)], [str(neg_two8)]) self.assertEquals([str(m) for m in pad_to_digits(8, m_zero, neg_two8, neg_one5)], [str(zero8), str(neg_two8), str(neg_one8)]) self.assertEquals([str(m) for m in pad_to_digits(6, zero3, neg_one6, m_eight)], [str(zero6), str(neg_one6), str(eight6)])