【问题标题】:How to implement square root and exponentiation on arbitrary length numbers?如何对任意长度的数字实现平方根和求幂?
【发布时间】:2010-12-25 22:52:33
【问题描述】:

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

我将任意长度的数字存储为字符串,所以所有的操作都是由 char 来做的

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

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

感谢您的帮助。

【问题讨论】:

  • “我在实现平方根和求幂函数时遇到了困难”?坚持什么?为您的算法发布一些代码或一些伪代码,明确定义“卡住”的含义。
  • 我将任意长度的数字存储为字符串 - 在什么基础上? 10 点?
  • “我将任意长度的数字存储为字符串”——等等,什么?这不仅是令人难以置信的内存浪费(而且,在某种程度上,我无法判断,性能潜力),我还认为这是不必要的难以处理......
  • 你已经实现了哪些功能?怎么样?
  • @tomp 祝你考试顺利,请注意,我并不想听起来苛刻,只是提供真诚的意见和建议!

标签: algorithm language-agnostic types numbers


【解决方案1】:

平方根:Babylonian method。即

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

求幂: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:])

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

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

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

【讨论】:

  • @大卫:哦。固定的。 Sqrt 现在应该返回不超过 N 平方根的最大整数。
  • 很好的答案。我曾经看过一次平方幂运算,但是用函数式语言编写的,我完全忘记了它。另外,我从未听说过巴比伦的方法。看起来很有趣,谢谢。
  • 您对平方指数的解释可能是错误的。至少在函数的第一行,例如result = 1 应该是 result = base 并且我认为乘以基数(在第 5 行)也可能不正确(它并不总是原始基数)。使用递归时算法更容易。
  • @tomp:哎呀!!实际上,result = 1 是函数中唯一正确的部分!我现在已经更新了。
【解决方案2】:

乘法可以简单地实现求幂 - 最基本的实现只是一个循环,

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

您可以(并且应该)使用平方和分治来实现更好的版本 - 即 a^5 = a^4 * a = (a^2)^2 * a。

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

【讨论】:

    猜你喜欢
    • 2018-05-28
    • 1970-01-01
    • 1970-01-01
    • 2012-12-06
    • 2014-11-10
    • 1970-01-01
    • 2017-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多