如何在任意长度数上实现平方根和取幂?

时间:2010-12-25 22:52:33

标签: algorithm language-agnostic types numbers

我正在研究任意长度数字的新数据类型(只有非负整数),并且我坚持实现平方根和取幂函数(仅适用于自然指数)。请帮忙。

我将任意长度的数字存储为字符串,因此所有操作都由char 设为char。

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

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

感谢您的帮助。

2 个答案:

答案 0 :(得分:10)

平方根:Babylonian method。即。

function sqrt(N):
    oldguess = -1
    guess = 1
    while abs(guess-oldguess) > 1:
        oldguess = guess
        guess = (guess + N/guess) / 2
    return guess

Exponentiation:by squaring

function exp(base, pow):
    result = 1
    bits = toBinary(powr)
    for bit in bits:
        result = result * result
        if (bit):
            result = result * base
    return result

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

def toBinary(x):
    return map(lambda b: 1 if b == '1' else 0, bin(x)[2:])

请注意,如果您的实现是使用二进制数完成的,则可以使用按位运算来实现,而无需任何额外的内存。如果使用decimal,那么您将需要额外的来存储二进制编码。

但是,算法的十进制版本看起来像这样:

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

答案 1 :(得分:3)

使用乘法通常可以实现指数化 - 最基本的实现只是一个循环,

result = 1;    
for (int i = 0; i < power; ++i) result *= base;

您可以(并且应该)使用除以&div的平方来实现更好的版本征服 - 即a ^ 5 = a ^ 4 * a =(a ^ 2)^ 2 * a。

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