C语言编程题,求5!+16!+27!,定义函数求n! 用程序流程图表示出算法,代码...
发布网友
发布时间:2024-10-09 12:17
我来回答
共3个回答
热心网友
时间:2024-10-09 13:01
如果需要精确计算16和27的阶乘需要编写大整数计算,至少要实现大整数加法,大整数乘以短整数,大整数除以短整数,大整数转换为字符串用于显示结果。当然如果不需要精确计算可以使用浮点数来计算。
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <ctype.h>
typedef int BOOL;
typedef unsigned short LINT_B;
typedef unsigned long LINT_B2;
typedef LINT_B * LINT;
typedef const LINT_B * CLINT;
#define TRUE 1
#define FALSE 0
#define BASE 0x10000ul
#define BASEDIV2 0x8000ul
#define BASEMINONE 0xFFFFul
#define DIGITLEN 64 // 当 DIGITLEN = 64 时可以实现200以内的阶乘
#define Max(a, b) ((a) < (b) ? (b) : (a))
#define Rmldzrs(l, h) do {while(*(--h) == 0); ++h; h = Max(l, h);} while(0);
const int sBitperdgt = sizeof(LINT_B) * 8;
// 复制大数
LINT copy(CLINT f, CLINT l, LINT x)
{
while(f != l) *x++ = *f++;
return x;
}
// 大数是否为0
inline BOOL isZero(CLINT l, CLINT h)
{
Rmldzrs(l, h);
return (l == h) ? TRUE : FALSE;
}
// 调换字符串的顺序
void reverse(char *s)
{
char t;
char *sl = s;
char *sh = sl + strlen(s);
while(sl < sh) {t = *sl; *sl++ = *(--sh) ; *sh = t;}
}
// 交换大数指针
void swapCLINT(CLINT *a, CLINT *b)
{
CLINT t;
t = *a; *a = *b; *b = t;
}
// 加法 C = A + B
LINT add(CLINT al, CLINT ah, CLINT bl, CLINT bh, LINT cl)
{
LINT_B2 carry = (LINT_B2)0;
LINT ch = cl;
if((ah - al) < (bh - bl)) swapCLINT(&al, &bl), swapCLINT(&ah, &bh); // 保证A的长度大于或等于B
// 两个数相加
while (bl < bh)
*ch++ = (LINT_B)(carry = (LINT_B2)*al++ + (LINT_B2)*bl++ + (LINT_B2)(LINT_B)(carry >> sBitperdgt));
// 处理 A 比 B 多出的长度
while (al < ah)
{
if(carry >= BASE) *ch++ = (LINT_B)(carry = (LINT_B2)*al++ + (LINT_B2)(LINT_B)(carry >> sBitperdgt));
else *ch++ = *al++;
}
// 处理进位
if(carry & BASE) *ch++ = (LINT_B)1;
return ch;
}
// 短乘法 C = A * b
LINT umul(CLINT al, CLINT ah, LINT_B b, LINT cl)
{
LINT ch;
LINT_B2 *pc;
CLINT pa;
LINT_B2 carry, bv;
if(b == 0 || isZero(al, ah)) {if(cl) *cl = 0; return cl;}
if(ah - al == 1) // A 的长度只有一个数字
{
pc = (LINT_B2 *)cl;
*pc = (LINT_B2)*al * (LINT_B2)b;
ch = cl + 2;
Rmldzrs(cl, ch);
return ch;
}
ch = cl;
pa = al;
carry = (LINT_B2)0, bv = (LINT_B2)b;
// 循环计算
while(pa < ah) *ch++ = (LINT_B)(carry = bv * (LINT_B2)*pa++ + (LINT_B2)(LINT_B)(carry >> sBitperdgt));
// 处理进位
*ch++ = (LINT_B)(carry >> sBitperdgt);
Rmldzrs(cl, ch);
return ch;
}
// 短除 A = b * C + d
// cl 或 d 可以是空指针
LINT udiv(CLINT al, CLINT ah, LINT_B b, LINT cl, LINT d)
{
int lenA, lenC;
LINT bufC = NULL, ch, pch;
LINT_B c;
CLINT pah;
LINT_B2 rdach, bv, rv;
// 处理特殊情况
if(b == 0)
{
printf("带余短除出现除以0错误");
if(d) *d = 0;
if(cl) *cl = 0;
return cl;
}
lenA = ah - al;
if(lenA == 0) {if(d) *d = 0; if(cl) *cl = 0; return cl;} // 被除数等于0,结果商等于0,余数等于0
if(lenA == 1) // 被除数也只有1位
{
if(*al < b) {if(d) *d = *al; if(cl) *cl = 0;} // 被除数小于除数,商等于0,余数等于被除数
else
{
c = *al / b;
if(cl) *cl++ = c;
if(d) *d = *al - c * b;
}
return cl;
}
lenC = lenA - 1; // 计算长度
if(cl == NULL)
{
bufC = (LINT)malloc((lenC + 1) * sizeof(LINT_B)); // 申请内存,保证cl不为NULL
if(bufC == NULL)
{
printf("带余短除申请临时内存发生错误!\n");
if(d) *d = 0;
return NULL;
}
cl = bufC;
}
ch = cl + lenC;
// 开始计算
pah = ah - 1;
pch = ch;
bv = b, rv = 0;
while(al <= pah)
{
*pch = (LINT_B)((rdach = ((rv << sBitperdgt) + (LINT_B2)*pah--)) / bv);
rv = (rdach - bv * (LINT_B2)*pch--);
}
if(d) *d = (LINT_B)rv;
if(bufC)
{
free(bufC);
return NULL;
}
return (*ch == 0) ? ch : ++ch;
}
// 大整数变成数字串
const char * LInt2Str(char * o, CLINT l, CLINT h, LINT_B base, BOOL uppercase)
{
const char * sVecUpper = "0123456789ABCDEF";
const char * sVecLower = "0123456789abcdef", *Vec;
char *po;
LINT_B x, t[DIGITLEN], ii[DIGITLEN];
LINT th, tl, il, ih;
CLINT xl, xh;
BOOL flag = TRUE;
po = o;
il = ii;
ih = copy(l, h, il);
Rmldzrs(il, ih);
if(isZero(il, ih))
{
*o++ = '0';
*o++ = 0;
return po;
}
Vec = uppercase ? sVecUpper : sVecLower;
xl = &x;
xh = xl + 1;
th = tl = t;
switch(base)
{
case 2: case 8: case 10: case 16: break;
default: base = 10;
}
while(1)
{
if(flag)
{
th = udiv(il, ih, base, tl, &x);
flag = FALSE;
}
else
{
ih = udiv(tl, th, base, il, &x);
flag = TRUE;
}
*o++ = Vec[x];
if(th == tl || ih == il) break;
}
*o++ = 0;
reverse(po);
return po;
}
// 阶乘,可以精确计算200以内的阶乘,定义更大的DIGITLEN可以实现更大数字的阶乘
LINT jiecheng(LINT l, LINT_B x)
{
LINT h = l + 1, tl, th;
LINT_B i = 1, t[DIGITLEN];
BOOL flag = TRUE;
*l = 1;
th = tl = t;
while(i <= x)
{
if(flag) {flag = FALSE; th = umul( l, h, i++, tl);}
else {flag = TRUE; h = umul(tl, th, i++, l);}
}
if(!flag) h = copy(tl, th, l);
return h;
}
int main()
{
char buf[512];
LINT_B a[DIGITLEN], b[DIGITLEN], c[DIGITLEN], i = 5;
LINT al, ah, bl, bh, cl, ch;
ah = al = a, bh = bl = b, ch = cl = c;
while(i < 30)
{
printf("%d! ", i);
ch = add(al, ah, bl, jiecheng(bl, i), cl);
ah = copy(cl, ch, al);
i += 11;
if(i < 30) printf("+ ");
}
printf("= %s\n", LInt2Str(buf, al, ah, 10, FALSE));
return 0;
}
热心网友
时间:2024-10-09 13:06
#include<stdio.h>
double fac(int n) //计算n的阶乘
{double x=1.0;
int i;
for(i=2;i<=n;i++)
x*=i;
return x;
}
int main()
{printf("%.0lf\n",fac(5)+fac(16)+fac(27));
return 0;
}
热心网友
时间:2024-10-09 13:07
void main(void)
{
uint sum;
sum = f_JieCheng(n);
}
uint f_JieCheng(uint n)
{
uint temp = 1;
for(i=1;i<(n+1);i++)
{
temp *= i;
}
return temp;
}