Go程序中按位移位计算结果不一致问题咨询
Go程序中按位移位计算结果不一致问题咨询
嘿,我来帮你拆解这个问题的核心原因,其实是Go对常量表达式和变量表达式的求值规则差异导致的,具体细节如下:
先看x2的正确结果(10)
const N uint = 10是编译期常量,所以(1 << N)/100属于常量表达式,Go编译器会在编译阶段直接用任意精度整数计算:
1 << 10直接得到1024(不受目标平台整数类型位数限制)1024 / 100做整数除法得到10- 最后把
10赋值给byte类型的x2,因为10在byte(0-255)的范围内,所以结果就是10。
再看x1的异常结果(0)
var n uint = 10是运行期变量,(1 << n)/100属于变量表达式,会在程序运行时计算,这里的关键是类型推导和位移规则:
- 无类型常量
1会被默认转换为int类型(Go中无类型整数常量的默认类型是int) - 位移操作的右操作数
n(uint类型)会被转换为int类型,值为10 - 如果你的运行环境中
int是8位(比如某些嵌入式系统),位移位数10超出了int的位数范围(要求0≤n<8),此时Go的行为是未定义的,大多数编译器会对位移位数取模,也就是10 mod 8 = 2,所以1 << 2 = 4 4 / 100的整数除法结果是0,赋值给byte类型的x1,自然就是0了。
如果你的运行环境是普通PC(int为32/64位),理论上1 << 10 = 1024,1024/100=10,x1应该也是10,但出现0的结果大概率是因为你在8位int的嵌入式环境中运行,或者编译器对超出范围的位移做了取模处理。
备注:内容来源于stack exchange,提问作者Bahamas
相关产品推荐
相关产品推荐

