TI中文支持网
TI专业的中文技术问题搜集分享网站

1<<16 的结果是多少?不仿真,谁知道?仿真了,又有谁知道?

最近被坑惨了,根源于 1  << 15 ,1 << 16 的值是多少的问题。

之前写了一款产品,有个句子

int a,b;

a |= 1 << b;

当时 b 的值从 0 到 15,一切都很正常。

后来产品扩展,就改成

Uint32 a

int b

a |= 1 << b

 b 的值从 0 到 31。

单台产品运行时,看起来很正常,扩展出来的 a 的高16位能正常得到1,这也是我关注的地方,而低16位目测也正常。

但是将新代码和旧代码放到一起比较,就发现两台产品的运行有差异。尽快很快就定位到这个 1 << b ,因为我知道 1 默认是 int 类型,左移超过15位肯定有异常,但是,我的直觉告诉我,超过15位应该是0,在expression窗口输入 1 << 16 , 1 << 17 ,显示结果也都是 0,所以从理论上,a  的低16位不应该出现异常,应该是搞16位永远得不到 1,而事实上不是这样。

最后发现,当 b 等于 15 时,a 的高16位全是 1 !

当然这也可以理解,1 << 15 = -32768 , 高位对齐的话,a 高位用1填充,我认了。

然后,当 b 等于 16 时,a 的最低位居然又等于 1 !!!

b等于17时,a的第二位等于1!!!!!

问题就是这样,a 在一个周期内,低16位被重复赋值两次,比以前多了一次,所以程序的时间改变了,这种改变肉眼很难立即觉察,只有两台产品放在一起才能注意到。

关于这个问题,相信大侠们有很多真知灼见,欢迎讨论!以上的描述一些细节可能有出入,这两天忙着填坑,填完了才来这里,一些仿真细节可能记错了。

rookiecalf:

是因为隐含类型引起的BUG,1是int型,移位是按16取余的,所以需要对被移数据先确定需要的数据类型(必要时强制类型转换),然后再移位,才不会出现这样的bug

最近被坑惨了,根源于 1  << 15 ,1 << 16 的值是多少的问题。

之前写了一款产品,有个句子

int a,b;

a |= 1 << b;

当时 b 的值从 0 到 15,一切都很正常。

后来产品扩展,就改成

Uint32 a

int b

a |= 1 << b

 b 的值从 0 到 31。

单台产品运行时,看起来很正常,扩展出来的 a 的高16位能正常得到1,这也是我关注的地方,而低16位目测也正常。

但是将新代码和旧代码放到一起比较,就发现两台产品的运行有差异。尽快很快就定位到这个 1 << b ,因为我知道 1 默认是 int 类型,左移超过15位肯定有异常,但是,我的直觉告诉我,超过15位应该是0,在expression窗口输入 1 << 16 , 1 << 17 ,显示结果也都是 0,所以从理论上,a  的低16位不应该出现异常,应该是搞16位永远得不到 1,而事实上不是这样。

最后发现,当 b 等于 15 时,a 的高16位全是 1 !

当然这也可以理解,1 << 15 = -32768 , 高位对齐的话,a 高位用1填充,我认了。

然后,当 b 等于 16 时,a 的最低位居然又等于 1 !!!

b等于17时,a的第二位等于1!!!!!

问题就是这样,a 在一个周期内,低16位被重复赋值两次,比以前多了一次,所以程序的时间改变了,这种改变肉眼很难立即觉察,只有两台产品放在一起才能注意到。

关于这个问题,相信大侠们有很多真知灼见,欢迎讨论!以上的描述一些细节可能有出入,这两天忙着填坑,填完了才来这里,一些仿真细节可能记错了。

HH Y:

回复 rookiecalf:

我感兴趣的是,这是 TI 编译器的特性,还是C语言的标准?仿真时expressiong窗口输入 1<<16 显示是 0,算不算一个 bug 呢?

最近被坑惨了,根源于 1  << 15 ,1 << 16 的值是多少的问题。

之前写了一款产品,有个句子

int a,b;

a |= 1 << b;

当时 b 的值从 0 到 15,一切都很正常。

后来产品扩展,就改成

Uint32 a

int b

a |= 1 << b

 b 的值从 0 到 31。

单台产品运行时,看起来很正常,扩展出来的 a 的高16位能正常得到1,这也是我关注的地方,而低16位目测也正常。

但是将新代码和旧代码放到一起比较,就发现两台产品的运行有差异。尽快很快就定位到这个 1 << b ,因为我知道 1 默认是 int 类型,左移超过15位肯定有异常,但是,我的直觉告诉我,超过15位应该是0,在expression窗口输入 1 << 16 , 1 << 17 ,显示结果也都是 0,所以从理论上,a  的低16位不应该出现异常,应该是搞16位永远得不到 1,而事实上不是这样。

最后发现,当 b 等于 15 时,a 的高16位全是 1 !

当然这也可以理解,1 << 15 = -32768 , 高位对齐的话,a 高位用1填充,我认了。

然后,当 b 等于 16 时,a 的最低位居然又等于 1 !!!

b等于17时,a的第二位等于1!!!!!

问题就是这样,a 在一个周期内,低16位被重复赋值两次,比以前多了一次,所以程序的时间改变了,这种改变肉眼很难立即觉察,只有两台产品放在一起才能注意到。

关于这个问题,相信大侠们有很多真知灼见,欢迎讨论!以上的描述一些细节可能有出入,这两天忙着填坑,填完了才来这里,一些仿真细节可能记错了。

rookiecalf:

回复 HH Y:

这是属于编译器的特性,编译后代码的执行结果和expression中的不同可以算是两种编译器的差异(expression中的这种直接数据表示是不经过TI编译器的),所以作为开发人员需要尽量避免这样的陷阱

赞(0)
未经允许不得转载:TI中文支持网 » 1<<16 的结果是多少?不仿真,谁知道?仿真了,又有谁知道?
分享到: 更多 (0)