javascript - 使用有限的数学运算符求立方根
问题描述
我需要编写一个函数来告诉我一个数字是否是一个完美的立方体。如果是我希望立方根返回 else false 如下:
cubeRoot(1) // 1
cubeRoot(8) // 2
cubeRoot(9) // false
cubeRoot(27) // 3
cubeRoot(28) // false
它必须适用于非常大的数字。性能是一个很大的奖励。
但是,我使用的库意味着我只能使用以下数学函数/运算符:
abs, round, sqrt
/ * + -
===
> >= < <=
%
^
如果仅使用上述运算符在 JS 中提供答案,我可以自己将答案转换为(big.js)语法(我正在使用的库)。这可能吗?
big.js
PS由于它保证的精度,我需要使用。
解决方案
所以让我们看一下二进制中的一些立方体
2^3 = 8 = 100b (3 binary digits)
4^3 = 64 = 100 000b (6 binary digits)
8^3 = 512 = 100 000 000b (9 binary digits)
(2^n)^3 = 2^(3n) = (3n binary digits).
因此,对于粗略的第一个猜测,计算二进制数字的数量,d
例如,除以三,让n = d/3
这告诉我们立方根数是否介于2^n
和之间2^(n+1)
。计数数字可以与对数的原始第一近似值相关联。
如果您无法访问二进制数字,只需重复除以 8(或 8 的幂),直到得到零结果。
现在我们可以使用 Newton-Raphson 来确定解决方案。Wikipedia 立方根为我们提供了迭代公式。如果a
是我们想要找到根的数字并且x_0
是我们使用上面的第一个猜测
x_{n+1} = ( a / x_n^2 + 2 x_n ) / 3.
这可以很快收敛。例如,a=12345678901234567890
我们发现它a
在 8^21 和 8^22 之间,因此立方根必须在 2^21 和 2^22 之间。
运行迭代
x_1 = 2333795, x_1^3 = 12711245751310434875
x_2 = 2311422, x_2^3 = 12349168818517523448
x_3 = 2311204, x_3^3 = 12345675040784217664
x_4 = 2311204, x_4^3 = 12345675040784217664
我们看到它在 3 次迭代后已经收敛。检查显示a
介于 2311204^3 和 2311205^3 之间。
该算法可以使用 big.js 进行计算。上述计算是使用 Java 的 BigInt 类完成的。
推荐阅读
- unit-testing - 如何在使用 Bunit 自动化脚本时更新 Scroll 值
- discord - discord.py 如何制作表情符号猜谜游戏?
- javascript - 在 React Native 中拥有来自 expo-camera 的多个图像
- javascript - 格式化不带 html: 标记的 Sweet Alert 文本
- c++ - 为什么将 const 对象传递给期望非 const 模板类型参数的模板化函数会导致编译错误?
- java - XMLElement 与 XMLAttribute 结合创建新对象
- python - 在 tensorflow 2 中使用回调信息训练神经网络
- kotlin - Corda - 注册和监听处理程序/响应程序流
- java - 如何将此 SQL 转换为 JPA?
- c# - 无法将数据更新到数据库中