假設 divop()
的第二個參數也就是除數,必為大於 0
的整數
#include <stdio.h>
#include <stdlib.h>
double divop(double dividend, int divisor) {
if (dividend == 0 || divisor == 1)
return dividend;
int odd = divisor & 1;
double result = divop(dividend/2, odd ? (divisor+1)>>1 : divisor>>1);
if (odd)
result += divop(result, divisor);
return result;
}
double
,所以最後除到最小的誤差 DBL_EPSILON
(定義在 float.h
),就會視同等於 0 了
dividend <= 1e-4
,就最多計算到小數點第 5 位1 ÷ 3 = 0.33
實際上會變成 1 ÷ 4 = 0.25
5 -> 3 -> 2
、13 -> 7 -> 4
、37 -> 19 -> 10 -> 5
、101 -> 51 -> 26 -> 13
等等1 ÷ 3
3 -> 2 -> 1
兩次,得到 1 ÷ 4 = 0.25
的商 (第 8 行)0.25 × 3 = 0.75
,誤差正好等於商 0.25
0.25 ÷ 3
,作法同上 (第 10 行)0.25 ÷ 3
一定又會有新的誤差,所以當這誤差小於我們設定的條件 (第 5 行) 就會結束了1 ÷ 5
5 -> 3 -> 2 -> 1
三次,得到 1 ÷ 8 = 0.125
的商 (第 8 行)0.5 ÷ 3
時的誤差,0.125 × 3 = 0.375
,誤差正好是 0.125
0.125 ÷ 3
(第 10 行) 直到終止條件 (第 5 行)0.166...
(第 10 行)0.166... × 5 = 0.833...
,誤差再次等於商 0.166...
0.166... ÷ 5
(第 10 行) ,也會再次碰到除數為 3只有相同除數的商才能相加
1 ÷ 5
為例1 ÷ 6
等價 0.5 ÷ 3
0.5 ÷ 4
等價 0.25 ÷ 2
0.25 ÷ 2
等價 0.125 ÷ 1
(4) => (3) 兩邊同乘 2
(3) => (2) 這些 ÷ 4 的商相加,構成了近似 ÷ 3 的商,也就等價回 ÷ 6
(2) => (1) 這些 ÷ 6 的商相加,構成了近似 ÷ 5 的商,也就是解
但實際上逼近的過程是根據較大的 2 的次方數,像 ÷ 5 實際上是用 ÷ 8 逼近,÷ 9 則會是 ÷ 16,因為商都是不斷 ÷ 2 得來的
考慮 dividend <= 1e-3
1 ÷ 3
dividend: 1.0000000000, divisor: 3
dividend: 0.5000000000, divisor: 2
dividend: 0.2500000000, divisor: 1
result: 0.2500000000
dividend: 0.2500000000, divisor: 3
dividend: 0.1250000000, divisor: 2
dividend: 0.0625000000, divisor: 1
result: 0.0625000000
result: 0.0156250000
result: 0.0039062500
result: 0.0009765625
dividend: 0.0009765625, divisor: 3 // <= 1e-4
final: 0.3339843750 // result 總和
1 ÷ 5
dividend: 1.0000000000, divisor: 5 // 對應到 22 行
----------------------------------
dividend: 0.5000000000, divisor: 3
dividend: 0.2500000000, divisor: 2
dividend: 0.1250000000, divisor: 1
result: 0.1250000000
dividend: 0.1250000000, divisor: 3 // 處理 3 情況
dividend: 0.0625000000, divisor: 2
dividend: 0.0312500000, divisor: 1
result: 0.0312500000
dividend: 0.0312500000, divisor: 3
dividend: 0.0156250000, divisor: 2
dividend: 0.0078125000, divisor: 1
result: 0.0078125000
result: 0.0019531250
result: 0.0009765625
result: 0.1679687500 // 第一輪 ÷ 5 的商
----------------------------------
dividend: 0.1679687500, divisor: 5 // 對應到 40 行
----------------------------------
dividend: 0.0839843750, divisor: 3
dividend: 0.0419921875, divisor: 2
dividend: 0.0209960938, divisor: 1
result: 0.0209960938
dividend: 0.0209960938, divisor: 3
dividend: 0.0104980469, divisor: 2
dividend: 0.0052490234, divisor: 1
result: 0.0052490234
result: 0.0013122559
result: 0.0006561279
result: 0.0288696289 // 第二輪誤差的商
----------------------------------
dividend: 0.0288696289, divisor: 5
----------------------------------
dividend: 0.0144348145, divisor: 3
dividend: 0.0072174072, divisor: 2
dividend: 0.0036087036, divisor: 1
result: 0.0036087036
dividend: 0.0036087036, divisor: 3
dividend: 0.0018043518, divisor: 2
dividend: 0.0009021759, divisor: 1
result: 0.0009021759
result: 0.0054130554 // 第三輪誤差的商
----------------------------------
dividend: 0.0054130554, divisor: 5
----------------------------------
dividend: 0.0027065277, divisor: 3
dividend: 0.0013532639, divisor: 2
dividend: 0.0006766319, divisor: 1
result: 0.0006766319
dividend: 0.0006766319, divisor: 3 // <= 1e-4
result: 0.0013532639 // 第四輪誤差的商
----------------------------------
dividend: 0.0013532639, divisor: 5
----------------------------------
dividend: 0.0006766319, divisor: 3 // <= 1e-4
result: 0.0006766319 // 第五輪誤差的商
----------------------------------
dividend: 0.0006766319, divisor: 5 // <= 1e-4
final: 0.2049579620 // result 總和