两个int 型数相乘,如果积超出int型最大表示数,结果怎么取的?

wmajia 2012-04-08 12:02:06
sizeof(int)=4,
在两个GCC和IAR for Arm下面计算出来的结果不同。
GCC是正确的,IAR计算结果不对,请教怎么将下面几行语句移植到IAR下面来
(代码实际就是触摸屏tslib校准算法中一段代码),我把它简化如下:

int a[7];
int aa,bb,cc,dd;

a[0]=111793920;
a[1]=-153434;
a[2]=-57;
a[6]=65536;

aa=412*a[0];
bb=272*a[1];
cc=aa+bb+a[2];
dd=cc/a[6];
GCC编译计算的结果是正确的,输出值aa,bb,cc,dd为:
-63214808 -15504 48563608 741

aa ,bb ,cc 是怎么算出来的,有点不清楚,望高手指点。



在另外一个编译器(IAR for Arm V6.21)同样是上面的值,aa bb cc dd 为:
-1185545216 -32528008 -1218073281 -18586
这个是错误的计算结果

现在要把GCC上面这段代码移到IAR上面去,要求计算结果一样,怎么弄?
这段代码的目的是避免符点运算,将数都放大了65536倍 ,最终再除以65536.
如果不转成浮点,有办法不?

多谢!!


...全文
1077 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
wmajia 2012-04-09
  • 打赏
  • 举报
回复

有没有人能帮忙解释一下, aa bb cc dd 是怎么计算得到的???




int a[7];
int aa,bb,cc,dd;

a[0]=111793920;
a[1]=-153434;
a[2]=-57;
a[6]=65536;

aa=412*a[0];
bb=272*a[1];
cc=aa+bb+a[2];
dd=cc/a[6];
GCC编译计算的结果是正确的,输出值aa,bb,cc,dd为:
-63214808 -15504 48563608 741

rockhard 2012-04-09
  • 打赏
  • 举报
回复
下面数组下标不是一一对应,所以提供的范例值不对!

lin->a[0] = cal.a[1];
lin->a[1] = cal.a[2];
lin->a[2] = cal.a[0];
lin->a[3] = cal.a[4];
lin->a[4] = cal.a[5];
lin->a[5] = cal.a[3];
lin->a[6] = cal.a[6];

wmajia 2012-04-09
  • 打赏
  • 举报
回复
编译器不支持long long
wmajia 2012-04-09
  • 打赏
  • 举报
回复
编译器不支持long long
wmajia 2012-04-08
  • 打赏
  • 举报
回复
我帖出原始函数,也没多少内容,以及printf打印出来的内容。

static int linear_read(struct tslib_module_info *info, struct ts_sample *samp, int nr)
{
struct tslib_linear *lin = (struct tslib_linear *)info;
int ret;
int xtemp,ytemp;
int aa,bb,cc,dd;
printf("linear_read\n");

lin->a[0] = cal.a[1];
lin->a[1] = cal.a[2];
lin->a[2] = cal.a[0];
lin->a[3] = cal.a[4];
lin->a[4] = cal.a[5];
lin->a[5] = cal.a[3];
lin->a[6] = cal.a[6];

printf("a: %d %d %d %d %d %d %d\r\n",
cal.a[0],cal.a[1],cal.a[2],cal.a[3],cal.a[4],cal.a[5],cal.a[6]);

ret = info->next->ops->read(info->next, samp, nr);
printf("wsamp x,y:%d %d ret=%d\r\n", (int)(samp->x), (int)(samp->y), ret);
if (ret >= 0) {
int nr;

for (nr = 0; nr < ret; nr++, samp++) {
xtemp = samp->x; ytemp = samp->y;
samp->x = ( lin->a[2] +
lin->a[0]*xtemp +
lin->a[1]*ytemp ) / lin->a[6];
aa=lin->a[0]*xtemp;
bb=lin->a[1]*ytemp;
cc=aa+bb+lin->a[2];
dd=cc/lin->a[6];
printf("test: %d %d %d %d\r\n", aa,bb,cc,dd);

samp->y = ( lin->a[5] +
lin->a[3]*xtemp +
lin->a[4]*ytemp ) / lin->a[6];

aa=lin->a[3]*xtemp;
bb=lin->a[4]*ytemp;
cc=aa+bb+lin->a[5];
dd=cc/lin->a[6];
printf("test2: %d %d %d %d\r\n", aa,bb,cc,dd);


samp->pressure = ((samp->pressure + lin->p_offset)
* lin->p_mult) / lin->p_div;
if (lin->swap_xy) {
int tmp = samp->x;
samp->x = samp->y;
samp->y = tmp;
}
}
}
samp-=ret;
printf("wsamp2 x,y:%d %d ret=%d\r\n", (int)(samp->x), (int)(samp->y), ret);
return ret;
}



打印输出的两组数据如下,麻烦高手帮忙分析一下,特别是cc得出来的值很奇怪:

ts_read
linear_read
a: 111793920 -153434 -57 -87360320 -1686 352553 65536
ts_read_raw
getxy
wsamp x,y:412 272 ret=1
test: -63214808 -15504 48563608 741
test2: -694632 95894416 7839464 119


ts_read
linear_read
a: 111793920 -153434 -57 -87360320 -1686 352553 65536
ts_read_raw
getxy
wsamp x,y:364 282 ret=1
test: -55849976 -16074 55927870 853
test2: -613704 99419946 11445922 174
wmajia 2012-04-08
  • 打赏
  • 举报
回复
多谢楼上几位,这么晚还没睡,

GCC编译计算的结果是正确的,输出值aa,bb,cc,dd为:
-63214808 -15504 48563608 741


这5个数,是我用printf输入的结果。因为没办法单步,

IAR下面,是单步跟踪计算得出来的值。



现在肯定的是,GCC那个编译器编译出来的,计算结果可用,因为屏坐标点击正确。
在IAR上面不一致,肯定就不对了。



现在最关键的,是能计算出想要的结果。
evencoming 2012-04-08
  • 打赏
  • 举报
回复
我用gcc计算出来的结果
-1185545216,-41734048,-1227279321,-18726
西山小月 2012-04-08
  • 打赏
  • 举报
回复
自己定义一种类型,比如六个字节,或者8个字节。
evencoming 2012-04-08
  • 打赏
  • 举报
回复
换成long long 或者long long类似物(64位整型)就可以.
wmajia 2012-04-08
  • 打赏
  • 举报
回复
tslib代码本身就是避免了每个坐标点都要浮点运算的,因此移植时,请大家先不要改成浮点运算。
pathuang68 2012-04-08
  • 打赏
  • 举报
回复
两种办法:
1. 用long long
2. 如果用long long不行的话,就自己定义一个结构,用来表示一个大的整数,比如:
typedef struct _big_int
{
int high_part;
int low_part;
}big_int;
wmajia 2012-04-08
  • 打赏
  • 举报
回复
睡前再顶一次,望高手指点迷津!

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧