求助!请大神指导~~~~

2019-07-15 15:56发布

* 利用单片机计算出1!+2!+3!+……+9!的结果。
程序:
#include <reg51.h>
#define INT8U        unsigned char
#define INT16U        unsigned int

code INT8U SEG_CODE[] = {0x3f,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//段码
code INT8U SEG_WEI[] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位码

void delay_ms(INT16U x)
{
        INT8U t; while(x--) for(t = 0; t < 120; t++);
}//延时子程序

sbit d=P1^0;//位定义(控制段码信号的"门")
sbit w=P1^1; //位定义(控制位码信号的"门")

/*unsigned int*/long sum()
{
unsigned int i , j=1 ;
long s=0 ;
for(i=1;i<=9;i++)
{
  j*=i;
  s+=j;
}
  return s ;
}//求和子函数

void main()
{
unsigned int he;
he=sum();//在主函数中调用求和子函数
        while(1)
        {
                P0=0xff;
                w=1;
                P0=SEG_WEI[7];
                w=0;
                d=1;
                P0=SEG_CODE[he%10];
                d=0;
                delay_ms(5);//显示完个位

                P0=0xff;
                w=1;
                P0=SEG_WEI[6];
                w=0;
                d=1;
                P0=SEG_CODE[(he/10)%10];
                d=0;
                delay_ms(5);//显示完十位

                P0=0xff;
                w=1;
                P0=SEG_WEI[5];
                w=0;
                d=1;
                P0=SEG_CODE[(he/100)%10];
                d=0;
                delay_ms(5);//显示完百位

                P0=0xff;
                w=1;
                P0=SEG_WEI[4];
                w=0;
                d=1;
                P0=SEG_CODE[(he/1000)%10];
                d=0;
                delay_ms(5);//显示完千位

                P0=0xff;
                w=1;
                P0=SEG_WEI[3];
                w=0;
                d=1;
                P0=SEG_CODE[(he/10000)%10];
                d=0;
                delay_ms(5);//显示完万位
               
                P0=0xff;
                w=1;
                P0=SEG_WEI[2];
                w=0;
                d=1;
                P0=SEG_CODE[(he/100000)%10];
                d=0;
                delay_ms(5);//显示完十万位

                P0=0xff;
                w=1;
                P0=SEG_WEI[1];
                w=0;
                d=1;
                P0=SEG_CODE[(he/1000000)%10];
                d=0;
                delay_ms(5);//显示完百万位

                P0=0xff;
                w=1;
                P0=SEG_WEI[0];
                w=0;
                d=1;
                P0=SEG_CODE[he/10000000];
                d=0;
                delay_ms(5);//显示完千万位


                }
}


但是在proteus仿真却出现这样的结果:

QQ图片20151015203714.png    

有两个问题:
1.为什么我在调试1!+2!+...+8!时结果都是正确的,而多一个9!时却发生这样的结果?
2.百万位和十万位一直都是8,怎样修改主函数才能得到没有问题的程序?
因为积分只有一分,所以希望大神不要见怪~~~~
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
3条回答
1522495332
1楼-- · 2019-07-15 21:50
keil C51中unsigned int类型是16位,最大值为65535。unsigned long为32位。long型变量与int型变量相乘是被当成int × int还是long×long,这个需要实际测试一下,这会影响计算结果。局部变量he是unsigned int型,1! + ... + 8! = 46233,< 65535可以准确表示。但+9!之后,结果是409113 > 65535,则高16位丢失,则he=15897,这与你显示的后5位一致。至于前面两个8,可能是除法运算错误导致的,这个我没验证过。
想要正确的结果,最简单的办法是把所有的变量,包括局部变量和全局变量,全部改为unsigned long类型。 最佳答案
changhaozhe
2楼-- · 2019-07-16 00:15
将变量he改为long型试试
sunge
3楼-- · 2019-07-16 05:07
好像大部分的8位和16位单片机的编译器整型都是16位的。我也经常不小心弄错数据类型,特别是运算之后。如果有在线调试的功能,设置断点或单步运行,查看变量的值,一般来说会很快定位问题。

一周热门 更多>