我的方法和 LPH66 其實差不多,後半段是用硬爆的。
另擅用了 sqrt 鍵 (原本 LPH66 是用平方,我是用根號), 多做了建表的工作..
我打算先求 10^0.2, 其它用轉換的。
10^7.2 = 10^7 * 10^0.2 , 10^0.1 = sqrt(10^0.1)
10^6.9 = 10^7 / 10^0.1 , 剛剛算出來
10^7.4 = 10^6.9 * sqrt(10)
-----------------------------
假設 x = 10, m0 = x, m<n> = sqrt(m<n-1>) , 故
m1 = sqrt(10) = 3.16227766
m2 = sqrt(m1) = 1.77827941
m3 = sqrt(m2) = 1.333521432
m4 = sqrt(m3) = 1.154781985
m5 = sqrt(m4) = 1.074607828
m6 = sqrt(m5) = 1.036632928
m7 = sqrt(m6) = 1.018151722
m8 = sqrt(m7) = 1.009035045
接著看 10^0.2 , 把 0.2 化為二進位,
得到 0.2(10) = 0.001100110011...,
第 3,4,7,8 bit 為 1,
m3 * m4 * m7 * m8 = 1.5820447
得 10^0.2 = 1.5820447, 10^0.1 = sqrt(1.5820447) = 1.25779358
10^7.2 = 10^7 * 10^0.2 = 15820447 ,
10^6.9 = 10^7 / 10^0.1 = 7950430 ,
10^7.4 = 10^6.9 * sqrt(10) = 25141467
加總約 = 48911944 < 工程按的結果是 48911078>
原理是也是將指數部份化成二進位計算,
按一次 sqrt : sqrt(m)
按二次 sqrt : sqrt ( sqrt(m) )
...
按 N 次 sqrt : m 的 0.5^N 。
------------------------------
後半段如 LPH66 所示較佳,這裡提供硬爆法。
x
48911944 = 10 , 兩邊取 log, 左邊正規化至小數第一位非零。
8 + log(0.49) ~ x
剩下要解 log(0.49) , < 很沒用的還是要靠 taylor series.. >
還要先記 ln(10) ~ 2.3026 才解得下去 , 不然就是另一個 taylor series 展開..
log(0.49) = ln(0.49) / ln(10) = ln(0.49) / 2.3026 = 0.434 * ln(0.49)
再來是公式了,
ln(1-x) = - [x + x^2/2 + x^3/3 + x^4 / 4 + ... ] , for 0 <= x < 1
這也是為什麼前面要做正規化的原因。
很多人說做到前三項就行,但仔細看一下第二項和第四項只是平方關係,
根本差不到多少時間。故令 x=0.51, 計算機按的時候有技巧,
先把所有 n 次方記下來, 再算 x^n /n
n x^n x^n/n
1 0.51 0.51
2 0.2601 0.13005 , 平方=0.0169
3 0.132651 0.044217
ln(0.49) = -[0.51 + 0.13005 + 0.0169 + 0.044217] = -0.701167。
原式 ~ 8 + log(0.49) = 8 + ln(0.49) / ln(10)
= 8 - 0.701167 * 0.434 ~ 7.696
--------------------------
一開始還想用牛頓法解,不過牛頓法也是卡死。
--
「自從我學了 C# , 人都變聰明 , 考試都考一百分」
「自從我學了 VB , 皮膚都變好 , 人也變漂亮了 」
「自從我學了 Java , 明顯變壯 , 個子也變高了 」
「自從我學了 C++ , 內分泌失調 , 頭都禿了... 」
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 180.177.76.161