英文:
Invalid operation: shift of type float64
问题
我在使用Golang中的位移运算符<<
时遇到了一个奇怪的问题。在我的最终代码中,位移值将是两个整数的绝对值。然而,Go语言包只为float64
类型定义了Abs
函数,所以我需要将参数转换为float64
类型来使用它,然后再将结果转换回uint
类型。
最后,这个值将被用作float64
类型的参数,所以我在此之后将其转换回float64
类型。
问题是返回值的转换似乎不像我预期的那样工作...
var test float64
// 以下所有行都按预期工作
test = float64(1 << 10)
test = float64(1 << uint(10))
test = float64(1 << uint(float64(11-1)))
test = float64(1 << uint(-float64(1-11)))
// 但是这一行不工作:编译时出错
test = float64(1 << uint(math.Abs(10)))
我收到的错误是:
invalid operation: 1 << uint(math.Abs(10)) (shift of type float64)
然而,似乎单独的转换操作是有效的:
var test = uint(math.Abs(10))
fmt.Println(reflect.Kind(test))
// uint32
这是一个示例:http://play.golang.org/p/36a8r8CCYL
英文:
I'm facing a strange issue using the shift operator <<
in Golang. In my final code, the shift value will be the absolute value of two integers. However, the Go package only defines the Abs
function for float64
values, so I will need to cast the parameters to use it, and then cast the result back to uint
.
Finally, this value will be used as a float64
parameter, so I cast it back to float64
after that.
The problem is that the return value's cast does not seem to work as I expected...
var test float64
// all the following lines are working as expected
test = float64(1 << 10)
test = float64(1 << uint(10))
test = float64(1 << uint(float64(11-1)))
test = float64(1 << uint(-float64(1-11)))
// but this one does not: error at compilation
test = float64(1 << uint(math.Abs(10)))
The error I'm receiving is:
invalid operation: 1 << uint(math.Abs(10)) (shift of type float64)
However, it seems that the cast operation alone works:
var test = uint(math.Abs(10))
fmt.Println(reflect.Kind(test))
// uint32
Is it a Golang issue ? A behaviour I did not find in the specifications ? A normal behaviour I simply don't understand ?
Here is a playground: http://play.golang.org/p/36a8r8CCYL
答案1
得分: 13
根据规范:
移位表达式中的右操作数必须具有无符号整数类型,或者是可以转换为无符号整数类型的无类型常量。如果非常量移位表达式的左操作数是无类型常量,则该常量的类型将与仅使用左操作数的移位表达式的类型相同。
因此,float64(1 << uint(math.Abs(10)))
基本上与float64(1) << uint(math.Abs(10))
是相同的,但会产生错误,因为不能简单地将浮点数进行移位操作。
英文:
From the spec:
>The right operand in a shift expression must have unsigned integer type or be an untyped constant that can be converted to unsigned integer type. If the left operand of a non-constant shift expression is an untyped constant, the type of the constant is what it would be if the shift expression were replaced by its left operand alone.
So float64(1 << uint(math.Abs(10)))
is basically the same as float64(1) << uint(math.Abs(10))
, which produces an error, since one does not simply shift a float.
答案2
得分: 0
你不应该使用math.Abs
。在Go语言中,可以使用一个简单的小函数来解决这个问题。例如,
package main
import "fmt"
func shift(a, b int) uint {
s := a - b
if s < 0 {
s = -s
}
return uint(s)
}
func main() {
a, b := 24, 42
i := 1 << shift(a, b)
fmt.Printf("%X\n", i)
f := float64(i)
fmt.Println(f, i)
}
输出结果:
40000
262144 262144
英文:
You shouldn't be using math.Abs
. In Go, solve the problem with a small, simple function. For example,
package main
import "fmt"
func shift(a, b int) uint {
s := a - b
if s < 0 {
s = -s
}
return uint(s)
}
func main() {
a, b := 24, 42
i := 1 << shift(a, b)
fmt.Printf("%X\n", i)
f := float64(i)
fmt.Println(f, i)
}
Output:
40000
262144 262144
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论