为什么 byte cast 炸毁不一致的 golang?
Why does byte cast blow up inconsistently golang?
我有以下例子,摘自 Addison-Wesley Golang 书,我稍作修改:
package main
import "fmt"
// pc[i] is the population count of i.
var pc [256]byte
func init() {
for i := range pc {
pc[i] = pc[i/2] + byte(i&1)
}
}
// PopCount returns the population count (number of set bits) of x.
func PopCount(x uint64) int {
fmt.Printf("Value is %d\n", x)
fmt.Printf("byte(%d>>(0*8)) is %d\n", x, byte(x>>(0*8)))
y := byte(x>>(0*8))
return int(pc[y] +
pc[byte(x>>(1*8))] +
pc[byte(x>>(2*8))] +
pc[byte(x>>(3*8))] +
pc[byte(x>>(4*8))] +
pc[byte(x>>(5*8))] +
pc[byte(x>>(6*8))] +
pc[byte(x>>(7*8))])
}
func main() {
// fmt.Println(byte(256>>(0*8))) // This blows up, but doesn't blow up on line 19 or line 20, why?
fmt.Println(PopCount(256))
}
这是 playground 中的相同代码:example-code
以防万一 link 过期,这里是 playground,您可以在其中粘贴以上内容并开始游戏:go playground
如果您取消注释
// fmt.Println(byte(256>>(0*8)))
你得到一个错误:
prog.go:31: constant 256 overflows byte
鉴于这是在 PopCount 内部完成的而没有爆炸,我不明白发生了什么。有人可以帮助解释为什么当我在 main 中执行它而不是在函数 PopCount 中时它会爆炸吗?
我敢说我漏掉了一些明显的东西!
是因为256>>(0*8)
(等同于256
),是一个无类型常量,太大了,不适合byte
中的规则language spec状态
A constant value x can be converted to type T in any of these cases:
- x is representable by a value of type T.
- x is a floating-point
constant, T is a floating-point type, and x is representable by a
value of type T after rounding using IEEE 754 round-to-even rules, but
with an IEEE -0.0 further rounded to an unsigned 0.0. The constant
T(x) is the rounded value.
- x is an integer constant and T is a string
type. The same rule as for non-constant x applies in this case.
在您的 PopCount
函数中,256
值的类型为 uint64
,可以将其转换为 byte
,将其截断为 0
.
我有以下例子,摘自 Addison-Wesley Golang 书,我稍作修改:
package main
import "fmt"
// pc[i] is the population count of i.
var pc [256]byte
func init() {
for i := range pc {
pc[i] = pc[i/2] + byte(i&1)
}
}
// PopCount returns the population count (number of set bits) of x.
func PopCount(x uint64) int {
fmt.Printf("Value is %d\n", x)
fmt.Printf("byte(%d>>(0*8)) is %d\n", x, byte(x>>(0*8)))
y := byte(x>>(0*8))
return int(pc[y] +
pc[byte(x>>(1*8))] +
pc[byte(x>>(2*8))] +
pc[byte(x>>(3*8))] +
pc[byte(x>>(4*8))] +
pc[byte(x>>(5*8))] +
pc[byte(x>>(6*8))] +
pc[byte(x>>(7*8))])
}
func main() {
// fmt.Println(byte(256>>(0*8))) // This blows up, but doesn't blow up on line 19 or line 20, why?
fmt.Println(PopCount(256))
}
这是 playground 中的相同代码:example-code 以防万一 link 过期,这里是 playground,您可以在其中粘贴以上内容并开始游戏:go playground
如果您取消注释
// fmt.Println(byte(256>>(0*8)))
你得到一个错误:
prog.go:31: constant 256 overflows byte
鉴于这是在 PopCount 内部完成的而没有爆炸,我不明白发生了什么。有人可以帮助解释为什么当我在 main 中执行它而不是在函数 PopCount 中时它会爆炸吗?
我敢说我漏掉了一些明显的东西!
是因为256>>(0*8)
(等同于256
),是一个无类型常量,太大了,不适合byte
中的规则language spec状态
A constant value x can be converted to type T in any of these cases:
- x is representable by a value of type T.
- x is a floating-point constant, T is a floating-point type, and x is representable by a value of type T after rounding using IEEE 754 round-to-even rules, but with an IEEE -0.0 further rounded to an unsigned 0.0. The constant T(x) is the rounded value.
- x is an integer constant and T is a string type. The same rule as for non-constant x applies in this case.
在您的 PopCount
函数中,256
值的类型为 uint64
,可以将其转换为 byte
,将其截断为 0
.