【问题标题】:How to handle a large input in an integer square-root method?如何处理整数平方根方法中的大输入?
【发布时间】:2020-06-26 07:25:52
【问题描述】:

我需要实现一个求整数平方根的方法。

我的平台是 Solidity 语言,仅支持整数运算,输入大小为 256 位 (uint256)。

典型的解决方案是二分搜索,我很容易实现。

问题是我的方法仅限于输入小于2 ^ 129。

这是我的方法(用 Python 实现):

def sqrt(x):
    assert(x < 0x200000000000000000000000000000000);
    lo = 0;
    hi = x;
    while (True):
        mid = (lo+hi)//2;
        if (mid == lo or mid**2 == x):
            return mid;
        elif (mid**2 < x):
            lo = mid;
        else: # (mid**2 > x)
            hi = mid;

请注意,我使用 Python 而不是 Solidity 发布了它,因为这里的大多数用户不熟悉 Solidity,所以我认为 Python 是一个不错的选择,以便其他人可以轻松地对我的方法应用更改。

不过,我通常对算法解决方案感兴趣。

【问题讨论】:

    标签: algorithm binary-search fixed-point square-root


    【解决方案1】:

    这是用 Java 编写的,而不是 Python,纯粹是因为我已经有了这个。代码很简单,可以转换,因为所有变量都是整数,所以都是整数运算。

    /**
     * Finds the integer square root of a positive number.
     * Crandall and Pomerance algorithm 9.2.11 (Newton-Raphson).
     *
     * @param num int Number to find root of.
     * @return int Integer square root of given number.
     */
    public static int iSqrt(int num) {
        if (0 == num) {
            // Avoid zero divide crash
            return 0;
        }
        int x = (num / 2) + 1;
        int y = (x + (num / x)) / 2;
        while (y < x) {
            x = y;
            y = (x + (num / x)) / 2;
        } // end while
        return x;
    } // end iSqrt(int)
    

    与您已有的非常相似,但我认为稍微简单一些。

    【讨论】:

    • 啊,Newton-Raphson 太棒了,我不知道它可以用整数算术实现。现在就测试一下,谢谢!!!
    • 好的,在0256 之间的每个n 上测试了2**n-12**n-02**n+1 上的方法,它似乎工作正常。谢谢!!!
    • 谢谢。它来自我的 Java 数学库,我还没有对它进行深入测试。
    • 嗯,使用 Java 的原生 int(或者甚至 unsigned int,你也可以在你的库 BTW 中使用它)显然不会为那个深度工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-09
    • 1970-01-01
    • 2015-03-04
    • 1970-01-01
    • 2015-12-28
    • 2013-03-01
    • 1970-01-01
    相关资源
    最近更新 更多