2 回答
TA贡献1845条经验 获得超8个赞
移位运算符将左操作数移位右操作数指定的移位计数。如果左操作数是有符号整数,则它们实现算术移位,如果它是无符号整数,则它们实现逻辑移位。班次计数没有上限。移位的行为就像左操作数被移位 n 次,移位计数为 n。因此,x << 1 与 x*2 相同,x >> 1 与 x/2 相同,但向负无穷大截断。
对于较大的值ch
,1<<uint(ch)
将导致溢出:
对于无符号整数值,运算 +、-、* 和 << 是以 2 n为模计算的,其中 n 是无符号整数类型的位宽。粗略地说,这些无符号整数运算在溢出时丢弃高位,并且程序可能依赖于“环绕”。
对于有符号整数,运算 +、-、* 和 << 可能会合法溢出并且结果值存在并且由有符号整数表示、运算及其操作数确定性地定义。不会因溢出而引发异常。在不发生溢出的假设下,编译器可能不会优化代码。例如,它可能不会假设 x < x + 1 总是正确的。
因此<<
,使用按位旋转运算符(您似乎正在描述的内容)实现将违反规范。 1<<uint(ch)
对于ch
大于int
类型大小的值,将评估为零,因此不会导致任何误报。
TA贡献1859条经验 获得超6个赞
完整回答:
规范明确指出,对于无符号操作,我们将高位屏蔽掉,因此低位实际上是“环绕”的。
它起作用的原因是:
Scanner.Whitespace
实际上uint64
是GoWhitespace
完全合身的价值运行时
s.Whitespace&(1<<uint(ch))
对无符号整数的操作可以具有任意大的中间值并且会回绕。因此,如果说 char 是“a”(96),我们有1 << 96
溢出所以 64 位 int 的模大小为 0。
- 2 回答
- 0 关注
- 205 浏览
添加回答
举报