(小ネタ)1000!を求めてみた。

誰得。
安 心 の 俺 得 ( `・ω・) b

なんてね。
実は「一番手軽に多倍長計算を実装したらどうなるか」を実験してて、思ったよりスッキリしなかったからこういうネタになってしまったと言うだけのはなしです(・ε・)〜♪

まあ、簡易的に多倍長計算実装しなきゃならないのは変わらず。まともなやり方を知らんので自己流でやった結果がこれだよ。

factor.cpp

#include<iostream>
#include<iomanip>
#include<string>
#include<cstdlib>
#define SIZE 1000
using namespace std;

class Integer{
	public:
	int parts[SIZE];
	Integer(string);
	Integer(int);
	Integer mul(Integer);
	void print();
};
Integer::Integer(int num){
	for(int i=0;i<SIZE;i++)parts[i]=0;
	for(int i=0;num!=0;num/=10000,i++){
		parts[i]=num%10000;
	}
}
Integer::Integer(string num){
	int len = num.length();
	for(int i=0;i<SIZE;i++)parts[i]=0;
	for(int i=0;len>0;len-=4,i++){
		if(len>4)parts[i]=strtol(num.substr(len-4,4).c_str(),NULL,10);
		else parts[i]=strtol(num.substr(0,len).c_str(),NULL,10);
	}
}
Integer Integer::mul(Integer num){
	Integer prod(0);
	for(int n=0;n<SIZE;n++){
		for(int i=0;i<SIZE;i++){
			prod.parts[n+i] += (parts[n]*num.parts[i]);
		}
	}
	for(int i=0;i<SIZE-1;i++){
		prod.parts[i+1] += (prod.parts[i]/10000);
		prod.parts[i] %= 10000;
	}
	return prod;
}
void Integer::print(){
	
	int i=SIZE-1;
	while(i<0 || parts[i]==0)i--;
	if(i<0){printf("0");return;}
	cout<<parts[i];i--;
	for(;i>=0;i--)cout<<setw(4)<<setfill('0')<<parts[i];
	return;
}
int main(){
	Integer num(1);
	for(int i=1;i<=1000;i++)num=num.mul(Integer(i) );
	num.print();
	cout<<endl;
	return 0;
}

ただ単に4ケタづつ区切って計算してるだけ。
勿論効率は悪いと思う。

ちなみに表示する関数printで4ケタ揃え+空白文字0指定の入出力マニピュレータをつかってるのは、4ケタづつに区切った各々の部分が4ケタの数字じゃなかったら表示がズレるからです。実は最初は気付かなかった(;・ω・)

無駄にstringで整数を受けれるようにしてあるところに多倍長計算実装チャレンジの名残が……もちろんこの部分余計です。

で、計算すると、まあ5秒かそこらで


40238726
0077093773543702433923003985719374864210
7146325437999104299385123986290205920442
0848696940480047998861019719605863166687
2994808558901323829669944590997424504087
0737599188236277271887325197795059509952
7612087497546249704360141827809464649629
1056393887437886487337119181045825783647
8499770124766328898359557354325131853239
5846307555740911426241747434934755342864
6576611667797396668820291207379143853719
5882498081268678383745597317461360853795
3452422158659320192809087829730843139284
4403281231558611036976801357304216168747
6096758713483120254785893207671691324484
2623613141250878020800026168315102734182
7977704784635868170164365024153691398281
2648102130927612448963599287051149649754
1990934222156683257208082133318611681155
3615836546984046708975602900950537616475
8477284218896796462449451607653534081989
0138544248798495995331910172335555660213
9450399736280750137837615307127761926849
0343526252000158885351473316117021039681
7592151090778801939317811419454525722386
5541461062892187960223838971476088506276
8629671466746975629112340824392081601537
8088989396451826324367161676217916890977
9911903754031274622289988005195444414282
0121873617459926429565817466283029555702
9902432415318161721046583203678690611726
0158783520751516284225540265170483304226
1439742869330616908979684825901254583271
6822645806652676995865268227280707578139
1858178889652208164348344825993266043367
6601769996128318607883861502794659551311
5655203609398818061213855860030143569452
7224206344631797460594682573103790084024
4324384656572450144028218852524709351906
2092902313649327349756551395872055965422
8749774011413346962715422845862377387538
2304838656889764619273838149001407673104
4664025989949022222176590433990188601856
6526485061799702356193897017860040811889
7299183110211712298459016419210688843871
2185564612496079872290851929681937238864
2614839657382291123125024186649353143970
1374285319266498753372189406942814341185
2015801412334482801505139969429015348307
7644569099073152433278288269864602789864
3211390835062170950025973898635542771967
4282224875758676575234422020757363056949
8825087968928162753848863396909959826280
9561214509948717012445164612603790293091
2088908694202851064018215439945715680594
1872748998094254742173582401063677404595
7417851608292301353580818400969963725242
3056085590370062427124341690900415369010
5933983835777939410970027753472000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
0000000000000000000000000000000000000000
という答えが返ってくる。
正直合ってんのか全くわからん。

そして今回はこれまで。
なんかこういう気軽な内容ちょくちょく更新していきたいですね。
(・ω・)ノシ<それじゃまた