【发布时间】:2017-07-31 14:19:12
【问题描述】:
让我简短一点。我正在计算
alert((Math.pow(7,35))%71)
但它给了我 61,而结果必须是 70。怎么了?
【问题讨论】:
-
您超出了 JavaScript 数字的准确性。
-
有什么办法可以解决这个问题吗?
-
也许你可以四处寻找一个无限精度的定点库。
让我简短一点。我正在计算
alert((Math.pow(7,35))%71)
但它给了我 61,而结果必须是 70。怎么了?
【问题讨论】:
您使用的数字对于 javascript 来说太大了。 int 的最大大小为 2^53 -- 小于 7^35。
【讨论】:
唯一需要更高精度的值是中间结果。因此,当您的算法不需要有问题的中间结果时,也可以避免该问题,而不需要更高精度的变量。
以下公式对此很有用:
(a.b) % c = (a % c)(b % c) % c
这意味着 Math.pow(7,35)%71 = ((Math.pow(7,17)%71) * (Math.pow(7,18)%71)) % 71。
现在中间结果较小,但可能仍然太大。因此,我们需要进一步拆分并将模运算符应用于较小的中间结果。
所以你可以做这样的事情:
Math.pow((Math.pow(7,7)%71),5)%71
但是您可能需要对可变的整数执行此操作(否则,您可以通过对结果进行硬编码来避免该问题)。 因此,您需要对可以预期的值范围有所了解,并定义一个算法,将功率计算拆分为多个部分,当输入在预期范围内时,这些部分总是具有足够小的结果。
无论您为这样的计算选择什么,使用更高精度变量的计算(使用专门的库)或专门的算法,您都应该始终断言输入以确保您的计算仅在您确定它可以返回一个值时提供正确的值。否则,对于不知道其有效范围的任何人来说,您的实现将变得不可靠。否则返回异常,并带有一条消息,清楚地说明哪个输入或输入组合是问题以及原因。
【讨论】: