首页
社区
课程
招聘
弱弱的请教个C语言数学题,热心的朋友请进。
发表于: 2006-4-18 08:13 7478

弱弱的请教个C语言数学题,热心的朋友请进。

2006-4-18 08:13
7478
昨天单位同事在学习QB(用它搞工控开发),在他学习的书上有个习题:
“编写计算N!的程序。要求N!的值可以达到17位以上。(提示,可用数组元素存放N!的每一位数)”
这是原题,结果我想了半天也没想出来怎么做。请教大家,这题在C语言中如何实现。:)
谢谢:)

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (16)
雪    币: 149
活跃值: (344)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
2
要先把描述大数的运算符的工作做好...

你可以去看看密码学里面的代码...他们的第一步都是大数定义和运算符的描述...
2006-4-18 11:50
0
雪    币: 216
活跃值: (77)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
采用大数运行库,如:MIRACL等。
2006-4-18 12:04
0
雪    币: 768
活跃值: (540)
能力值: ( LV13,RANK:460 )
在线值:
发帖
回帖
粉丝
4
谢谢楼上两位。
不会这么麻烦吧?
这道题在这本书的第5章就有(刚讲完数组),是不是有简单的方法?
2006-4-18 13:15
0
雪    币: 768
活跃值: (540)
能力值: ( LV13,RANK:460 )
在线值:
发帖
回帖
粉丝
5
还有:如果一个数非常大,如:0x845285469857412565489652314785654(33位数)
这个数用什么类型的变量能存下??ULONG是存不下了吧?:)
谢谢各位!
2006-4-18 14:09
0
雪    币: 291
活跃值: (213)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
6
只能用字符串存了
2006-4-18 14:22
0
雪    币: 2134
活跃值: (14)
能力值: (RANK:170 )
在线值:
发帖
回帖
粉丝
7
数组模拟乘法萨,
2006-4-18 16:05
0
雪    币: 768
活跃值: (540)
能力值: ( LV13,RANK:460 )
在线值:
发帖
回帖
粉丝
8
?=0x845285469857412565489652314785654 * 0x845285469857412565489652314785654
这题目用C语言怎么样描述呢?
2006-4-18 16:31
0
雪    币: 211
活跃值: (40)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9
我也问这样的问题    上次笔试有这个题  我做错了
也是求N的阶乘要求是15位以上
2006-4-18 17:23
0
雪    币: 179
活跃值: (131)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
10
字符串,然后用小九九模拟人算
2006-4-18 21:22
0
雪    币: 343
活跃值: (611)
能力值: ( LV9,RANK:810 )
在线值:
发帖
回帖
粉丝
11
__int64
2006-4-18 23:26
0
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
12
最初由 FishSeeWater 发布
?=0x845285469857412565489652314785654 * 0x845285469857412565489652314785654
这题目用C语言怎么样描述呢?


大整数乘法,用模拟“乘法阵列器”的方法,一般组成原理书上都有

大致算法如下:
设置大整数类型
const int MAX_LEN = 10000;(可能不够,可以更改)
class big {
  byte digit[MAX_LEN] ;// digit[0]存最低位
  unsigned len ;
  bool sign ;// 正或负
} ;
//现在假设有两个大整数,他们的长度分别为m,n
//假设a,b的运算结果保存到c
class a, b, c ;
a.len = m ; b.len = n ;
c.len = m+n-1 ;
//大整数乘法的算法如下
for ( p = 0; p < c.len; p++ )
{
  for ( i = 0; i <= p; i++ )
    c.digit

+= a.digit[i] * b.digit[p-i] ;
}
// 到这里大整数c就a*b的结果,不过还需要进位处理
int carry = 0, temp = 0 ;
for ( i = 0; i < c.len; i++ )
{
temp = carry + c.digit[i] ;
carry = temp / 10 ;
c.digit[i] = temp % 10;
}

以上算法可以处理大整数乘法,不过对于15位以上的大整数[介乘]没测试过
估计还是有困难的

如果按照老老实实的算法,就算大整数a*b是一次运算,那么也至少需要10^15次操作,一般PC一秒估计为10^10运算,那么就需要10^5 = 100000秒 = 28 小时
晕,这是什么概念。。。

如果可以的话,那么就应该有更加巧妙的算法,期待

2006-4-19 01:18
0
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
13
最初由 17521 发布
我也问这样的问题 上次笔试有这个题 我做错了
也是求N的阶乘要求是15位以上


我理解错你们的意思了
你们的意思应该是N经过介乘后的值为15位以上吧

那么我上面的乘法早就够了
const int MAX_LEN = 10000 ;>> 15
而且长度还可以自己设定
2006-4-19 01:35
0
雪    币: 2384
活跃值: (766)
能力值: (RANK:410 )
在线值:
发帖
回帖
粉丝
14
//我的是这样的。
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

char* _mul(char* szOutBuff,char szStr1[],char szStr2[])
{
        int iLen1,iLen2,i,j;
        WCHAR szTmp1[255]={0},Tmp;
        char szTmp2[255]={0};
        iLen1 = strlen(szStr1);
        iLen2 = strlen(szStr2);
        for (i=0; i<=iLen1-1; i++)
        {
                 for (j=0; j<=iLen2-1; j++)
                 {
                          szTmp1[i+j] += ((szStr1[i]-'0')*(szStr2[j]-'0'));
                 }
        }
       
        for (i=iLen1+iLen2-2; i>=0; i--)
        {
                 Tmp = szTmp1[i] / 10;
                 szTmp1[i] %= 10;
                 if (szTmp1[i] >= 10)
                         szTmp2[i+1] = '0';
                 else
                         szTmp2[i+1] = szTmp1[i] + '0';
                 szTmp1[i-1] += Tmp;
        }
        if (Tmp >= 10 || Tmp == 0)
                strcpy(szTmp2,&szTmp2[1]);
        else
                szTmp2[i+1] = Tmp + '0';
        strcpy(szOutBuff,szTmp2);
        return szOutBuff;
}

int main()
{
        char szStr1[255]={0},szStr2[255]={0},szStr3[255]={0};
        printf("-------------------Code by zhanshen[DFCG][RCT]-------------------\n");
        printf("please Input you Number1:");
        scanf("%s",&szStr2);
        printf("\n");
        printf("please Input you Number2:");
        scanf("%s",&szStr3);
        printf("\n");
        printf("Number1:%s\nNumber2:%s\nNumber1*Number2=%s\n",szStr2,szStr3,_mul(szStr1,szStr2,szStr3));
        system("pause");
        return 0;
}
2006-4-19 01:46
0
雪    币: 768
活跃值: (540)
能力值: ( LV13,RANK:460 )
在线值:
发帖
回帖
粉丝
15
收到回复!:)
谢谢各位朋友,我消化一下:)
2006-4-19 08:52
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
最初由 小虾 发布
//我的是这样的。
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

........


这是原贴地址,大家也看下。。是什么原因。。。
http://bbs.pediy.com/showthread.php?s=&threadid=24268
看到你写的这个大数乘法。。。程序。。有点问题。。。

下面是调整结果的那一段。。。。。。
for (i=iLen1+iLen2-2; i>=0; i--)
   {
      Tmp = szTmp1[i] / 10;
   /*
    * 问题就在这儿。。。szTmp[i]%=10 执行完后,永远小于10
    *szTmp[i] >=10 不可能成立了呀。。。
    *
   */
      szTmp1[i] %= 10;
      if (szTmp1[i] >= 10)/*请问题这个还能执行到吗???*/
        szTmp2[i+1] = '0';
      else
        szTmp2[i+1] = szTmp1[i] + '0';
      szTmp1[i-1] += Tmp;
   }
请 小虾 或明白的人指点。。。。。。偶只是想弄清楚。。。。。
2006-5-3 21:07
0
雪    币: 221
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
17
?嘱完?酵??是用高精度算法吧
2006-5-6 15:56
0
游客
登录 | 注册 方可回帖
返回
//