215 = 32768 and the sum of its digits is 3 + 2 + 7 + 6 + 8 = 26.
What is the sum of the digits of the number 21000?
计算 2 的 1000次方的所有数字的和?
这个设计大数乘方问题,我自己写了一个计算大数乘方的函数来计算。
先来说下如何计算大数乘方的问题吧,通用的思路就是采用数组来分段处理大数,分段表示大数。(使用链表的话,其实也会更简单,更省空间的)
下面的算法中,我采用的是“万进制”,用数组来存储数据。
原理如下:
先说计数方法:
十进制和其他进制都是用权和数字(好象这里名词不对,记不清楚了)来计数的:
比如
2 的 26次方
num= 67108864
我们可以这样来写这个数:6710 8864
令arr[0] = 6710, arr[1] = 8864
那么,arr数组看起来就象和67108864是一样的
看到这里你明白了吧?
我们可以分段表示一个非常大的数而不必考虑它的溢出,
而只用考虑段数是否大于一个数即可
举个例子:
上边,单段的最大值是9999,每段不溢出
那么,num就不会溢出
再一个乘法.
我们老祖宗给我们留下的算盘,很妙,
它其实就是最基本的计算机之一
我们算乘方时,
只用乘以一个数:
这样来列式子:
123456790
*2=
--------------
246913580
即:
123 456 790
*2= *2= *2=
----- ----- ------
246 912 (1)580(溢出) 第三段有溢出,加到上一段
----- ----- --------
246 913 580
呵呵,就这样,打算盘一样,进位.
上面就是一般通用的原理了。上面的每段都是以999为限,我的代码是以9999为限。 分段处理每段数,溢出则进位。下面计算
这样计算2的1000次方就轻而易举了。 至于如何将最后数组里的每段数字相加,这个就简单了,每段进行转换,单个字符相加。
欧拉项目第16题/*----------------------- ** 计算大数乘方 ** 采用万进制 ------------------------*/ #include <stdio.h> #include <stdlib.h> #define N 1000 // 计算大数乘方的函数声明,x 的 y次方,返回整形数组 void BMul(int arr[], int x, int y); int main() { int arr[N] = {1}; BMul(arr, 4536, 144); int i; for(i = 0; i < N; i++) { if(arr[i] != 0) printf("%d", arr[i]); } int sum = 0; for(i= 0; i < N; i++) { if(arr[i] != 0) { char s[4]; memset(s, '\0', 4); sprintf(s, "%d", arr[i]); int j = 0; for(j =0; j < 4; j++) { if(s[j] != '\0') sum += s[j] - 48; } } } printf("\n"); printf("%d", sum); return 0; } void BMul(int arr[N], int x, int y) { int position = 1; // position 指示 x的y次方占用的段数 int yt; // yt 指数计数器 int at; // 占用段数计数器 int incse; //记录进位信息 int tmp = 0; for(yt = 0; yt < y; yt++) { incse = 0; for(at = 0; at < position; at++) { tmp = arr[at]; arr[at] *= x; // 第at段乘以x arr[at] += incse; // 加上来自第 at - 1段的进位 if(arr[at] > 9999) // 判断是否溢出 { if(at == position - 1) // 如果是首段溢出 { arr[position] = arr[at] / 10000; arr[at] = arr[at] % 10000; position ++; break; } else { incse = arr[at] / 10000; arr[at] = arr[at] % 10000; } } else // 此段不溢出 incse = 0; // 如果不溢出一定要记得将incse 归为0 否则隔空跳位 } } //将整形数组逆序 int i; for(i = 0; i < N / 2; i++) { int tmp; tmp = arr[i]; arr[i]= arr[N - 1 - i]; arr[N - 1 - i] = tmp; } }