如果 "x=(date<<7)>>12" 和 y=date<<7;z=y>>12; 为啥 x 和 z 的评估不同?
Posted
技术标签:
【中文标题】如果 "x=(date<<7)>>12" 和 y=date<<7;z=y>>12; 为啥 x 和 z 的评估不同?【英文标题】:Why are x and z evaluating differently if "x=(date<<7)>>12" and y=date<<7;z=y>>12;?如果 "x=(date<<7)>>12" 和 y=date<<7;z=y>>12; 为什么 x 和 z 的评估不同? 【发布时间】:2013-05-10 14:45:08 【问题描述】:这真的令人沮丧。(date<<7)>>12
与y>>12
给出不同结果的可能原因是什么,y
是date<<7
?我应该补充一点,后者按我的意图正常工作,但是第一个不是。有什么区别?我看不出。
#include<stdio.h>
int main()
unsigned short date=5225,x,y,z;
x=(date<<7)>>12;
printf("Month is %hu\n",x);
y=date<<7;
z=y>>12;
printf("Month is %hu\n",z);
输出
Month is 163
Month is 3
【问题讨论】:
@Robᵩ 我已将 y 声明为unsigned short
,然后将其初始化为date<<7
。它怎么还没定义?
你可以这样尝试:((unsigned short)(date<<7))>>12
@A4L 它有效。我希望您添加一行关于它为什么有效。我也问过肯尼,只是为了确定。
好吧,我会直观地说,如果只有 date
被转换为 unsigned short
- 由于日期已经是那种类型,所以女巫实际上已经过时了 - 然后结果再次被转换为 int
女巫有与完全不强制转换的效果相同,这就是 Kenny 关于整数提升的解释。因此,您实际上需要的是转换最终结果,即(date<<7)
,使其再次变为unsigned short
,然后对其应用>>12
。
@A4L 为什么x = (unsigned short)(date << 7) >> 12
能解决问题呢?
【参考方案1】:
在 C 中,所有整数计算都至少提升到 int
1。所以
x = (date << 7) >> 12
= (5225 << 7 /* result as int */) >> 12
= 668800 >> 12
= 163
计算完成后,我们将结果截断回unsigned short
,得到163。
在第二种情况下,y
强制将结果截断为unsigned short
,所以
y = (unsigned short) (date << 7)
= (unsigned short) 668800
= 13440
z = y >> 12
= 3
1:C11 §6.5.7/3:“对每个操作数执行整数提升。结果的类型是提升的左操作数的类型。”; §6.3.1.1/2:“如果int
可以表示原始类型的所有值(受宽度限制,对于位域),则该值将转换为int
;否则,将其转换到unsigned int
。这些称为整数促销。”
【讨论】:
@Rüppell'sVulture:是的。括号不会改变促销规则。x = (unsigned short)(date << 7) >> 12
解决了这个问题。我直观地知道为什么,但我希望你通过评论简单地解释一下,以确保。
为什么x = (unsigned short)(date << 7) >> 12
解决了这个问题?**A4L** 说这个转换没有效果。
@Rüppell'sVulture:A4L 说强制转换没有效果,因为答案只是强制转换 date
变量,这不会改变任何事情。您正在投射(date << 7)
的结果。以上是关于如果 "x=(date<<7)>>12" 和 y=date<<7;z=y>>12; 为啥 x 和 z 的评估不同?的主要内容,如果未能解决你的问题,请参考以下文章