亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何使用位操作實現唐葉乘法

如何使用位操作實現唐葉乘法

墨色風雨 2021-12-30 16:07:04
我正在Scala(我的選擇)中為在線課程實施Karatsuba 乘法??紤]到該算法旨在乘以大數,我選擇了BigInt由 Java BigInteger支持的類型。我想有效地實現算法,它使用基數 10 算法從維基百科復制如下:procedure karatsuba(num1, num2)  if (num1 < 10) or (num2 < 10)    return num1*num2  /* calculates the size of the numbers */  m = max(size_base10(num1), size_base10(num2))  m2 = floor(m/2)  /* split the digit sequences in the middle */  high1, low1 = split_at(num1, m2)  high2, low2 = split_at(num2, m2)  /* 3 calls made to numbers approximately half the size */  z0 = karatsuba(low1, low2)  z1 = karatsuba((low1 + high1), (low2 + high2))  z2 = karatsuba(high1, high2)  return (z2 * 10 ^ (m2 * 2)) + ((z1 - z2 - z0) * 10 ^ m2) + z0鑒于它BigInteger在內部表示為int[],如果我可以根據m2進行計算int[],我可以使用位移來提取數字的低半部分和高半部分。同樣,最后一步也可以通過位移來實現。然而,說起來容易做起來難,因為我似乎無法理解邏輯。例如,如果最大數為999,則二進制表示為1111100111,下半部分為99 = 1100011,上半部分為9 = 1001。我如何獲得上述分割?注意:有一個現有問題顯示了如何在 上使用算術BigInteger而不是位移來實現。因此,我的問題不是重復的。
查看完整描述

1 回答

?
繁星coding

TA貢獻1797條經驗 獲得超4個贊

為了能夠使用位移位進行拆分和重組,基數需要是 2 的冪。使用兩個本身,如鏈接的答案,可能是合理的。然后可以直接用 找到輸入的“長度”,bitLength分割可以實現為:


// x = a + 2^N b

BigInteger b = x.shiftRight(N);

BigInteger a = x.subtract(b.shiftLeft(N));

以位N為單位的大小在哪里a。


鑒于它BigInteger是用 32 位肢體實現的,使用 232 作為基礎是有意義的,確保大移位只涉及整個整數的移動,而不是較慢的代碼路徑,其中BigInteger1 和 31 之間的值移位。這可以通過四舍五入N到 32 的倍數來實現。


這一行中的特定常數,


if (N <= 2000) return x.multiply(y);                // optimize this parameter

鑒于該評論,可能不應該太相信。但是對于性能來說應該有一些限制,否則遞歸拆分會過深。例如,當數字的大小為 32 或更少時,只進行乘法顯然更好,但好的截止值可能要高得多。在這個源中BigInteger,截止值用肢體數而不是位數表示,并設置為 80(因此為 2560 位) - 它還有一個其他閾值,高于該閾值它會切換到 3 路 Toom-Cook 乘法唐葉乘法。


查看完整回答
反對 回復 2021-12-30
  • 1 回答
  • 0 關注
  • 127 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號