找回密码
 欢迎注册
查看: 16170|回复: 12

[提问] 多算十六万次乘除法,为什么还快了?

[复制链接]
发表于 2010-2-20 16:10:20 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?欢迎注册

×
我才开始学习C语言,觉得它确实比VB快。我今天贴一个程序,请高手看看,请多多提意见。
1)  问题的提出:我在编写代码时,无意中发现,如果多算了八万次除法、八万次求余,程序输出反而快。如果把这十六万次乘除法去掉,直接输出。结果反而慢。
2)  代码如下:
3)说明:程序中的gets()是用来在屏幕上输入大整数的。现在没有用,已将它注释了。为了产生大整数,在程序的开始部分使用了随机数发生器。打双横线的部分就是。这里产生的是四万位的十进制大整数。
  1. #include <stdio.h>
  2. #include <string.h>//*以下程序是我自己编写的验证超大数组的输出,已通过VC++6.0编译。
  3. #include <stdlib.h>
  4. #include <math.h>
  5. #include <time.h>
  6. #include <windows.h>

  7. void main()
  8. {
  9.   long t1,t2;//------------时间变量。
  10.   
  11.    char a[50000],b[50000];
  12.         long c[100002];
  13.         int i,j,k,l,m,s,kd,kf;
  14.         register temp,n;//------寄存器变量,听说可以不这样定义。
  15. unsigned int seed; //-----------初始化随机函数的发生器
  16. //        printf("输入第一个数:");
  17. //                       gets(a);//-----从屏幕输入一个大数。
  18. ///        printf("输入第二个数::");
  19. //                        gets(b);//-----从屏幕输入一个大数。



  20.    
  21.    
  22.    
  23. t1=GetTickCount();//时间计时开始;

  24.   seed=time(0);//=======以下部分用来随机产生两个大数,共产生两个四
  25.     srand(seed);//======万位的大整数。
  26. a[0]=2;
  27.   for(kd = 1; kd <=40000; kd++)
  28.    {
  29.           a[kd]=rand();
  30.          a[kd]=abs(a[kd]);
  31.            a[kd]%=10;
  32. }
  33.    b[0]=6;
  34.     for(kf = 1; kf <=40000; kf++)
  35.    {
  36.         b[kf]=rand();
  37.          b[kf]=abs(b[kf]);
  38.            b[kf]%=10;

  39. }

  40.            i=40001;//strlen(a);//计算输入数组中的数字位数。
  41.    j=40001;//strlen(b);
  42. ////====================以上部分是随机产生两个四万位的大整数。


  43.        //  i=strlen(a);//计算输入数组中的数字位数。
  44.            //  j=strlen(b);
  45.                


  46.              for(s=0;s<=i+j-1;s++)//将数组C初始化,让C中的数置零。
  47.                  {
  48.                          c[s]=0;
  49.                  }
  50.                  


  51. for (k=0;k<=i-1;k++)//*以下就是乘法的核心部分,这是最垃圾最慢的乘法。
  52.         // 这里的目的不是为了检验乘法算法的优劣。就
  53.    //姑且用之吧*/
  54. {
  55.    temp=a[k]-48;
  56.      for (n=0;n<=j-1;n++)
  57.    c[k+n]+=temp*(b[n]-48);//遍乘B中的各数。结果保存在C中。
  58.    }



  59. for(l=i+j-1;l>=1 ;--l)//---------B
  60.   {  //---------------------------------B
  61. c[l-1]+=c[l]/10;  //把C中的十位以上数字取出来,准备向前进位。B
  62. c[l]%=10;       //-------------------------B
  63.    }//--------------------------------------B
  64.   
  65.        
  66.   for (m=0;m<=i+j-2;m++)//这两句是输出语句。把乘积的结果输出。
  67.    printf("%d",c[m]);//输出语句。
  68.                        
  69.         printf("\n");

  70. t2=GetTickCount();//程序段结束后取得系统运行时间(ms)。时间计时结束。

  71.     printf("时间%d",t2-t1);
  72.   
  73. }
复制代码
将程序中注有B的那五行用上,程序输出时间是13秒多(在我的机器上),而将程序中注有B的那五行去掉,程序输出的时间是16秒多。这是为什么?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-2-21 08:27:00 | 显示全部楼层
请问是否是相同的测试环境?比如:
有否运行其它程序?如打开网页、听MP3?
是否有后台程序活跃?如磁盘整理、杀毒扫描等?

计时最好是多运行几次再进行统计,否则容易得出错误结果误导判断。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2010-2-21 09:33:32 | 显示全部楼层
能得到郭老大的回答非常高兴。
回老大:1)没有其它的程序在运行,我连杀毒软件都没有安装。
         2)这两种运行情况分别各运行上百次。不是一次。但多加那几行程序就少要时间。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2010-2-21 09:52:24 | 显示全部楼层
回#gxqcn
我刚才又试了(分别两种情况各10次),将网线也拨了。只有VC++6.0和上面的那个程序在运行。仍然是16秒多和13秒多的时差。我还找了个秒表,秒表测出来的时间也是多算的要快。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-2-21 10:11:32 | 显示全部楼层
debug 模式 还是 release 模式?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-2-21 10:22:54 | 显示全部楼层
cl /O2 m.c
注释//B
cl /O2 m1.c

D:\app>type t1.bat
@echo off
time < cr
m >m.obj
time < cr
m1 >m.obj
time < cr
m1 >m.obj
time < cr
m >m.obj
time < cr


D:\app>t1
当前时间: 10:21:47.74
输入新时间:
当前时间: 10:21:49.81
输入新时间:
当前时间: 10:21:51.87
输入新时间:
当前时间: 10:21:53.95
输入新时间:
当前时间: 10:21:55.99
输入新时间:
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-2-21 10:24:47 | 显示全部楼层
输出的长度不同导致
D:\app>m> m.obj

D:\app>m1> m1.obj

D:\app>dir m*obj
驱动器 D 中的卷没有标签。
卷的序列号是 98F7-F781

D:\app 的目录

2010-02-21  10:23            80,014 m.obj
2010-02-21  10:24           628,341 m1.obj
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2010-2-21 11:11:28 | 显示全部楼层
引用:5#gxqcn  debug 模式 还是 release 模式?
回郭老大:是debug模式。
引用:6#、7#   输出的长度不同导致
                  D:\app>m> m.obj
回这位老大:你写的代码我看不懂,但你给的结论“输出的长度不同导致”让我真的明白了。是真正的理解了。那个乘法执行完以后,数组中全是没有进位的大数,其实际数字个数远远超过十六万个数。而计算机输出多的数字可能就慢了。当把这些进位全部处理完毕。数组中只剩下十六万个数字。所以看上去快了。

再次感谢各位老大在百忙之中关注我的问题。谢谢。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-4-3 19:52:38 | 显示全部楼层
有没有什么能精确测试程序运行时间的程序啊?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2010-4-4 23:08:33 | 显示全部楼层
有没有什么能精确测试程序运行时间的程序啊?
szsdk 发表于 2010-4-3 19:52

可能没有,现在通常的做法只是大概测一下程序的运行时间。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-3-29 17:16 , Processed in 0.047308 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表