论坛风格切换切换到宽版
  • 3914阅读
  • 6回复

keil C高手请进,请教一道数学题 [复制链接]

上一主题 下一主题
离线BG4ABM
 
发帖
1139
只看楼主 倒序阅读 0楼 发表于: 2007-06-14
#include<reg51.h>
unsigned int m;

void main(void)
{
while(1)
{
  m=255*251/128;
}
}

正确答案应该是500,可编译后单步运行并观察m,无论如何出不了这个数字,如果把乘法和除法分开来写成2行,就可以出来500了,请问这是为什么?
离线bellstudio
发帖
2820
只看该作者 1楼 发表于: 2007-06-14
#include<reg51.h>
unsigned int m;

void main(void)
{
while(1)
{
m=(unsigned int)255*251/128;
m++;
}
}

前面运算溢出了
如果分开,系统作了隐式转换,这是基本的c问题,与keil无关
离线BG4ABM
发帖
1139
只看该作者 2楼 发表于: 2007-06-14
应该还是和keil有关的吧,我在别人的c编译器上试过,直接写成m=255*251/128就可以出来正确答案了.
离线bellstudio
发帖
2820
只看该作者 3楼 发表于: 2007-06-16
hehe
32位编译器的int是32位的
离线bd1es
发帖
2096
只看该作者 4楼 发表于: 2007-06-19
有意思,好像真是keil的bug,别的编译器没事。
离线bd1es
发帖
2096
只看该作者 5楼 发表于: 2007-06-27
今天无事,我用avr gcc又作了一遍,发现问题是一样的。

原因是:这样的计算在编译时完成,对目标程序来说只是load一个立即数。那么如果编译器错误认为运算是有符号的,就会产生溢出,除非强制通知编译器启用16位无符号运算。

我还是觉得这问题算编译器问题,保证最终结果正确本是编译器的职责,否则会害惨程序员的。以后干脆在常数运算式里写下一个“.”,都启用浮点运算挺好,

两种源码编译结果见下图,注意看编译器的警告信息:
离线firetiger
只看该作者 6楼 发表于: 2007-07-09
bellstudio 兄说的对!