用c语言表达:求两个日期之间有多少天?输入1900 1 1到3000 12 31时误差很大,而其它测试数据都通过

下面是我的源程序:
#include <stdio.h>
int main(){
int swap(int date1[],int date2[]);
long years(int year1,int year2);
int leap_year(int year);
int days(int month,int day);
int judge(int date[]);
int date1[4],date2[4],i,m;
long Days,Days1,Days2,Days3;
char ch;
int months[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
do{
printf("\n\n\n");
printf("\t\tinput the first date:");
printf("\n");
do{
printf("\t\t\tinput the year:");
scanf("%d",&date1[1]);
if(leap_year(date1[1]))months[2]=29;
else months[2]=28;
}while(date1[1]<1900||date1[1]>3000);
do{
printf("\t\t\tinput the month:");
scanf("%d",&date1[2]);
m=date1[2];
}while(date1[2]<1||date1[2]>12);
do{
printf("\t\t\tinput the day:");
scanf("%d",&date1[3]);
}while(date1[3]<1||date1[3]>months[m]);
printf("\n\n\t\tinput the second date:");
printf("\n");
do{
printf("\t\t\tinput the year:");
scanf("%d",&date2[1]);
if(leap_year(date2[1]))months[2]=29;
else months[2]=28;
}while(date2[1]<1900||date2[1]>3000);
do{
printf("\t\t\tinput the month:");
scanf("%d",&date2[2]);
}while(date2[2]<1||date2[2]>12);
do{
printf("\t\t\tinput the day:");
scanf("%d",&date2[3]);
m=date1[2];
}while(date2[3]<1||date2[3]>months[m]);
for(i=1;i<4;i++){
if(date1[i]>date2[i]){
swap(date1,date2);
break;
}
else if(date1[i]==date2[i]) continue;
else break;
}
Days1=years(date1[1],date2[1]);
Days2=days(date2[2],date2[3]);
Days3=days(date1[2],date1[3]);
Days=Days1+Days2-Days3;
//Days=years(date1[1],date2[1]);
printf("\t\tThere are %ld days",Days1);
printf("\t\tThere are %ld days",Days2);
printf("\t\tThere are %ld days",Days3);
printf("\n\t\tThere are %ld days",Days);

ch=getch();
}while(ch==' ');
return 0;
}

int swap(int date1[],int date2[]){
int i,temp;
for(i=1;i<4;i++){
temp=date1[i];
date1[i]=date2[i];
date2[i]=temp;
}
return 0;
}

int leap_year(int year){
if((year%4==0&&year%4!=0)||year%400==0)return 1;
else return 0;
}

long years(int year1,int year2){
int d=0;
long td=0;
if(year1==year2)return 0;
for(;year1<year2;year1++){
if(leap_year(year1))d=366;
else d=365;
td+=d;
}
td=td+1;
return td;
}

int days(int month,int day){
int months[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int i;
//day=day-1;
for(i=1;i<month;i++)
day+=months[i];
//total=sm+day;
return day;
}
我不明白的是输入1900 1 1到3000 12 31时误差很大,而输入其它数据时都通过
会有加分的,你们回答得越精彩,加分会越多!

第1个回答  2011-12-28
可以这样做:编写一个求从1.1.1到y.m.d的总天数的函数(比如 int days(int,int,int)),然后调用这个函数即可。前看下面程序:
#include <stdio.h>

int days(int y,int m,int d); /* 求1.1.1~y.m.d的天数 */
inline int isleap(int y); /* 判断y年是否闰年 */

void main(){
int y=2011,m=12,d=28;
int ds=days(y+1,1,1)-days(y,m,d);
printf("%d\n",ds);
}

/* 参数:y,m,d=年,月,日 */
int days(int y,int m,int d){
int ds[12]={0,31,59,90,120,151,181,212,243,273,304,334}; /* ds[i]=平年i+1月1日前的天数,i=0,1,... */
int t; /* 总天数 */
t=365*(y-1)+(y-1)/4-(y-1)/100+(y-1)/400; /* 到y-1年底的总天数 */
t+=ds[m-1]; /* 到y-1年m-1月底的总天数 */
t+=((m<=2) ? 0 : isleap(y) ? 1 : 0); /* m>2时,闰年加1天 */
t+=d; /* 到y-1年m-1月d日的总天数 */
return t; /* 总天数 */
}

/* 判断y年是否闰年,是则返回非0,否则返回0 */
int isleap(int y){
return (y%4==0 && y%100!=0 || y%400==0);
}追问

你有看我的程序吗?我程序的设计就是这样子的。就是有误差而已,我找不出这误差

第2个回答  2011-12-28
没什么问题啊
输入1900 1 1到3000 12 31时,输出:
There are 401868 days

1900 1 1到3000 12 31有1101年,大概1101*365=401865天

是一致的啊

运行环境: VC++ 6.0追问

呵呵,答案是402000多,就差了200多天,我不知道怎么回事,这是我们的实习作业来着,大家的结果都是402000多。还有,实际上,我有几个测试数据都跟正确的结果差了1天,我想,误差应该出在这里吧

追答

差了200多天的话,1101年,大概有200多个闰年,这么看来,最大的可能性是你的程序里闰年的处理应该有问题,导致每一个闰年的计算都差一天,1000多年累积差了200多天

追问

我前面有说过,我有几个数据都跟正确的答案有1天的误差,误差会不会出在这里呀?
long years(int year1,int year2){
int d=0;
long td=0;
if(year1==year2)return 0;
for(;year1<year2;year1++){
if(leap_year(year1))d=366;
else d=365;
td+=d;
}
td=td+1;
return td;
}
我一直都怀疑这个函数,但一直找不出这个函数是怎么产生误差的。帮我看下,谢谢!

第3个回答  2011-12-29
根据楼上的回答,如果是用VC++编译的话应该没问题,其他的有些编译器比如Turbo C是将int型视为2个字节的,那样数据超出30000就溢出了。如果是这样的话,就将天数的类型由int改为long,long是4个字节的,能表示到40亿,足够用了。追问

c语言里面没有long long这样声名的,而且,我测试过了,没有溢出哦

第4个回答  2011-12-29
你判断闰年的函数错了, 是year%100!=0 而不是year%4!=0:

int leap_year(int year){
if((year%4==0&&year%100!=0)||year%400==0)return 1; //这儿改了。。。
else return 0;
}本回答被提问者采纳
第5个回答  2011-12-29
do{
printf("\t\t\tinput the month:");
scanf("%d",&date1[2]);
m=date1[2];
}while(date1[2]<1||date1[2]>12);//这个地方是要一直输入吗?
}追问

不是一直输入的,只是要求输入月份,我用循环是为了控制输入数据的正确性

追答

用不着吧。。。

追问

这是老师要求的,如果老师没有要求控制输入数据的正确性的话,我4~5行就解决输入问题了

相似回答