C# 对超长二进制数的数字求和?

C# 对超长二进制数的数字求和?,c#,binary,numbers,.net-2.0,C#,Binary,Numbers,.net 2.0,一位朋友问我: 如果2^10=1024,我们可以取1024,并对其数字进行分解和汇总: 1+0+2+4=7。 这很容易 但是,当输入是2^30000(输入实际上是一个长字符串“1000…”)--没有.net类型可以保存此值 所以必须有一个技巧来求和它的数字(十进制值的数字) 编辑: 相关技巧(用于查找10^20-16) 100=10^2(一个零和两个零) 10^20=(1和20个零) 因此: 10^20-16=18个9,一个8加4 18*9+8+4=174 但我还没有成功地将这个解决方案转化为我

一位朋友问我:

如果
2^10=1024
,我们可以取1024,并对其数字进行分解和汇总:

1+0+2+4=7。

这很容易

但是,当输入是
2^30000
(输入实际上是一个长字符串
“1000…”
)--没有.net类型可以保存此值

所以必须有一个技巧来求和它的数字(十进制值的数字)

编辑:

相关技巧(用于查找
10^20-16

100=10^2(一个零和两个零)

10^20=(1和20个零)

因此:

10^20-16=18个9,一个8加4

18*9+8+4=174

但我还没有成功地将这个解决方案转化为我的问题(我尝试了很多)

*我将这个问题标记为.net,因为我可以使用.net库中的字符串函数和数学函数*

问题

这里有没有什么技巧可以让我对许多由
x^n
产生的数字求和

这里的诀窍是什么

已编辑的#2:添加了.net2标记(其中biginteger不可用)-我想知道没有biginteger我怎么做。(我正在寻找隐藏的技巧)

您可以利用该结构来实现这一点。如MSDN中所述

BigInteger类型是表示 理论上其值没有上限或下限的任意大整数 界限

基本上,在创建BigInteger实例并计算指数后,可以将其转换为字符串。之后,您将迭代该字符串的每个字符,并将每个字符转换为整数。把这些整数加起来,你就会得到答案

BigInteger bi = new BigInteger(2);
var bi2 = BigInteger.Pow(bi, 30000);
BigInteger sum = new BigInteger();
foreach(var ch in bi2.ToString())
    sum = BigInteger.Add(sum, new BigInteger(int.Parse(ch.ToString())));
MessageBox.Show(bi2.ToString() + " - " + sum.ToString());

我不相信这里有什么把戏。 您展示的后一个技巧有效,因为数字和结果都是十进制数字

For example:
1267 = 1*10^3 + 2*10^2 + 6*10^1 + 7*10^0
所以你知道,幂和和和之间有明显的相关性。 但不幸的是,如果你想把二进制数,或2的幂,转换成十进制数,那是行不通的。最大的努力是降低功率以增加基数

2^3000 = 4^1500 = 16^750 = 256^375

但正如你所看到的,这个系列跨越了10垒。不幸的是,这意味着您需要将最终结果计算为十进制数,然后才能将其转换为10的幂。使这个技巧不起作用。

我所知道的寻找一个数字的基数10位数和的一般技巧

然而,有一个简单的技巧可以找到一个数字的基数10位数的根

正如你所说,数字和就是所有数字的和。1024的基数10位数之和为1+2+4=7。65536的基数10位和为6+5+5+3+6=25

当你重复数字和直到只有一个数字时,你得到的是数字根。65536的数字和是25,因此数字根是2+5=7

诀窍是:如果你有Z=X*Y,那么DigitRoot(Z)=DigitRoot(DigitRoot(X)*DigitRoot(Y))。(给读者的练习:证明它!提示:从证明相同的身份开始添加。)

如果你有一个容易分解的数字——最容易分解的数字是2n——那么很容易递归地计算出数字根:216=28*28,所以DigitRoot(216)=DigitRoot(DigitRoot(28)*DigitRoot(28))——我们只是把问题缩小了很多。现在我们不需要计算216,我们只需要计算28。当然,你可以对230000使用这个技巧——将其分解为DigitRoot(DigitRoot(215000*DigitRoot(215000))。如果215000太大,则进一步分解;继续分解,直到有足够小的问题可以解决

有意义吗?

来自:

公共类问题\u 16{
公共长数据集(int-base,int-exp){
int numberOfDigits=(int)Math.ceil(exp*Math.log10(base));
int[]位=新的int[numberOfDigits];
数字[0]=基数;
int currentExp=1;
while(currentExp
c#

公共类问题\u 16{
公共长数据集(int base1,int exp){
int numberOfDigits=(int)数学上限(exp*Math.Log10(base1));
int[]位=新的int[numberOfDigits];
数字[0]=base1;
int currentExp=1;
while(currentExp
你是特别要求
2^30000
2的幂
,还是仅仅要求任何大的数?@Paulpro 2的幂.
2^n
,其中n是
1..让我们说int.max
(我说int.max只是为了表示一个其十进制表示法不适合任何.net类型的数字)这个“把戏”错误:如果你从100^20中减去33,结果将是99…999967,而不是100…0000967。@Edwin:但是这与计算
2^n
,有什么区别呢?@KenKin no。只有十进制数的总和。例如:2^12=4096。所以我想要4+0+9+6,即19。(我不需要1+9,即10 w)
public class Problem_16 {
    public long sumOfDigits(int base, int exp) {
        int numberOfDigits = (int) Math.ceil(exp * Math.log10(base));
        int[] digits = new int[numberOfDigits];
        digits[0] = base;
        int currentExp = 1;

        while (currentExp < exp) {
            currentExp++;
            int carry = 0;
            for (int i = 0; i < digits.length; i++) {
                int num = base * digits[i] + carry;
                digits[i] = num % 10;
                carry = num / 10;
            }
        }

        long sum = 0;
        for (int digit : digits)
            sum += digit;

        return sum;
    }

    public static void main(String[] args) {
        int base = 2;
        int exp = 3000;
        System.out.println(new Problem_16().sumOfDigits(base, exp));
    }
}
public class Problem_16 {
    public long sumOfDigits(int base1, int exp) {
        int numberOfDigits = (int) Math.Ceiling(exp * Math.Log10(base1));
        int[] digits = new int[numberOfDigits];
        digits[0] = base1;
        int currentExp = 1;

        while (currentExp < exp) {
            currentExp++;
            int carry = 0;
            for (int i = 0; i < digits.Length; i++) {
                int num = base1 * digits[i] + carry;
                digits[i] = num % 10;
                carry = num / 10;
            }
        }

        long sum = 0;
        foreach (int digit in  digits)
            sum += digit;

        return sum;
    }
}


void Main()
{
     int base1 = 2;
        int exp = 3000000;
        Console.WriteLine (new Problem_16().sumOfDigits(base1, exp));

}