论坛风格切换切换到宽版
  • 5729阅读
  • 10回复

无法理解的计算结果 [复制链接]

上一主题 下一主题
离线ba2ba
 
发帖
961
只看楼主 倒序阅读 0楼 发表于: 2013-03-03
我用C语言编了一小段计算程序,发现有个奇怪的现象,百思不得其解:
程序中其他计算都有正确的结果,唯有一个出现问题,而计算公式都是一样的  A=B*C  ,计算后,用取余/位值 的方式取出千 百 十 个位等值。
例如通过I/O口(比如P0)来查看计算结果,P0=A%10000/1000  。
其中B=79(十进制)C=16384  及B=81 C=16384 时 或 B=80 C=16383  或B=80 C=16385 计算结果都正确,而B=80 C=16384时,计算后的各位值都是 0  。
说明:A值宏定义数据类型是unsigned long   应没有问题。
请大家给看看究竟是什么原因。

地址:黑龙江省伊春市伊美区美溪镇新兴小区12号楼一单元201室
姓名:陈铁石/BA2BA
邮编:153021
电话:18804585572
QQ:464826156
离线BI3MEK
发帖
25
只看该作者 1楼 发表于: 2013-03-03
贴上代码来看看,B和C如何定义的?int?
呼号:BI3MEK,河北任丘
离线BI3MEK
发帖
25
只看该作者 2楼 发表于: 2013-03-03
B=80 C=16385 时,
A=B*C=80*16385=1310800
此时A%10000=800
800/1000=0
结果为0 ,P0  LED全部亮,是正确的。

B=79 C=16384 时,
A=B*C=79*16384=1294336
此时A%10000=4336
4336/1000=4
结果为4 ,P0端口P2_2LED熄灭是正确的。

B=81 C=16384 时,
A=B*C=79*16384=1327104
此时A%10000=7104
7104/1000=7
结果为7 ,P0端口P2_0,P2_1,P2_2LED熄灭,其他LED亮,是正确的。

如果你的P0口LED为共阳,就应该是上面的结果,你看看你的实验板是不是这样显示?
呼号:BI3MEK,河北任丘
离线ba2ba
发帖
961
只看该作者 3楼 发表于: 2013-03-03
回 BI3MEK 的帖子
GPS_2.rar (10 K) 下载次数:3
BI3MEK:B=80 C=16385 时,
A=B*C=80*16385=1310800
此时A%10000=800
800/1000=0
结果为0 ,P0  LED全部亮,是正确的。
....... (2013-03-03 17:37)

谢谢你的指导,请你在试试计算80*16384=1310720并取出各位值,我取得各位都是 0 。
A%10000000/1000000:
A%1000000/100000;
A%100000/10000;
A%10000/1000;                  
A%1000/100;
A%100/10;
A%10;


[ 此帖被ba2ba在2013-03-03 18:45重新编辑 ]
地址:黑龙江省伊春市伊美区美溪镇新兴小区12号楼一单元201室
姓名:陈铁石/BA2BA
邮编:153021
电话:18804585572
QQ:464826156
离线BI3MEK
发帖
25
只看该作者 4楼 发表于: 2013-03-03
做个数制强制转换吧
呼号:BI3MEK,河北任丘
离线BI3MEK
发帖
25
只看该作者 5楼 发表于: 2013-03-03
//GPS模块计算
#include<reg51.h>
#define uchar unsigned char     //宏定义uchar为无符号字符型数据类型,计数范围0~255
#define uint unsigned int       //宏定义uint为无符号整型数据类型,计数范围0~65535
#define ulong unsigned long     //宏定义ulong为无符号长整型数据类型,计数范围0~429496725
uchar GPS[23]={0xE0,0x07,0x08,0x0D,0x50,0x17,0x3A,0x24,0x78,0x2F,0x4B,0x00,0x00,0x11,0x5A,0x00,0x00,0x01,0x0B,0x4B,0x05,0xA8,0xEA};
sbit LED=P2^7;
sbit YSQ=P3^7;
void main(void)
{
uint gps5;
ulong gps3,gps4,gpsW1;
LED=0;
YSQ=1;
gps5=GPS[5]*128;
gps4=gps4=(unsigned long)GPS[4]*16384;GPS[4]*16384;   //此处做数据强制转换
P0=gps4%10000000/1000000;
P0=gps4%1000000/100000;
P0=gps4%100000/10000;
P0=gps4%10000/1000;          
P0=gps4%1000/100;
P0=gps4%100/10;
P0=gps4%10;                     //以上计算得值错误
gps3=GPS[3]*2097152;
P0=gps3%100000000/10000000;    
P0=gps3%10000000/1000000;
P0=gps3%1000000/100000;
P0=gps3%100000/10000;
P0=gps3%10000/1000;          
P0=gps3%1000/100;
P0=gps3%100/10;
P0=gps3%10;                     //以上计算得值正确
gpsW1=gps3+gps4+gps5+GPS[6];
P0=gpsW1%100000000/10000000;    //取千万位值,得2
P0=gpsW1%10000000/1000000;      //8      
P0=gpsW1%1000000/100000;        //5
P0=gpsW1%100000/10000;          //7
P0=gpsW1%10000/1000;             //6
P0=gpsW1%1000/100;               //6
P0=gpsW1%100/10;                 //9
P0=gpsW1%10;                    //8
}

[ 此帖被BI3MEK在2013-03-03 19:39重新编辑 ]
呼号:BI3MEK,河北任丘
离线ba2ba
发帖
961
只看该作者 6楼 发表于: 2013-03-03
回 BI3MEK 的帖子
BI3MEK://GPS模块计算
#include<reg51.h>
#define uchar unsigned char     //宏定义uchar为无符号字符型数据类型,计数范围0~255
#define uint unsigned int       //宏定义uint为无符号整型 .. (2013-03-03 19:37)

再次感谢你的回复。我将你加的语句"gps4=gps4=(unsigned long)GPS[4]*16384;GPS[4]*16384;   //此处做数据强制转换 "
修改了一下,去掉了多出来的一个"gps4="和后面的"GPS[4]*16384;"  
经编译,通过,计算结果正确。
我不明白的是,程序的前面我已经宏定义了数据类型,为什么这里还有强制进行数据类型转换,而只要不是GPS[4]=0x50(十进制为80)或乘数不是16384,结果都正确,麻烦你给解释下为盼!
[ 此帖被ba2ba在2013-03-04 07:20重新编辑 ]
地址:黑龙江省伊春市伊美区美溪镇新兴小区12号楼一单元201室
姓名:陈铁石/BA2BA
邮编:153021
电话:18804585572
QQ:464826156
离线okstar
发帖
4734
只看该作者 7楼 发表于: 2013-03-04
请贴代码,特别是A的定义

内容来自Android手机客户端

离线BG4FQD
发帖
3406
只看该作者 8楼 发表于: 2013-03-04
回 ba2ba 的帖子
ba2ba:再次感谢你的回复。我将你加的语句"gps4=gps4=(unsigned long)GPS[4]*16384;GPS[4]*16384;   //此处做数据强制转换 "
修改了一下,去掉了多出来的一个"gps4="和后面的"GPS[4]*16384;"&nbs .. (2013-03-03 21:35) 

我猜测和编译器的关系很大,为了避免编译器歧义通常情况下这个显式的类型转换是需要写上的。

至于你说为什么只有16384不对,可以对照一下编译出来的汇编代码看看区别在哪儿,另外关闭关编译器的"优化"再比较一下。
别人吃饭我看着,别人睡觉我站着。
离线ba2ba
发帖
961
只看该作者 9楼 发表于: 2013-03-04
回 okstar 的帖子
okstar:请贴代码,特别是A的定义 (2013-03-04 08:13) 

代码在3楼,文件名:GPS_2.rar。即5楼中除去添加的强制数据类型转换语句。
地址:黑龙江省伊春市伊美区美溪镇新兴小区12号楼一单元201室
姓名:陈铁石/BA2BA
邮编:153021
电话:18804585572
QQ:464826156
离线ba2ba
发帖
961
只看该作者 10楼 发表于: 2013-03-04
回 BG4FQD 的帖子
BG4FQD:我猜测和编译器的关系很大,为了避免编译器歧义通常情况下这个显式的类型转换是需要写上的。
至于你说为什么只有16384不对,可以对照一下编译出来的汇编代码看看区别在哪儿,另外关闭关 .. (2013-03-04 10:22) 

我用的是Keil uVision2软件,没有对软件进行设置,都是默认设置。
地址:黑龙江省伊春市伊美区美溪镇新兴小区12号楼一单元201室
姓名:陈铁石/BA2BA
邮编:153021
电话:18804585572
QQ:464826156