c# byte类型数据移位 溢出 50

例如定义:byteiTmp=0x0A;iTmp<<=5;//这样写可以!运算正确!//iTmp=iTmp<<5;//这样写不可以!为什么?//iTmp=Convert.T... 例如定义:
byte iTmp = 0x0A;
iTmp <<= 5; // 这样写可以!运算正确!
// iTmp = iTmp << 5; // 这样写不可以!为什么?
// iTmp = Convert.ToByte(iTmp << 5);// 这样写可以!运行报溢出!为什么?
展开
 我来答
freeeeeewind
2015-05-29 · TA获得超过1万个赞
知道大有可为答主
回答量:3227
采纳率:94%
帮助的人:1361万
展开全部

1)iTmp <<= 5 

这个语句是正确的。因为执行这个语句仅需要运算一次,也就是说,对byte类型的iTemp变量直接执行一次左移5位的运算。运算过程中,变量类型明确为byte类型。

参考MSDN:https://msdn.microsoft.com/zh-cn/library/ayt2kcfb.aspx

2)iTmp = iTmp << 5

从语法上,这句话与1)具有相当的含义;但是运算处理上有微妙的差异:首先,iTmp << 5 得出的中间结果,这个中间结果的类型为int或uint;然后,再将中间结果赋值给iTmp。错误出现在第二步上:无法将int或uint类型的中间结果赋值给byte类型的iTmp。要防止错误,必须使用强制转换:

iTmp = (byte)(iTmp << 5 );

3)iTmp = Convert.ToByte(iTmp << 5) 发生错误的根本原因与2)相同,也就是计算iTmp << 5的中间结果的类型为int或uint。要防止错误,也必须使用强制转换:

iTmp = Convert.ToByte((byte)(iTmp << 5 ));

这样写也能得到正确结果,但是很啰嗦、很别扭!

4)总之,关键点在于:一定要注意运算中间结果的类型!!!

lrh3321
2015-05-28 · TA获得超过2183个赞
知道大有可为答主
回答量:2296
采纳率:75%
帮助的人:2127万
展开全部

0x0A <<5  = 0x140 超出byte的最大值0xFF了

iTmp << 5; 的值类型是int无法隐式转换为byte类型


使用unchecked 来防止溢出报错

             unchecked{
                iTmp =(byte)(iTmp <<5);
                
            }
追问
在C语言里以下两个表达式不是等效的吗?
iTmp <<= 5;
iTmp = iTmp << 5;

还有iTmp是byte类型的只有8位,如果向左移位时超出部分应该被丢弃,不应该存在0x0A <<5 = 0x140这种说法吧?
追答
自己去MSDN上看吧。C#和C里是不一样的。他把iTmp 隐式转换为int类型再进行位移操作的,位移本身不会溢出。但你把一个大于byte.Max的数转换为byte类型时会报溢出。

左移运算符 (<<) 将第一个操作数向左移动第二个操作数指定的位数。 第二个操作数的类型必须是一个 int 或具有向 int 的预定义隐式数值转换的类型。
备注

如果第一个操作数是 int 或 uint(32 位数),则移位数由第二个操作数的低 5 位给出。 也就是实际的 shift 计数为 0 到 31 位。
如果第一个操作数是 long 或 ulong(64 位数),则移位数由第二个操作数的低 6 位给出。 也就是实际的 shift 计数为 0 到 63 位。
不在移位后第一个操作数类型范围内的任意高序位均不会使用,低序空位用零填充。 移位操作从不导致溢出。
https://msdn.microsoft.com/zh-cn/vbrun/a1sway8w.aspx
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式