日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

递归算法之不用乘号的乘法——用位移实现乘法(dart语言实现)

發布時間:2024/9/5 编程问答 60 如意码农
生活随笔 收集整理的這篇文章主要介紹了 递归算法之不用乘号的乘法——用位移实现乘法(dart语言实现) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  前兩天突發奇想,寫一個乘法的實現,但不用乘號*。并測試一下性能如何。因此就有了下面的代碼:(本文主要目的是為了玩遞歸和位移,因此僅限自然數)

首先,標準乘法:

 int commonMultiplication(int a, int b) => a * b;

第二,從數學的角度,乘法其實就是加法,只是加法的簡寫而已,因此 a * b 可以理解為 b 個 a 相加;故得出用加法代替的乘法。為了減少加法的次數,取 a, b 兩數的最小值進行循環:

 int plusMultiplication(int a, int b) {
var t = a > b ? b : a, r = 0;
if (t == a) {
a = b;
b = t;
} while (b-- > 0) r += a;
return r;
}

最后,位移乘法。計算機進行位移操作的速度是非常快的,因此,如果能把乘法換算成位移操作的話,速度會不會更快?但是根據計算機二進制的特點,每次向左位移,相當于是乘了2的n次方,怎么辦?我們看看例子:

  31 * 18

怎么用位移來實現呢?首先我們取小的數:18,進行拆解。拆解的算法是,任何一個自然數,在計算機中都可以用二進制表示,那么,任何一個自然數,也可以拆解為2的冪的和。比如 18 的二進制表示 為  10010,拆解成十進制,即為 18 = 16 + 2;那么上面可以拆解為:

  31 * 18 = 31 * (16 + 2) = 31 * 16 + 31 * 2

此時即可換成位移的算法:

  31 * 18 = 31 * (16 + 2) = 31 * 16 + 31 * 2 = 31 * 2^4 + 31 * 2^1 = (31 << 4) + (31 << 1)

是不是轉成了位移?這里要注意對乘數 18 的處理,位移的關鍵是找到乘數 b 如何拆解為 2 的冪,這里要遞歸拆解,以18為例,第一次的關鍵是找到16這個2的冪,然后用18 - 16,結果等于 2,繼續找2等于多少2的冪,直到差小于2為止。同時,考慮到a*b,在實際計算中即使小的乘數也很大的情況,采用類似二分搜索的方式,給定階數,從大的階數向小的階數遞歸。階數的設定可以參考計算機的位數,即32位還是64位。因此,計算一個數可以拆分出來的最大2的冪的代碼如下:

 int _bitShift(int d, int order) {
if (order == 0) return 0;
var i = 0;
for (var t = d; (t >>= order) > 0; d = t, t = d) i += order;
return i + _bitShift(d, order >> 1);
}

位移乘法實現的代碼

int bitMultiplication(int a, int b, int order) {
var t = a > b ? b : a, r = 0;
if (t == a) {
a = b;
b = t;
} for (var i = _bitShift(b, order); i > 0; i = _bitShift(b, order)) {
r += a << i;
b -= 1 << i;
} return b == 1 ? r + a : r;
}

經過采用隨機大數進行多次循環測試,結果顯示,用加法實現的乘法速度最慢,最快的仍然是 普通乘法,即用乘號的乘法;位移乘法居中。看來底層的計算機指令還是對*乘法做了優化。

最后說明一下,本文純屬原創,沒有使用dart 自帶math包,尤其是在求一個數可以拆出來的最大的2的冪的數字時。否則直接用math包中的log函數即可得出結果,但這樣就起不到自己練習位運算和遞歸的目的了。

總結

以上是生活随笔為你收集整理的递归算法之不用乘号的乘法——用位移实现乘法(dart语言实现)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。