首页 > 编程知识 正文

c语言实现n的阶乘三种方法,c语言求1到20的阶乘

时间:2023-05-04 16:47:43 阅读:118093 作者:1186

2015-06-21 06:30:01

读(309 )。

大数量阶乘,计算10000! 时间在200毫秒以内,主要采用10^8进制优化(许多其他demo程序采用10进制大整数算法,实现效率低下),期望fft实现得更快。

//====================================

//Name : factorial.cpp

//Author : hyb

//版本: 3.0

//版权所有: 2007-2012

//Description : calculate n! with n 100000

//====================================

#包含

#包含

#包含

#包含

#包含

用户命名空间STD;

#定义线宽度80

#定义基础100000000

#定义digit 8

#定义最大化(500000/digit )。

#ifdef _WIN32

typedef unsigned __int64 uint64;

#else

类型def unsigned long long uint 64;

#endif

typedef unsigned int uint;

#define MULTI_THREAD

#define MAX_THREADS 2

类工厂;

factorial无可救药的酸奶hyb[1024];

类工厂

{

公共:

静态uint 64 s _ buffer [ maxsize ];

uint无可救药的酸奶m_digit;

uint m_multiplicand[5];

uint m_length,m_0,m_5;

int m_beg,m_end;

公共:

factorial(intbeg,int end ) )。

{

static int s_offset=0;

this-m_beg=beg;

this-m_end=end;

intt_d=total_d(Beg-1,end );

m_5=total_0(Beg-1,end );

m_0=0;

m_digit=(uint没办法的酸奶) s_buffer s_offset );

m_digit[0]=m_length=1;

s_offset=(t_d-m_5)/DIGIT 1;

}

void start () )

{

wile(m_end=m_beg ) {

uint64 multiplicand=m_end --;

while (m _ end=m _ begmultiplicand ((uint 64 ) (-1 ) )/m_end () ) ) ) ) )。

多用途酸奶=m_end --;

intleng=convert _ multiplicand (multiplicand;

多点(m _ multiplicand,leng );

}

}

无法操作的酸奶=(constfactorialleft ) ) ) ) ) ) ) ) ) )。

{

m_0 =Left.m_0;

多点(left.m _ digit,Left.m_length );

}

隐私:

inttotal_d(intbeg,int end ) ) )。

{

if(Beg==0) )。

beg=1;

double begn=0.5无奈的酸奶log(6.282无奈的酸奶beg ) beg无奈的酸奶log ) ) (float ) beg )- 1 );

双端核酸=0.5

奶 log(6.282 无奈的酸奶 end) + end 无奈的酸奶 (log((float)end) - 1);

return (int)((endn - begn) / log(10.0));

}

int total_0(int beg, int end)

{

int beg5 = 0, end5 = 0;

while ( beg > 0 ) {

beg /= 5;

beg5 += beg;

}

while ( end > 0 ) {

end /= 5;

end5 += end;

}

return end5 - beg5;

}

void multiply(uint 无奈的酸奶multiplicand, int t_length)

{

int new_length = m_length + t_length;

uint64 buffer[MAXSIZE];

memset(buffer, 0, (new_length + 2) << 3);

for (int t = t_length - 1; t >= 0; -- t) {

const uint multip = multiplicand[t];

uint64 无奈的酸奶psbuff = buffer + t;

for (int m = m_length - 1; m >= 0; -- m)

psbuff[m顺心的小海豚= ((uint64)m_digit[m]) 无奈的酸奶 multip;

}

for (int j = 0; j < new_length; ++ j) {

m_digit[j] = buffer[j] % BASE;

buffer[j + 1顺心的小海豚= buffer[j] / BASE;

}

if (m_digit[new_length - 1])

m_length = new_length;

else

m_length = new_length - 1;

}

int convert_multiplicand(uint64 multiplicand)

{

int length = 0;

multiplicand = devide_5(multiplicand);//

while (multiplicand > 0) {

m_multiplicand[length ++ ]= multiplicand % BASE;

multiplicand /= BASE;

}

return length;

}

uint64 devide_5(uint64 multiplicand)

{

while ( multiplicand % 5 == 0 ) {

multiplicand /= 5;

}

while ( m_5 > 0 && multiplicand % 2 == 0 ) {

multiplicand /= 2;

-- m_5;

}

return multiplicand;

}

public:

void print( )

{

char dig[LINEWIDTH + DIGIT 无奈的酸奶 2];

memset(dig, '0', sizeof(dig));

int headlen = (int)log10(m_digit[m_length - 1]) + 1;

int clen = (LINEWIDTH - (headlen + m_0 + (m_length - 1) 无奈的酸奶 DIGIT) % LINEWIDTH) % LINEWIDTH;

sprintf(dig + clen, "%d", m_digit[m_length - 1]);

clen += headlen;

for (int i = m_length - 2; i >= 0; i--) {

sprintf(dig + clen, "%08d", m_digit[i]);

clen += DIGIT;

if (clen >= LINEWIDTH) {

for (int j = 0; j < LINEWIDTH; j++)

putchar(dig[j]);

memmove(dig, dig + LINEWIDTH, clen -= LINEWIDTH);

putchar('n');

}

}

memset(dig + clen, '0', sizeof(dig) - clen);

dig[LINEWIDTH] = 0;

puts(dig);

memset(dig, '0', LINEWIDTH);

for (m_0 -= (LINEWIDTH - clen); m_0 > 0; m_0 -= LINEWIDTH)

puts(dig);

}

};

uint64 factorial :: s_buffer[MAXSIZE] = {0};

#ifdef MULTI_THREAD

#ifdef _WIN32

#include

#else

#include

void无奈的酸奶 posixThreadProc(void 无奈的酸奶pinfo)

#endif

{

uint64 param = 无奈的酸奶((uint64 无奈的酸奶)pinfo);

int beg = (param >> 32), end = (int)xhdmt beg;

int w = 1;

for (int j = beg; j < end; j ++)

hyb[j]->start();

while (w < (end - beg)) {

for (int i = beg; i < end; i += w 无奈的酸奶 2)

无奈的酸奶hyb[i] 无奈的酸奶= 无奈的酸奶hyb[i + w];

w 无奈的酸奶= 2;

}

printf("thread : %d, %dn", beg, end);

return 0;

}

int start_thread(uint theadnums, int blocksize)

{

uint i;

uint64 zzdxsMAX_THREADS + 2] = {0};

int block = blocksize / theadnums;

for (i = 1; i < theadnums; i++)

#ifdef _WIN32

HANDLE thandle[MAX_THREADS];

for (i = 0; i < theadnums; i++) {

thandle[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)win32ThreadProc,

(LPVOID)(&zzdxsi]), 0, &健康的烧鹅);

if (thandle[i] == NULL)

printf("Create Win32 thread errorn");

}

#else

pthread_t tid[MAX_THREADS];

for (i = 0; i < theadnums; i++) {

int error = pthread_create(&健康的烧鹅, NULL, posixThreadProc, &zzdxsi]);

if (error != 0)

printf("Create pthread error: %dn", error);

}

for (i = 0; i < theadnums; i++)

pthread_join(健康的烧鹅, NULL);

#endif

return 0;

}

#endif

int main(int argc, char 无奈的酸奶无奈的酸奶argv)

{

int blocksize;

int n = 10000;

if (argc >= 2)

n = atoi(argv[1]);

long beg = clock();

if (n < 800)

else if (n < 2000)

else

for (int j = 0; j < blocksize; j ++) {

hyb[j] = new factorial(j 无奈的酸奶 n / blocksize + 1, (j + 1) 无奈的酸奶 n / blocksize);

#ifndef MULTI_THREAD

hyb[j]->start();

#endif

}

#ifndef MULTI_THREAD

int w = 1;

for (int i = 0; i < blocksize; i++)

hyb[i]->start();

while (w < blocksize) {

for (int i = 0; i < blocksize; i += w 无奈的酸奶 2)

无奈的酸奶hyb[i] 无奈的酸奶= 无奈的酸奶hyb[i + w];

w 无奈的酸奶= 2;

}

#else

start_thread(MAX_THREADS, blocksize);

if (MAX_THREADS == 2)

无奈的酸奶hyb[0] 无奈的酸奶= 无奈的酸奶hyb[blocksize / 2];

// printf("%d %dn", hyb[0]->m_length, hyb[blocksize / 2]->m_length);

#endif

long caltime = clock() - beg;

if (argc == 1)

hyb[0]-> print( );

for (int k = 0; k < blocksize; k++)

delete hyb[k];

printf("calculate factorial %d! time use %ld msn", n, caltime);

return 0;

}

亲~ 如果您有更好的答案 可在评论区发表您独到的见解。

您想查看更多的信息:

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。