如何处理整数平方根法中的大输入?
How to handle a large input in an integer square-root method?
我需要实现一种求整数平方根的方法。
我的平台是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 是一个不错的选择,以便允许其他人轻松地对我的方法应用更改。
尽管如此,我通常对算法解决方案感兴趣。
这是在 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)
与您已有的非常相似,但我认为稍微简单一些。
我需要实现一种求整数平方根的方法。
我的平台是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 是一个不错的选择,以便允许其他人轻松地对我的方法应用更改。
尽管如此,我通常对算法解决方案感兴趣。
这是在 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)
与您已有的非常相似,但我认为稍微简单一些。