[心得] 直式開方法

作者: jurian0101 (Hysterisis)   2013-07-04 22:44:37
Knuth說,自己已經學會某事情的一種證明是:教會你的電腦。
今天學會了脫胎自 (10a+b)^3 = 1000a^3 + 300 a^2 b + 30a b^2 + b^3 公式
和直式開平方法的直式開立方法
source= http://chowkafat.net/Abacus8.html
其實這個方法很爛,因為相較於開平方時左手邊欄是每次增加一位數,
而開立方時,不僅步驟多,而且估計下一位更難,更糟糕的是左手邊的位數以每次
兩位增加。
所以用手算除了要很大一張紙和大量的細心,甚至效率不比簡單的牛頓法好。
總之為了紀念學過,就有點多此一舉的把這又點複雜的算法編成MMA代碼吧 (做為練習XD
直式開方[x_Integer, precision_Integer] :=
Module[{rL, r, a, b, col, ans, idx = precision, point},
rL = IntegerDigits[x, 1000]; (*每3位一組*)
ans = (a = Floor[rL[[1]]^(1/3)]);
rL[[1]] = rL[[1]] - a^3;
col = {300 a^2, 30 a, 1};
idx -= 1; (*算幾次後停止*)
point = 1; (*記錄小數點以上有幾位*)
(*若精準度足夠則跳出,ans=a *)
While[idx > 0,
r = rL[[1]]*1000 + rL[[2]];
b = Floor[r/col[[1]]];
While[r < col.{b, b^2, b^3}, b -= 1]; (*決定b*)
If[Length@rL > 2,
rL = {r - col.{b, b^2, b^3}}~Join~rL[[3 ;;]]; (*清單向右縮短*)
point += 1, (*是小數點以上*)
rL = {r - col.{b, b^2, b^3}, 0} (*小數點以下的補0*)
];
idx -= 1;
ans = 10*ans + b;
col = {300 ans^2, 30 ans, 1}(*更新col*)
];
(*輸出*)N[ans/10^(precision - point - 1), precision]
]
測試:
352^3=43614208, 直式開方[43614208, 3]= 352.
直式開方[43614207, 20] = 351.99999730974515850
N[43614207^(1/3), 20] = 351.99999730974515850
= = =
ps. 後記
會去研究怎麼算其實是被明代朱載堉(1530-1610)這個奇才刺激到了
這位超牛的王子是「十二平均律」的最早發明+實現者,正是這個原因他用算盤
將2開了12次方,求到小數點以下25位精確值! 當時歐洲的數學家還算得2266誤差百出呢。
可想見要不就是直接解x^12-2=0的牛頓法 (牛頓還沒出生咧),
或是開兩次平方再一次立方。除此之外我列不出其他方法能算到25位XD
接近接近2^(1/12)的分數中分母最小的是
FromContinuedFraction@ContinuedFraction[2^(1/12), 28]=
7147579272248/6746416472931
N[7147579272248/6746416472931,25]=1.059463094359295264561825
而這個結果朱載堉在四百年前就算出來了
http://zh.wikipedia.org/wiki/File:%E4%B9%90%E5%BE%8B%E5%85%A8%E4%B9%A6%E5%85%A8-123.jpg
= = =
pps. 列入金氏世界紀錄的一項心算挑戰是 13th root of 100/200-digit number
這位超能逆天的法國人Alexis Lemaire成功在70秒內
算出 200位數
9147439234287241692920723809496000857331422592710260318167504650965532\
9359229555248436073522547285876508820526837505708703326135976287791083\
873682599348132022020213082392767546685090283520000000000000
的十三次方根
= 2407899883032220^13
source= http://tech.sina.com.cn/d/2007-12-12/10121907975.shtml
嗯,大家應該有注意到他運氣很好,挑戰當時電腦正好選到0結尾的數,瞬間少算一位。
13次方後剛好兩百位數的數有
Floor[10^(200/13)] - Floor[10^(199/13)] = 393 544 396 177 593 個 @@
剛好選到0結尾則只有十分之一的可能,還是很多很逆天 @A@
作者: leo80042 (嗯嗯啊啊去洗澡)   2013-07-11 00:50:00
很有趣 XD 推!

Links booklink

Contact Us: admin [ a t ] ucptt.com