搜索
bottom↓
回复: 11

XC16理解的对? 还是我理解的对?

[复制链接]

出0入0汤圆

发表于 2017-1-10 16:31:09 | 显示全部楼层 |阅读模式
最近发现一个很有趣的事情

程序如下:
{
unsigned long I;
unsigned char J = 1000;


.
.
.
I += J*100;

}

结果呢,J*100是超出了16位的数字,但是呢,I中超出16位的进位没了!

我的理解是 这条公式里面的类型转换,也就是J*100,应该是unsigned long类型的,二不应该是unsigned int类型的。

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入57汤圆

发表于 2017-1-10 16:49:21 | 显示全部楼层
J*100是8位。

出0入0汤圆

 楼主| 发表于 2017-1-10 16:52:24 | 显示全部楼层

这是第三种理解,J*100的结果是八位吗?

出20入70汤圆

发表于 2017-1-10 16:55:54 | 显示全部楼层
觉得不对,加个强制转换不就得了!
I += (unsigned long)J*100;

出10入23汤圆

发表于 2017-1-10 16:57:57 来自手机 | 显示全部楼层
J=1000?uchar哦

出0入0汤圆

发表于 2017-1-10 17:29:23 | 显示全部楼层
unsigned char J = 1000; 这里1000就被截了

I += J*100; 这里会先转换成unsigned char,这一步就会发生截位,然后在转换成unsigned long。
反过来写 I+= 100*J 应该就不会。

出0入0汤圆

发表于 2017-1-10 18:00:31 | 显示全部楼层
J = 1000会被截断成J = 232,因为只能保留最低8位。

计算表达式J*100时存在整型提升,将J扩充到8*sizeof(unsigned int)位,然后再计算与100的乘积,结果为23200,因为没有超过unsigned int的取值范围,所以没有发生截断损失。

在计算+=时,先将上述的临时结果23200扩充到8*sizeof(I)位,然后计算加法。

综上,XC16没有错。

出0入475汤圆

发表于 2017-1-11 08:37:40 来自手机 | 显示全部楼层
如果这么容易就找到bug了人家编译器公司还想不想混了,:)

出0入0汤圆

 楼主| 发表于 2017-1-11 08:44:42 | 显示全部楼层
OK, 表达式错误, 改成

unsigned char J=100;

I += J*1000;

那么有
(1) I +=  J*1000;
等效于
(2) I = I + J*1000;

在(2)里面,J*1000应该是 unsigned long格式。

那么,在式(1)里面, J*1000就不是 unsigned long了?

标注一下, PIC24里面,long是32位, int 是16位。

出0入0汤圆

 楼主| 发表于 2017-1-11 08:45:41 | 显示全部楼层
eduhf_123 发表于 2017-1-10 18:00
J = 1000会被截断成J = 232,因为只能保留最低8位。

计算表达式J*100时存在整型提升,将J扩充到8*sizeof(u ...

如果提升的话,J*100也只应该提升为int, 而不是unsigned int.

出0入0汤圆

发表于 2017-1-11 10:18:49 | 显示全部楼层
J*100
应该写成 J*100UL,这样运算会按照unsigned long进行升位

出0入0汤圆

 楼主| 发表于 2017-1-11 10:31:02 | 显示全部楼层
转一篇数据转换原则吧。

赋值运算:自动把“=”右边的表达式的类型转换成“=”右边的变量的类型,例如 int a=4.5; a的值实际是4!
混合运算:就是一个运算表达式当中包含了多个类型,这时候就需要有类型转换。当运算符两边的操作数类型不同时,其中一个操作数就要经过类型转换以和另一个操作数的类型相一致,然后才能进行运算。
变换操作数采取就高不就低的原则,即级别低的操作数先被转换成和级别高的操作数具有同一类型,然后再进行运算,结果的数据类型和级别高的操作数相同。
       高        double    ←←    float
       ↑          ↑             
       ↑         long     
       ↑          ↑
       ↑        unsigned
       ↑          ↑
       低         int      ←←    char,short
             自动转换顺序表

顺带说一句:如果等式两端都不超过int, 那么右端运算时都自动提升为int. 如果超过int, 则提升为表达式中最高级别那个变量的级别。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-25 14:39

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表