Python 乘法中如何计算进位?

Python 乘法中如何计算进位?,python,Python,我在使用Python 2计算任何乘法问题中的进位数时遇到困难。我试图调整我已经制作的一个程序,它可以计算任何加法问题,但我似乎仍然无法使它工作。我目前正在学习Python的基础知识,所以我使用了非常简单的东西。任何关于如何将此程序转换为乘法的提示都将不胜感激 这是我为加法程序计算的结果: if len(str(x)) != len(str(y)): if len(x) > len(y): while len(x) > len(y): y

我在使用Python 2计算任何乘法问题中的进位数时遇到困难。我试图调整我已经制作的一个程序,它可以计算任何加法问题,但我似乎仍然无法使它工作。我目前正在学习Python的基础知识,所以我使用了非常简单的东西。任何关于如何将此程序转换为乘法的提示都将不胜感激

这是我为加法程序计算的结果:

if len(str(x)) != len(str(y)):
    if len(x) > len(y):
        while len(x) > len(y):
            y = '0' + y
    else:
        while len(y) > len(x):
            x = '0' + x
z = int(x) + int(y)
counter = 0
carries = 0
i = len(str(x))

while i > 1:
    i -= 1
    added = int((x[i])) + int((y[i])) + counter

    if added > 9:
        carries +=1
        counter = 1
    else:
        counter = 0

print str(x), '+', str(y), '=', z
print 'Number of carries: ', str(carries)

我假设通过进位次数,你想知道进位发生了多少次,而不是进位总数。例如,34 x 48在第一步将有一个乘法进位(4和8相乘时进位3),即使总进位值等于3

此外,我假设您还想知道执行乘法时发生的加法进位数。继续我们的例子,当我们乘以34*40时,我们有一个乘法进位(4*4)。我们现在必须将两个结果(272和1360)相加。这将导致一次进位,进位操作总数等于3

基本上,我计算进位总数,不包括超过最大进位数的进位。这意味着90*9将不会有任何进位。同样,90+99也不会有任何进位。我是根据你的加法运算来决定这个行为的。如果您不希望出现这种情况,并且希望包含最后一位的进位,只需按照
******中说明的代码更改操作即可****注释

代码如下。我包括了我自己的计算加法实现。它应该在功能上等同于您发布的代码

def num_add_carries(x, y):
    """
    Return a count of the number of addition carries.

    @param x: A number to add, as an integer.

    @param y: A number to add, as an integer.

    @return: The total number of carry operations.
    """

    # Determine which number is the larger one
    if y <= x:
        min_num = y; max_num = x
    else:
        min_num = x; max_num = y

    # Initialize some parameters
    num_carries = 0
    smin = str(min_num); smin_length = len(smin)
    smax = str(max_num); smax_length = len(smax)

    # Determine the end looping parameter
    #   **** Set to '-1' to include the end carry ****
    end_ix = -1 if smin_length != smax_length else 0

    # Iteratively perform the multiplication, counting the mult carries
    for i, ix in enumerate(xrange(smin_length - 1, end_ix, -1), 1):
        if int(smax[-i]) + int(smin[ix]) > 9:
            num_carries += 1

    return num_carries

def num_mult_carries(x, y):
    """
    Return a count of the total number of multiplication carries, including
    all necessary addition carries.

    @param x: A number to add, as an integer.

    @param y: A number to add, as an integer.

    @return: The total number of carry operations.
    """

    # Determine which number is the larger one
    if y <= x:
        min_num = y ; max_num = x
    else:
        min_num = x; max_num = y

    # Initialize some parameters
    num_carries = 0; adds = [] # List of numbers to add
    smin = str(min_num); smin_length = len(smin)
    smax = str(max_num); smax_length = len(smax)

    # Iteratively perform the multiplication, counting the mult carries
    for i, ix in enumerate(xrange(smin_length - 1, -1, -1)):
        # Perform Multiplication (used for summing, later)
        adds.append(max_num * int(smin[ix]) * (10 ** i))

        # Determine number of multiplication carries
        #   **** Change the '0' to '-1' to include the end carry **** 
        for ix2 in xrange(smax_length - 1, 0, -1):
            if int(smax[ix2]) * int(smin[ix]) > 9:
                num_carries += 1

    # Iteratively perform the addition, counting the addition carries
    s = 0
    while len(adds) > 1:
        s += adds.pop(0)
        num_carries += num_add_carries(s, adds[0])

    return num_carries

print num_add_carries(99, 99)
print num_mult_carries(657, 34)

我做了与@TechGuy相同的假设,尽管我处理问题的方式不同。我选择使用递归方法而不是迭代方法,因为它更适合于这类问题

如果我们在计算加法阶段发生的进位,那么我们需要将加法进位计数逻辑封装在一个方法中,如下所示:

def count_addition_carries_rec(nums, answer=0, carries=0):

    dig_count = max(len(str(nums[0])), len(str(answer)))
    carries_list = [0]
    new_answer = ''
    # convert to string, apply left-padding, and reverse
    rnums = [str(x).zfill(dig_count)[::-1] for x in [nums[0], answer]]

    for i in range(dig_count):
        dig_sum = str(sum([int(num[i]) for num in rnums]) + carries_list[i])
        if i < dig_count - 1:
            new_answer = dig_sum[-1] + new_answer
            carries_list.append(int(dig_sum[:-1].zfill(1)))
        else:
            new_answer = dig_sum + new_answer

    carries_list = [car for car in carries_list if car != 0]

    if len(nums) == 1:
        # If this is the last number in the list, 
        # return the answer and the number of carries that 
        # occurred in the current as well as previous operations.
        return int(new_answer), carries + len(carries_list)
    else:
        # if there are more numbers in the list,
        # repeat the operation with a sublist, consisting of the next
        # number onwards, passing the current sum (new_answer) and 
        # the current count of carries 
        return count_addition_carries_rec(nums[1:],
                                          new_answer,
                                          carries + len(carries_list))
def count_multiplication_carries_rec(num1, num2, answer=0, carries=0):

    num1, num2 = str(num1), str(num2)

    # if num2 is smaller than num1, 
    # then reverse their assignments, and apply left-padding
    # to the smaller number. 

    if int(num2) < int(num1):
        num1, num2 = num2.zfill(len(num1)), num1
    else:
        num1, num2 = num1.zfill(len(num2)), num2

    carries_list = [0]
    new_answer = ''

    for i in range(len(num2)):
        dig_mul = str(int(num1[-1])*int(num2[len(num2) - i - 1]) + carries_list[i])
        if i < len(num2) - 1:
            new_answer = dig_mul[-1] + new_answer
            carries_list.append(int(dig_mul[:-1].zfill(1)))
        else:
            new_answer = dig_mul + new_answer

    new_answer += '0'*(len(num2)-len(str(int(num1))))
    carries_list = [car for car in carries_list if car != 0]

    if len(str(int(num1))) == 1:
        # If this is the last digit in num1,
        # then return the sum of the answer of the previous operation
        # and the answer of the current operation, counting
        # the addition carries in the process. 
        # Return the final answer as well as the count 
        # of multiplication and addition carries.
        return count_addition_carries_rec([int(answer), int(new_answer)],
                                          answer=0,
                                          carries=carries+len(carries_list))
    else:
        # If there are more digits in num1, repeat the operation
        # with num1 stripped of its last digit.
        return count_multiplication_carries_rec(num1[:-1],
                                                num2,
                                                *count_addition_carries_rec([int(answer), int(new_answer)],
                                                                            answer=0,
                                                                            carries=carries+len(carries_list)))
count\u multiply\u carries\u rec
不像加法那样通用,但它很容易修复。您可以创建一个辅助方法,该方法一次使用2个数字调用
count\u multiplication\u carriers\u rec
,也可以修改当前实现以使用任意数量的整数

使用两种方法的示例:

>>> count_addition_carries_rec([99,99])
(198, 1)

>>> count_addition_carries_rec([17, 17, 17])
(51, 2)

>>> count_multiplication_carries_rec(15,15)
(225, 2)

>>> count_multiplication_carries_rec(657,34)
(223380, 6)
如您所见,这些方法返回加法/乘法运算的结果以及执行该运算时发生的进位数

>>> count_addition_carries_rec([99,99])
(198, 1)

>>> count_addition_carries_rec([17, 17, 17])
(51, 2)

>>> count_multiplication_carries_rec(15,15)
(225, 2)

>>> count_multiplication_carries_rec(657,34)
(223380, 6)