为什么在Go语言中,`1<<32 - 1`的结果是4294967295?

huangapple go评论129阅读模式
英文:

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&lt;&lt;32 - 1)

it&#39;s 4294967295

But in C

 printf(&quot;%lld&quot;,0x1ll&lt;&lt;32 - 1);
it&#39;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&lt;&lt;32-1 parses as (1 &lt;&lt; 32) - 1 (which gofmt helpfully hints at with the spaces it inserts). In C, it parses as 1 &lt;&lt; (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             *  /  %  &lt;&lt;  &gt;&gt;  &amp;  &amp;^
    4             +  -  |  ^
    3             ==  !=  &lt;  &lt;=  &gt;  &gt;=
    2             &amp;&amp;
    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 &lt;&lt;, so 1 &lt;&lt; 32 - 1 is 1 &lt;&lt; (32 - 1) i.e. 1 &lt;&lt; 31.

In Go, it's the other way round[2], so 1 &lt;&lt; 32 - 1 is (1 &lt;&lt; 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

huangapple
  • 本文由 发表于 2021年8月5日 15:16:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/68662158.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定