修改按位Karatsuba算法以使用负数的最佳方法是什么?

时间:2018-05-27 15:59:52

标签: python algorithm multiplication karatsuba

我写了这个按位Karatsuba乘法算法。它不使用字符串或math.pow。它只是分而治之的递归,按位运算和加法:

def karatsuba(x,y):
  n = max(x.bit_length(), y.bit_length())

  if n < 2:
    return x&y

  # split in O(1)
  n = (n + 1) >> 1

  b = x >> n;
  a = x - (b << n);
  d = y >> n;
  c = y - (d << n);

  ac = karatsuba(a, c);
  bd = karatsuba(b, d);
  abcd = karatsuba(a+b, c+d);

  return ac + ((abcd - ac - bd) << n) + (bd << (n << 1));

print(karatsuba(23,24))
print(karatsuba(-29,31))

# 552
# 381

对于正数而言绝对正常,但显然-29 * 31不等于381。

解决问题的最简单方法是什么?

我的第一个想法是使用(~(-29)+1) = 29使数字为正数,在布尔值中存储它是否为负数并在返回语句中处理该布尔值,但是有更好的(可能是按位)解决方案吗? / p>

提前致谢

1 个答案:

答案 0 :(得分:2)

问题在于您的退出案例,特别是x&y为负数返回错误的值:

-1 & 1 == 1   # Needs to return -1

所以你可以通过测试来解决这个问题,或者只是回来:

if n < 2:
    return x*y

E.g:

In []:
print(karatsuba(-29,31))

Out[]:
-899