Algorithm 如何在任意长度的数字上实现平方根和幂运算?

Algorithm 如何在任意长度的数字上实现平方根和幂运算?,algorithm,language-agnostic,types,numbers,Algorithm,Language Agnostic,Types,Numbers,我正在为任意长度的数字(只有非负整数)开发新的数据类型,并且我在实现平方根函数和求幂函数(仅适用于自然指数)时遇到了困难。请帮忙 我将任意长度的数字存储为字符串,因此所有操作都是逐字符进行的 请不要包含使用不同(现有)库或其他方式存储数字而不是字符串的建议。这是一个编程练习,而不是一个真实的应用程序,因此优化和性能不是那么必要 如果你在答案中包含代码,我希望它可以是伪代码,也可以是C++。重要的是算法,而不是实现本身 谢谢你的帮助。求幂是用乘法实现的,最基本的实现就是一个循环 result =

我正在为任意长度的数字(只有非负整数)开发新的数据类型,并且我在实现平方根函数和求幂函数(仅适用于自然指数)时遇到了困难。请帮忙


我将任意长度的数字存储为字符串,因此所有操作都是逐字符进行的

不要包含使用不同(现有)库或其他方式存储数字而不是字符串的建议。这是一个编程练习,而不是一个真实的应用程序,因此优化和性能不是那么必要

<>如果你在答案中包含代码,我希望它可以是伪代码,也可以是C++。重要的是算法,而不是实现本身


谢谢你的帮助。

求幂是用乘法实现的,最基本的实现就是一个循环

result = 1;    
for (int i = 0; i < power; ++i) result *= base;
result=1;
对于(int i=0;i
您可以(也应该)使用平方和分治实现更好的版本,即a^5=a^4*a=(a^2)^2*a

平方根可以用牛顿的方法找到——你必须得到一个初始的猜测(一个好的猜测是从最高的数字中取一个平方根,然后乘以提升到原始数字长度一半的数字的基数),然后用除法对其进行细化:如果a是sqrt(x)的近似值,那么更好的近似值是(a+x/a)/2.当下一个近似值等于上一个近似值,或等于x/a时,应停止计算。

平方根:。即

求幂:

其中,
toBinary
返回1和0的列表/数组,MSB优先,例如,由此Python函数实现:

def toBinary(x):
    return map(lambda b: 1 if b == '1' else 0, bin(x)[2:])
请注意,如果您的实现是使用二进制数完成的,则可以使用位操作来实现,而不需要任何额外的内存。如果使用十进制,则需要额外的内存来存储二进制编码

但是,该算法有一个十进制版本,如下所示:

function exp(base, pow):
    lookup = [1, base, base*base, base*base*base, ...] #...up to base^9
     #The above line can be optimised using exp-by-squaring if desired

    result = 1
    digits = toDecimal(powr)
    for digit in digits:
        result = result * result * lookup[digit]
    return result

“我在实现平方根和求幂函数时遇到了麻烦”?遇到了什么问题?为您的算法发布一些代码或伪代码,明确定义“遇到麻烦”的含义。我将任意长度的数字存储为字符串-以什么为基数?10?“我将任意长度的数字存储为字符串”--等等,沃特?这不仅是令人难以置信的内存浪费(而且,在某种程度上,我无法判断性能潜力),我也认为这是不必要的难处理…你已经实现了什么函数?如何实现?@tomp祝你考试顺利,请注意,我不是想说得太苛刻,只是提供真诚的意见和建议!@David:D'oh.修正了。Sqrt现在应该返回不超过N的平方根的最大整数。答案很好。I'v我看过平方求幂法一次,但是用函数语言写的,我完全忘记了。而且,我从来没有听说过巴比伦法。看起来很有趣,谢谢。你对平方求幂法的解释可能是错误的。至少函数的第一行,例如
result=1
应该是
result=base
而且我认为base的乘法(在第5行)可能也不正确(它并不总是原始的基数)。使用递归时算法更容易。@tomp:Whoops!!事实上,
result=1
是函数中唯一正确的部分!我现在更新了它。
def toBinary(x):
    return map(lambda b: 1 if b == '1' else 0, bin(x)[2:])
function exp(base, pow):
    lookup = [1, base, base*base, base*base*base, ...] #...up to base^9
     #The above line can be optimised using exp-by-squaring if desired

    result = 1
    digits = toDecimal(powr)
    for digit in digits:
        result = result * result * lookup[digit]
    return result