数字 2^1000 的数字之和是多少
本文关键字:数字 多少 1000 | 更新日期: 2023-09-27 18:34:47
这是欧拉计划的一个问题,这个问题包括一些源代码,所以如果你有兴趣自己解决它,请考虑你的剧透警报。不鼓励分发问题的解决方案,这不是我想要的。我只是真诚地在正确的方向上得到一点推动和指导。
问题如下:
2^15 = 32768,其数字之和为 3 + 2 + 7 + 6 + 8 = 26。
数字 2^1000 的数字之和是多少?
我了解问题的前提和数学原理,但我一周前才开始练习 C#,所以我的编程充其量是不稳定的。
我知道 int、long 和 double 对于精确地保存 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 的增加而增加。
对于我应该执行的实际计算,我得到输出:
二的幂:1000 数字总和:1189
但1189不是正确的答案。我的程序有什么问题?我愿意接受任何和所有建设性的批评。
为了计算如此大的数字的值,你不仅需要成为一名优秀的程序员,还需要成为一名优秀的数学家。这里有一个提示给你,有熟悉的公式 a x= e xln a ,或者如果您愿意,AX = 10x log a。
更具体地针对您的问题21000 求 2 的公共(基数为 10(对数,乘以 1000;这是 10 的幂。如果您得到类似 10 53.142 (53.142 = log 2 值 * 1000( - 您很可能会得到 - 那么那就是 1053 x 100.142;只需计算 100.142,您将获得一个介于 1 和 10 之间的数字;并将其乘以 10 53,但是这个 10 53 将没有用,因为53 零和将仅为零。
对于 C# 中的日志计算
Math.Log(num, base);
为了获得更高的准确性,您可以使用大整数的日志和Pow函数。
现在休息编程帮助我相信你可以从你身边得到。
普通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
精度并不能精确地代表结果的实际值。
不使用 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();
}
我使用了向左按位移动。然后转换为数组并对其元素求和。我的最终结果是 1366,不要忘记添加对系统数字的引用;
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);
因为这个问题是特定于 C# 的,使用 bigInt 可能会完成这项工作。 在Java和Python中,它也可以工作,但是在C和C ++等语言中,如果该工具不可用,则必须使用数组并进行乘法。 在数组中取一个大数字并将其乘以 2。 这很简单,将有助于提高您的逻辑技能。 并来到欧拉项目。 有一个你必须找到100的问题!您可能还希望为此应用相同的逻辑。
尝试使用 BigInteger type
,2^100 最终将得到一个非常大的数字,即使是双精度才能处理。
BigInteger bi= new BigInteger("2");
bi=bi.pow(1000);
// System.out.println("Val:"+bi.toString());
String stringArr[]=bi.toString().split("");
int sum=0;
for (String string : stringArr)
{ if(!string.isEmpty()) sum+=Integer.parseInt(string); }
System.out.println("Sum:"+sum);
------------------------------------------------------------------------
output :=> Sum:1366
这是我在 JavaScript 中的解决方案
(function (exponent) {
const num = BigInt(Math.pow(2, exponent))
let arr = num.toString().split('')
arr.slice(arr.length - 1)
const result = arr.reduce((r,c)=> parseInt(r)+parseInt(c))
console.log(result)
})(1000)
这不是一个严肃的答案——只是一个观察。
虽然尝试仅使用一种编程语言击败欧拉计划是一个很好的挑战,但我相信该网站旨在促进所有尝试它的程序员的视野。换句话说,考虑使用不同的编程语言。
一个通用的Lisp解决方案可以像这样简单
(defun sum_digits (x)
(if (= x 0)
0
(+ (mod x 10) (sum_digits (truncate (/ x 10))))))
(print (sum_digits (expt 2 1000)))
main()
{
char c[60];
int k=0;
while(k<=59)
{
c[k]='0';
k++;
}
c[59]='2';
int n=1;
while(n<=999)
{
k=0;
while(k<=59)
{
c[k]=(c[k]*2)-48;
k++;
}
k=0;
while(k<=59)
{
if(c[k]>57){ c[k-1]+=1;c[k]-=10; }
k++;
}
if(c[0]>57)
{
k=0;
while(k<=59)
{
c[k]=c[k]/2;
k++;
}
printf("%s",c);
exit(0);
}
n++;
}
printf("%s",c);
}
Python 使得使用单行计算这一点变得非常简单:
print sum(int(digit) for digit in str(2**1000))
或者使用地图:
print sum(map(int,str(2**1000)))