不使用BigInt计算为2 ^ 1000的总和

时间:2010-07-13 10:38:23

标签: c# c#-4.0 bigint

正如你们中的一些人可能会注意到这个问题来自problem 16 Project Euler。我已经使用C#4.0的新“bigInt”功能解决了这个问题,这个功能非常简单,但也没有真正学到我应该学到的东西。我假设因为它是2 ^ 1000会有某种位移解决方案,但我无法弄清楚它究竟是如何工作的。

有人在不使用bigint的情况下知道计算2 ^ 1000的方法吗?

8 个答案:

答案 0 :(得分:3)

这个问题最困难的部分不是计算(只用1开头,加倍1000倍),但是以十进制显示答案。考虑到这一点,您可能会发现在概念上更容易以某种形式的BCD表示执行计算,例如base-1000。然后进行长度乘法2千次。这是一个Python解决方案:

def mul2(n):
    result = []
    carry = 0
    for i in n:
        i = i * 2 + carry
        carry = 0 if i < 1000 else 1
        result.append(i % 1000)
    if carry: result.append(1)
    return result

n = [1]
for _ in range(1000):
    n = mul2(n)

print ''.join('{0:03}'.format(i) for i in reversed(n)).lstrip('0')

答案 1 :(得分:2)

这是一种相当天真的方式在python中使用数字列表(或数组)

digits = [1]
for n in range(1000):
    newdigits = []
    carry = 0
    for digit in digits:
        s = 2*digit+carry
        carry = s/10
        s = s%10
        newdigits.append(s)
    if carry:
        newdigits.append(carry)
    digits = newdigits
print "".join(map(str,reversed(digits)))

答案 2 :(得分:1)

你可能会自己暗示BigInt,可能会引入错误,并可能导致更慢的解决方案。典型的实现是自己手动执行数学运算(基于每个数字),具有一些高基数,例如基数为2 ^ 16的数字。

答案 3 :(得分:1)

问题实际上是将2 ^ 1000转换为基数10.一种简单的方法是实现某种任意长度的BCD(二进制编码十进制)并在BCD中计算2 ^ 1000。一个250字节的数组就足够了。然后你只需编写方法来对任意长度的BCD编号执行* 2并将其调用1000次)。然后提取和求和数字很容易。

即使在像C这样的语言中也很容易实现。

答案 4 :(得分:1)

class Program
{
    static void Main(string[] args)
    {
        double sum=0;
        for (int i = 1000; i <=1000; i++)
        {
            double pow = Math.Pow(2, i);
            string power = pow.ToString();
            for (int j = 0; j < power.Length; j++)
            {
                 sum = sum+pow % 10;
                 StringBuilder t = new StringBuilder(pow.ToString());
                 int len = t.Length;
                 if (len != 1)
                 {
                     t.Remove(len - 1, 1);
                 }
                 pow = Convert.ToDouble(t.ToString());
            }
             Console.WriteLine(sum);
                Console.WriteLine();

        }
    }
}

答案 5 :(得分:0)

好的就是:

1 << 1000

更严重的是,您在x位整数中保留的最多是1<<x-1。要实际计算1<<1000,你需要一个1000位处理器(技术上是1001位,但是在这一点上谁在计算)。由于这不可行,你唯一的选择是模仿它(这就是bigint的作用)。

答案 6 :(得分:0)

实际上无法计算:2^1000 = (1000...[994]...000)[Base2]。这已经是“结果”了。

如果您想知道如何存储它,您的机器没有精确度来存储其准确值。所以它是BigInt或双近似值Math.Pow(2, 1000)

编辑:我现在看到来自评论只想要数字的总和。请参阅其中一个解决方案。

答案 7 :(得分:0)

我会尝试回答而不会泄露太多代码......

1)使用String来保存产品

2)执行长乘法(就像你在学校一样)

Prod = "1"
for n = 1 to 1000
        carry = 0
        newprod = ""
        for i = strlen(prod) - 1 to 0 step - 1
                digit = int(prod[i])
                p = digit * 2 + carry
                newprod = (p % 10) & newprod // append
                carry = p / 10
        next
        if( carry > 0) newprod = carry & newprod
        prod = newprod
next

print prod

Notepad-Coding here ...所以,如果有人发现错误,请更正错误。