首先,我假设“大十进制”是指您代表一个理性,其中分母被限制为十的任何幂。
您需要认真考虑您希望两位小数的除法输出是什么。小数在加法、减法和乘法上是封闭的,但在除法上不是封闭的。也就是说,任何两个小数相乘产生第三个:(7 / 10) * (9 / 100) 得到 63 / 1000,这是另一个小数。但是将这两个小数相除,你会得到一个分母中没有十次方的有理数。
要回答您实际提出的问题:就像乘法可以通过循环中的加法构建一样,除法可以通过循环中的减法构建。要将 23 除以 7,请说:
- 7 < 23 吗?是的。
- 从 23 中减去 7 得到 16。
- 7 < 16 吗?是的。
- 从 16 中减去 7 得到 9
- 7 < 9 吗?是的。
- 从 9 中减去 7 得到 2。
- 7 < 2?不,我们有我们的第一个数字。我们做了三个减法,所以第一个数字是 3。
- 将 2 乘以 10 得到 20
- 7 < 20 吗?是的。
- 从 20 中减去 7 得到 13。
- 7 < 13 吗?是的。
- 从 15 中减去 7 得到 6。
- 7 < 6?不,我们做了两次减法和一次乘以 10,所以下一个数字是 2。
- 将 6 乘以 10 得到 60
- 7 < 60 吗?是的...
- ...
- 我们做了八次减法,所以下一个数字是 8...
- ... 等等
你知道为此目的更快的算法吗?
当然,有很多更快的除法算法。这是一个:Goldschmidt 算法。
首先,我希望很清楚,如果您尝试计算,X / D
那么您可以先计算1 / D
然后将其乘以X
. 此外,让我们假设 WOLOG D 严格介于 0 和 1 之间。
如果不是呢?如果 D 是负数,则将它和 X 反转;如果 D 为零,则给出错误;如果 D 为 1,则答案为 X;如果 D 大于 1,则将它和 X 都除以 10,这对您来说应该很容易,因为您的系统是十进制的。继续应用这些规则,直到你的 D 介于 0 和 1 之间。(作为附加优化:当 D 非常小时,算法最慢,所以如果 D 小于 0.1,则将 X 和 D 乘以 10,直到 D 大于或等于 0.1。)
好的,所以我们的问题是我们有一个介于 0 和 1 之间的数字 D,我们希望计算1 / D
。可能最简单的事情就是做一个例子。假设我们正在尝试计算1 / 0.7
. 正确答案是1.42857142857...
首先从 2 中减去 0.7 得到 1.3。现在将分数的两个部分都乘以 1.3:
(1 / 0.7) * (1.3 / 1.3) = 1.3 / 0.91
伟大的。我们现在已经计算1 / 0.7
到一位数的准确性。
现在再做一次。从 2 中减去 0.91 得到 1.09。将分数的两个部分乘以 1.09:
(1.3 / 0.91) * (1.09 / 1.09) = 1.417 / 0.9919
太好了,现在我们有两个正确的数字。现在再做一次。从 2 中减去 0.9919 得到 1.0081。将顶部和底部乘以 1.0081:
(1.417 / 0.9919) * (1.0081 / 1.0081) = 1.4284777 / 0.99993439
嘿,现在我们有四个正确的数字。看看情况如何?分母的每一步都越来越接近 1,因此分子越来越接近1 / 0.7
。
这比减法方法收敛得快得多。
你明白它为什么有效吗?
由于 D 介于 0 和 1 之间,因此存在一个数 E 使得 D = 1 - E,并且 E 也在 0 和 1 之间。
当我们将 D 乘以 (2 - D) 时,我们将 (1 - E) 乘以 (1 + E),得到 1 - E 2。
由于 0 < E < 1,显然 E 2小于 E 并且也在 0 和 1 之间,这意味着 1 - E 2更接近于 1。事实上它更接近 1。通过多次重复这个过程,我们很快就接近 1。实际上,我们在这里所做的是将每一步正确数字的数量大致增加一倍。显然,这比减法方法要好得多,减法方法在每一步都给出一个额外的数字。
继续这样做,直到获得所需的准确性。由于您在每个步骤中将准确数字的数量大致翻了一番,因此您应该能够很快达到可接受的准确度。由于我们一开始就已经安排 D 大于等于 0.1,所以 E 永远不会大于 0.9;反复平方 0.9 会让你很快降到一个非常小的数字。