亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
12下一頁
最近訪問板塊 發(fā)新帖
查看: 4877 | 回復(fù): 19
打印 上一主題 下一主題

計算 1000! 源代碼 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2007-04-29 11:18 |只看該作者 |倒序瀏覽
看到論壇里好多討論大數(shù)階乘的話題的,我也來湊個熱鬧,貼一個自己前段時間剛寫的。
文件內(nèi)的注釋已經(jīng)很清楚了,懶得再用中文寫一遍了,請大家看英文注釋吧。
文件已包含測試代碼,main函數(shù)計算了1000!。

測試結(jié)果:

  1. [ykuang@qdcvs 0_UnSorted]$ a.out
  2. indexEnd: 641
  3. ======================== 1000! =======================
  4. 402387260077093773543702433923003985719374864210714632543799910429938512398629020592044208486969404800479988610197196058631666872994808558901323829669944590997424504087073759918823627727188732519779505950995276120874975462497043601418278094646496291056393887437886487337119181045825783647849977012476632889835955735432513185323958463075557409114262417474349347553428646576611667797396668820291207379143853719588249808126867838374559731746136085379534524221586593201928090878297308431392844403281231558611036976801357304216168747609675871348312025478589320767169132448426236131412508780208000261683151027341827977704784635868170164365024153691398281264810213092761244896359928705114964975419909342221566832572080821333186116811553615836546984046708975602900950537616475847728421889679646244945160765353408198901385442487984959953319101723355556602139450399736280750137837615307127761926849034352625200015888535147331611702103968175921510907788019393178114194545257223865541461062892187960223838971476088506276862967146674697562911234082439208160153780889893964518263243671616762179168909779911903754031274622289988005195444414282012187361745992642956581746628302955570299024324153181617210465832036786906117260158783520751516284225540265170483304226143974286933061690897968482590125458327168226458066526769958652682272807075781391858178889652208164348344825993266043367660176999612831860788386150279465955131156552036093988180612138558600301435694527224206344631797460594682573103790084024432438465657245014402821885252470935190620929023136493273497565513958720559654228749774011413346962715422845862377387538230483865688976461927383814900140767310446640259899490222221765904339901886018566526485061799702356193897017860040811889729918311021171229845901641921068884387121855646124960798722908519296819372388642614839657382291123125024186649353143970137428531926649875337218940694281434118520158014123344828015051399694290153483077644569099073152433278288269864602789864321139083506217095002597389863554277196742822248757586765752344220207573630569498825087968928162753848863396909959826280956121450994871701244516461260379029309120889086942028510640182154399457156805941872748998094254742173582401063677404595741785160829230135358081840096996372524230560855903700624271243416909004153690105933983835777939410970027753472000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
  5. ======================== end ===========================
復(fù)制代碼


放上計算10000。ǘ,不是1000!, 是10000。┑倪\行時間, 供大家參考:


  1. [ykuang@qdcvs 0_UnSorted]$ time a.out
  2. indexEnd: 8914
  3. ======================== 10000! =======================
  4. 2846259680917054518906413212119868890148....
  5. /*結(jié)果太大,論壇發(fā)帖限制,這里省略,但運行時間是硬梆梆的!*/
  6. ======================== end ===========================

  7. real    0m2.196s
  8. user    0m1.730s
  9. sys     0m0.000s
復(fù)制代碼


/*                 LargeNumFactorial.cpp
  * #g++ LargeNumFactorial.cpp
  * #a.out
  */

  1. #include <iostream>
  2. #include <string>
  3. #include <sstream>
  4. #include "LargeNumMultiply.h"

  5. using namespace std;

  6. /*
  7. * The factorial of big number: e.g. 20000!
  8. *
  9. * Parameter:
  10. *      N     -   The big number;
  11. *  factorial  -   The result of factorial.
  12. *  indexEnd  -   The valid max index of factResult array.
  13. *  baseSize  -   How many bits of factResult[i] should be saved.
  14. *                e.g. If N = 8, baseSize = 2,
  15. *                     then factResult[0] = 20
  16. *                          factResult[1] = 3, should be taken as 03 because baseSize if 2
  17. *                          factResult[2] = 4, should be taken as 04, but since indexEnd is 2, only 4 is good.
  18. *                          result = 40302
  19. *                     
  20. *                     If N = 8, baseSize = 3,
  21. *                     then factResult[0] = 320,
  22. *                          factResult[1] = 40, should be taken as 040, but since indexEnd is 1, only 40 is good.
  23. *                     
  24. *                     If N = 8, baseSize = 4,
  25. *                     then factResult[0] = 320, should be taken as 0320 because baseSize if 4.
  26. *                          factResult[1] = 4,   should be taken as 0004, but since indexEnd is 1, only 4 is good.
  27. *
  28. * Note:
  29. *    Make sure N is <= MAX_FACT.
  30. *    Because every multiply result is stored at an unsigned int var, so we need to make sure
  31. *    the every step of mutiply result should be less than UINT_MAX.
  32. * */

  33. int Factorial (unsigned int N, unsigned int *factResult, int *indexEnd, unsigned int baseSize)
  34. {
  35.     if (N > MAX_FACT)
  36.     {
  37.         cout << "N should not be larger than: " <<MAX_FACT <<endl;
  38.         return 0;
  39.     }

  40.     int valIndex = 0;
  41.     factResult[0] = 1;

  42.     unsigned int baseValue = 1;
  43.     for( unsigned int k = 0; k < baseSize; k++ )
  44.         baseValue *= 10;

  45.     /* If baseValue * N is larger than UINT_MAX, we will overflow at factResult[j] *= i;*/
  46.     if ( baseValue > (UINT_MAX/N))
  47.     {   
  48.         cout <<"baseSize: "<< baseSize<<" is too large, will make factResult[i] * N larger than UINT_MAX." <<endl;
  49.         cout <<"Please choose smaller baseSize"<<endl;
  50.         return 0;
  51.     }
  52.    
  53.     for( unsigned int i = 1; i <= N; i++ )
  54.     {   
  55.         unsigned int add = 0;
  56.         // Every time we multiply i, we should multily every section of factResult.
  57.         // valIndex stands for the lagest index of elem that is valid in factResult;
  58.         for( int j = 0; j <= valIndex ; j++ )
  59.         {   
  60.             // Multiply of result section j.
  61.             factResult[j] *= i;                 
  62.             // Add the 'add' from lower section.
  63.             factResult[j] += add;
  64.             // Caculate 'add' of section j.
  65.             add = factResult[j]/baseValue;
  66.             // Caculate value of section j.
  67.             factResult[j] %= baseValue;
  68.         }
  69.         if( add > 0 )
  70.             // if 'add' is not 0, then store 'add' to higher section.
  71.             factResult[++valIndex] = add;
  72.     }
  73.     // Store the valid index of array factResult;
  74.     *indexEnd = valIndex;
  75.     return 1;
  76. }

  77. string IntToStr (unsigned int value, unsigned int baseSize )
  78. {
  79.     ostringstream o;
  80.     string s="";
  81.     if( o<<value )
  82.         s = o.str();
  83.     else return "";
  84.     int j;
  85.     int l = baseSize - s.length();
  86.     for( j = 0; j < l; j++ )
  87.         s = "0" + s;
  88.     return s;
  89. }

  90. int main()
  91. {
  92.     unsigned int factResult[100000];
  93.     int indexEnd;
  94.     int baseSize = 4;
  95.     Factorial (1000, factResult, &indexEnd, baseSize);

  96.     cout <<"indexEnd: "<< indexEnd << endl;
  97.     cout <<"======================== start ======================="<<endl;
  98.     /*
  99.      * 8! = 40320, if baseSize is 2, then factResult:
  100.      * factResult[0] = 4
  101.      * factResult[1] = 3
  102.      * factResult[2] = 20
  103.      * Result: 40320, not 040320
  104.      * */
  105.     cout << factResult[indexEnd];
  106.     for (int i = indexEnd-1; i >= 0; i-- )
  107.         cout << IntToStr (factResult[i], baseSize);
  108.     cout<<"\n======================== end ==========================="<<endl;
  109. }

復(fù)制代碼


/*LargeNumMultiply.h*/

  1. #ifndef __MYUTILSTUFF_H
  2. #define __MYUTILSTUFF_H

  3. #include <climits>
  4. #include <cmath>
  5. #include <iostream>
  6. using namespace std;

  7. const unsigned int MAX_FACT = (unsigned int)sqrt((double)UINT_MAX);
  8. int Factorial (unsigned int N, unsigned int *factResult, int *indexEnd , unsigned int baseSize = 5 );
  9. string IntToStr (unsigned int value, unsigned int baseSize);
  10. void BigNumMutiply (unsigned int N1, unsigned int N2, unsigned int *factResult, unsigned int n);

  11. #endif
復(fù)制代碼

[ 本帖最后由 softsongs 于 2007-4-29 21:14 編輯 ]

評分

參與人數(shù) 1可用積分 +1 收起 理由
win_hate + 1 原創(chuàng)內(nèi)容

查看全部評分

論壇徽章:
39
2017金雞報曉
日期:2017-02-08 10:39:4219周年集字徽章-周
日期:2023-04-15 12:02:2715-16賽季CBA聯(lián)賽之深圳
日期:2023-02-16 14:39:0220周年集字徽章-年
日期:2022-08-31 14:25:28黑曼巴
日期:2022-08-17 18:57:0919周年集字徽章-年
日期:2022-04-25 13:02:5920周年集字徽章-20	
日期:2022-03-29 11:10:4620周年集字徽章-年
日期:2022-03-14 22:35:1820周年集字徽章-周	
日期:2022-03-09 12:51:3220周年集字徽章-年
日期:2022-02-10 13:13:4420周年集字徽章-周	
日期:2022-02-03 12:09:4420周年集字徽章-20	
日期:2022-01-25 20:14:27
2 [報告]
發(fā)表于 2007-04-29 11:28 |只看該作者
好貼,比GMP速度如何?

論壇徽章:
0
3 [報告]
發(fā)表于 2007-04-29 11:33 |只看該作者
不知道GMP是什么,呵呵。
速度么,計算1000!幾乎不需要等待。
可以自己編譯測試一下。

原帖由 醉臥水云間 于 2007-4-29 11:28 發(fā)表
好貼,比GMP速度如何?

論壇徽章:
39
2017金雞報曉
日期:2017-02-08 10:39:4219周年集字徽章-周
日期:2023-04-15 12:02:2715-16賽季CBA聯(lián)賽之深圳
日期:2023-02-16 14:39:0220周年集字徽章-年
日期:2022-08-31 14:25:28黑曼巴
日期:2022-08-17 18:57:0919周年集字徽章-年
日期:2022-04-25 13:02:5920周年集字徽章-20	
日期:2022-03-29 11:10:4620周年集字徽章-年
日期:2022-03-14 22:35:1820周年集字徽章-周	
日期:2022-03-09 12:51:3220周年集字徽章-年
日期:2022-02-10 13:13:4420周年集字徽章-周	
日期:2022-02-03 12:09:4420周年集字徽章-20	
日期:2022-01-25 20:14:27
4 [報告]
發(fā)表于 2007-04-29 18:31 |只看該作者
不會吧,不知道GMP是什么?
那么你的代碼計算10000!效果如何,時間多久?抗的住么?
我一般用GMP, windows和linux都好用.功能也全.

論壇徽章:
0
5 [報告]
發(fā)表于 2007-04-29 18:35 |只看該作者
用 OpenSSL 的 BN 類型試一試。

論壇徽章:
0
6 [報告]
發(fā)表于 2007-04-29 21:11 |只看該作者
醉臥水云間 兄說笑了,計算10000!很輕松。

下面這個有說服力了吧,呵呵

[ykuang@qdcvs 0_UnSorted]$ time a.out
indexEnd: 8914
======================== 10000! =======================
2846259680917054518906413212119868890148....
/*結(jié)果太大,論壇發(fā)帖限制,這里省略,但運行時間是硬梆梆的!*/
======================== end ===========================

real    0m2.196s
user    0m1.730s
sys     0m0.000s

原帖由 醉臥水云間 于 2007-4-29 18:31 發(fā)表
不會吧,不知道GMP是什么?
那么你的代碼計算10000!效果如何,時間多久?抗的住么?
我一般用GMP, windows和linux都好用.功能也全.

[ 本帖最后由 softsongs 于 2007-4-29 21:13 編輯 ]

論壇徽章:
0
7 [報告]
發(fā)表于 2007-04-29 21:52 |只看該作者
gmp 是這樣處理的:

1) n! 分解成 2^m p_1^a_1 p_2^a_2 ... p_r^a_r

2)2^m 只不過是移位

3)其余素因子按方冪分組,即同次的放在一起,變成 (q_1 q_2 ... q_t)^a 的形式。由于我們能快速計算方冪,所以先求出  q_1 .. q_r 的值就可以了

4)求 q_1 ... q_r 時分組,使中間結(jié)果長度相近,然后當(dāng)數(shù)比較大時,可以采用經(jīng)典的快速乘法。

評分

參與人數(shù) 1可用積分 +2 收起 理由
langue + 2

查看全部評分

論壇徽章:
0
8 [報告]
發(fā)表于 2007-04-29 21:55 |只看該作者
原帖由 win_hate 于 2007-4-29 21:52 發(fā)表
gmp 是這樣處理的:

1) n! 分解成 2^m p_1^a_1 p_2^a_2 ... p_r^a_r

2)2^m 只不過是移位

3)其余素因子按方冪分組,即同次的放在一起,變成 (q_1 q_2 ... q_t)^a 的形式。由于我們能快速計算方冪,所以先求出  q_1 .. q_r 的值就可以了

4)求 q_1 ... q_r 時分組,使中間結(jié)果長度相近,然后當(dāng)數(shù)比較大時,可以采用經(jīng)典的快速乘法。


divide-and-conquer?

.

論壇徽章:
39
2017金雞報曉
日期:2017-02-08 10:39:4219周年集字徽章-周
日期:2023-04-15 12:02:2715-16賽季CBA聯(lián)賽之深圳
日期:2023-02-16 14:39:0220周年集字徽章-年
日期:2022-08-31 14:25:28黑曼巴
日期:2022-08-17 18:57:0919周年集字徽章-年
日期:2022-04-25 13:02:5920周年集字徽章-20	
日期:2022-03-29 11:10:4620周年集字徽章-年
日期:2022-03-14 22:35:1820周年集字徽章-周	
日期:2022-03-09 12:51:3220周年集字徽章-年
日期:2022-02-10 13:13:4420周年集字徽章-周	
日期:2022-02-03 12:09:4420周年集字徽章-20	
日期:2022-01-25 20:14:27
9 [報告]
發(fā)表于 2007-04-29 22:02 |只看該作者
原帖由 softsongs 于 2007-4-29 21:11 發(fā)表
醉臥水云間 兄說笑了,計算10000!很輕松啊:

下面這個有說服力了吧,呵呵

[ykuang@qdcvs 0_UnSorted]$ time a.out
indexEnd: 8914
======================== 10000! =======================
2846259 ...


回頭我抽時間比較一下GMP和你的代碼誰更快,謝謝!

論壇徽章:
0
10 [報告]
發(fā)表于 2007-04-29 22:05 |只看該作者
原帖由 langue 于 2007-4-29 21:55 發(fā)表


divide-and-conquer?

.


嗯,那個父親臨終之前應(yīng)該舉計算階乘為例子,而不應(yīng)該舉竹筷........
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP