英文:
why `1<<32 - 1` is 4294967295 in go?
问题
我在Go语言中发现了一个奇怪的结果,你能帮我看看吗?
fmt.Print(1<<32 - 1)
结果是4294967295。但是在C语言中:
printf("%lld", 0x1ll<<32 - 1);
结果是2147483648。
英文:
I found a weird result in Go, could you help me?
fmt.Print( 1<<32 - 1)
it's 4294967295
But in C
printf("%lld",0x1ll<<32 - 1);
it's 2147483648
答案1
得分: 17
在Go语言中,1<<32-1
被解析为(1 << 32) - 1
(通过gofmt插入的空格有助于提示)。而在C语言中,它被解析为1 << (32 - 1)
。这是因为在C语言中,移位操作的优先级低于加法和减法,而在Go语言中则相反。
你可以从输出中看到这一点,在Go语言中结果是奇数,为4294967295
,即2^32 - 1。而在C语言中结果是2147483648
,即2^31。
Go语言的运算符优先级(来自https://golang.org/ref/spec#Operators):
优先级 运算符
5 * / % << >> & &^
4 + - | ^
3 == != < <= > >=
2 &&
1 ||
C语言的运算符优先级:https://en.cppreference.com/w/c/language/operator_precedence
英文:
In go, 1<<32-1
parses as (1 << 32) - 1
(which gofmt helpfully hints at with the spaces it inserts). In C, it parses as 1 << (32 - 1)
. This is because in C, shifts have lower precedence than + and -, and in go, it's the other way round.
You can see this in the output, in go it's odd, and is 4294967295
which is 2^32 - 1. In C it's 2147483648
which is 2^31.
Go operator precendence (from https://golang.org/ref/spec#Operators)
Precedence Operator
5 * / % << >> & &^
4 + - | ^
3 == != < <= > >=
2 &&
1 ||
In C: https://en.cppreference.com/w/c/language/operator_precedence
答案2
得分: 4
C和Go之间的关键区别在于运算符优先级。
在C中,-
的优先级比<<
高,所以1 << 32 - 1
等于1 << (32 - 1)
,即1 << 31
。
而在Go中,情况正好相反,所以1 << 32 - 1
等于(1 << 32) - 1
。
这更加令人困惑的是,当你搜索"go operator precedence"时,第一个谷歌搜索结果并不是我提供的规范链接,而是tutorialspoint.com上的教程(我不会提供链接),它完全错误地解释了这一点 - 实际上,它似乎直接从其C教程中抄袭了C运算符优先级部分,包括包含许多在Go中甚至不存在的运算符的优先级表。
[1] https://en.cppreference.com/w/c/language/operator_precedence
[2] https://golang.org/ref/spec#Operator_precedence
英文:
The key difference between C and Go here is operator precedence.
In C, -
has higher precedence[1] than <<
, so 1 << 32 - 1
is 1 << (32 - 1)
i.e. 1 << 31
.
In Go, it's the other way round[2], so 1 << 32 - 1
is (1 << 32) - 1
.
This is made more confusing because the first Google result when you search for "go operator precedence" is not the spec I linked, but the tutorial at tutorialspoint.com (which I won't link), which gets this completely wrong - in fact, it appears to have copied the C operator precedence section verbatim from its C tutorial, including the precedence table, which contains lots of operators that do not even exist in Go.
[1] https://en.cppreference.com/w/c/language/operator_precedence
[2] https://golang.org/ref/spec#Operator_precedence
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论