[問題] 1+2+3+...加到20位數~~~累加問題

看板C_and_CPP (C/C++)作者 (Yen)時間14年前 (2011/12/06 02:42), 編輯推噓3(3020)
留言23則, 6人參與, 最新討論串1/1
朋友問的一個累加問題,寫了兩小時還是寫不太對,所以來詢問各位大大意見: 1+2+3+...+12345678901234567895 現在我遇到的問題是,累加到後面的位數太多(到20位數 int的記憶體不夠用 我是有想到先用梯形公式處理數字: (min+max)*max/2+(max/2)+1 之後再用陣列的方式處理:我寫的程式 #include <stdio.h> #include <stdlib.h> #include <string.h> #define N 100 int main() { int min=1,i,j; unsigned int max=18446744073709551615,medi,medi1,math,temp; char arr[N]; printf("計算1+2+3+...+18446744073709551615為多少\n"); medi=max/2; //sum=((min+max)*medi+medi+1); printf("min="); printf("%d",min); printf("\n"); printf("max="); printf("%d",max); printf("\n"); printf("medi="); printf("%d",medi); printf("\n"); memset(arr,0,N); arr[N-1]=1; temp=0; math=0; for(i=N-1;i>=0;i--){ temp=arr[i]*(min+max)+math; arr[i]=temp%10; math=temp/10; } for(i=N-1;i>=0;i--){ temp=arr[i]*medi+math; arr[i]=temp%10; math=temp/10; } medi1=medi+1; for(i=N-1;i>=0;i--){ temp=arr[i]+medi1; arr[i]=temp%10; medi1=temp/10; } printf("計算結果為:"); for(i=0;arr[i]==0;i++){} for(j=i;j<N;j++){ printf("%d",arr[j]); } system("pause"); return 0; } 這樣會比直接用for迴圈累加來的好, 只是寫到這裡,還是卡在記憶體不足的問題,累加頂多加到10位數就極限了 在多加就出現錯誤,所以懇請大大們賜教,幫忙解惑~卸卸!!! -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 111.251.136.37

12/06 02:51, , 2F
最近作業好像都在搞大數...
12/06 02:51, 2F

12/06 02:58, , 3F
用double夠嗎
12/06 02:58, 3F

12/06 03:01, , 4F
double 不行,我於文中有說過,它精度受限於ieee754之
12/06 03:01, 4F

12/06 03:01, , 5F
mantissa欄位只有52bits,所以超過2^52之後,再+1都加不
12/06 03:01, 5F

12/06 03:02, , 6F
進去。 (正確數字不是2^52,只是我懶得分析是多大.)
12/06 03:02, 6F

12/06 03:12, , 7F
double 參考一下demo code http://ideone.com/6dHCT
12/06 03:12, 7F

12/06 03:13, , 8F
最後換到十進位精度的大概只有 15.9x 位數。
12/06 03:13, 8F

12/06 04:09, , 9F
可不可以拆成前十位和後十位來算? 譬如0加到99可以拆成
12/06 04:09, 9F

12/06 04:11, , 10F
前一位和後一位來算 也就是10個"0加到9"加上 10*10個"0加
12/06 04:11, 10F

12/06 04:11, , 11F
到9" = 10*45 + 10*10*45 這種算法
12/06 04:11, 11F

12/06 04:14, , 12F
(我碰到這種問題都會想要直接從數學上解決XD)
12/06 04:14, 12F

12/06 04:17, , 13F
樓上這樣便是有用到大數演算法的概念.不同位數和不同
12/06 04:17, 13F

12/06 04:17, , 14F
位數相加,有進位再丟到下一位數.
12/06 04:17, 14F

12/06 15:58, , 15F
就google一下大數的作法
12/06 15:58, 15F

12/06 17:36, , 16F
^^" 我沒學過不曉得 不過數學上的直覺似乎就會想到這樣吧
12/06 17:36, 16F

12/06 18:28, , 17F
剛好是 ull 的極限
12/06 18:28, 17F

12/06 20:48, , 18F
18446744073709551615 是還在裡面,但結果似乎就..
12/06 20:48, 18F

12/06 21:08, , 19F
答案參考一下.. http://ideone.com/Y5gm7
12/06 21:08, 19F

12/06 21:09, , 20F
12/06 21:09, 20F

12/06 21:13, , 21F
答案很漂亮, 花點心思分解下, 兩個 ull 加位移就搞定
12/06 21:13, 21F

12/06 21:18, , 22F
loveme 大說得沒錯,唯我是把之前寫好的拉出來改而已 xd
12/06 21:18, 22F

12/07 23:03, , 23F
謝謝各位大大解答~我大約知道怎麼改寫程式了~~~
12/07 23:03, 23F
文章代碼(AID): #1EtH2D8I (C_and_CPP)
文章代碼(AID): #1EtH2D8I (C_and_CPP)