这是一个来自Euler项目的Euler项目,这个问题包含了一些源代码,所以请考虑一下您的扰流板警报,以防您有兴趣自己解决它。不鼓励分发问题的解决方案,这不是我想要的。我只是需要一点点的推动和引导,在正确的方向,真诚的。
问题如下:
2^15 = 32768,其数字之和为3+2+7+6+8= 26。 数字2^1000的数字之和是多少?
我理解这个问题的前提和数学,但我一周前才开始练习C#,所以我的编程充其量是不稳定的。
我知道int、长和双对于精确地保持2^1000的300+ (基数10)数字是无可救药的,因此需要一些策略。我的策略是设置一个地获取数字的计算,并希望编译器能够找出如何计算每个数字,而不会出现溢出之类的错误:
using System;
using System.IO;
using System.Windows.Forms;
namespace euler016
{
class DigitSum
{
// sum all the (base 10) digits of 2^powerOfTwo
[STAThread]
static void Main(string[] args)
{
int powerOfTwo = 1000;
int sum = 0;
// iterate through each (base 10) digit of 2^powerOfTwo, from right to left
for (int digit = 0; Math.Pow(10, digit) < Math.Pow(2, powerOfTwo); digit++)
{
// add next rightmost digit to sum
sum += (int)((Math.Pow(2, powerOfTwo) / Math.Pow(10, digit) % 10));
}
// write output to console, and save solution to clipboard
Console.Write("Power of two: {0} Sum of digits: {1}\n", powerOfTwo, sum);
Clipboard.SetText(sum.ToString());
Console.WriteLine("Answer copied to clipboard. Press any key to exit.");
Console.ReadKey();
}
}
}对于powerOfTwo < 34,它似乎是完美的。我的计算器在这个数字上用完了,所以我不能测试更高的能量。但是跟踪程序,似乎没有溢出:随着powerOfTwo = 1000的增加,计算出的数字数逐渐增加,而数字之和(平均)也随着powerOfTwo的增加而增加。
对于我应该执行的实际计算,我得到了输出:
2的幂: 1000数字之和: 1189
但1189并不是正确的答案。我的节目怎么了?我愿意接受任何建设性的批评。
发布于 2013-10-11 04:22:46
正常的int无法帮助您处理这么大的数字。甚至连long都没有。他们从来没有被设计来处理如此庞大的数字。int可以存储大约10位数字(确切的最大值:2,147,483,647),long可以存储大约19位数字(确切的最大值:9,223,372,036,854,775,807)。然而,从内置Windows计算器中快速计算的结果告诉我,2^1000有300多位数。
(旁注:精确值可分别从int.MAX_VALUE和long.MAX_VALUE获得)
由于您需要精确的数字之和,即使是float或double类型也无法工作,因为它们只存储少量到几十位数字的有效数字。(7数字表示浮点,15-16数字表示双)。有关浮点表示、双精度的更多信息,请在这里阅读。
然而,C#为任意精度提供了内置的算术BigInteger,这应该适合您的(测试)需要。也就是说,可以用任意数量的数字进行算术(理论上是当然的)。实际上,它确实受到物理机器内存的限制,而且也需要时间,这取决于您的CPU能力)。
回到您的代码,我认为问题就在这里。
Math.Pow(2, powerOfTwo)
这就超出了计算范围。嗯,不完全是,但正如我所说的,double的精度并不精确地表示结果的实际值。
发布于 2014-01-29 00:39:50
不使用BigInteger类的解决方案是将每个数字存储在它自己的int中,然后手动进行乘法。
static void Problem16()
{
int[] digits = new int[350];
//we're doing multiplication so start with a value of 1
digits[0] = 1;
//2^1000 so we'll be multiplying 1000 times
for (int i = 0; i < 1000; i++)
{
//run down the entire array multiplying each digit by 2
for (int j = digits.Length - 2; j >= 0; j--)
{
//multiply
digits[j] *= 2;
//carry
digits[j + 1] += digits[j] / 10;
//reduce
digits[j] %= 10;
}
}
//now just collect the result
long result = 0;
for (int i = 0; i < digits.Length; i++)
{
result += digits[i];
}
Console.WriteLine(result);
Console.ReadKey();
}发布于 2013-10-11 05:13:09
我用的是按位向左移动。然后转换为数组并对其元素进行求和。我的最终结果是1366年,别忘了添加对System.Numerics的引用;
BigInteger i = 1;
i = i << 1000;
char[] myBigInt = i.ToString().ToCharArray();
long sum = long.Parse(myBigInt[0].ToString());
for (int a = 0; a < myBigInt.Length - 1; a++)
{
sum += long.Parse(myBigInt[a + 1].ToString());
}
Console.WriteLine(sum);https://stackoverflow.com/questions/19310133
复制相似问题