操作无效:float64类型的移位

时间:2014-07-21 12:40:43

标签: go bit-shift

我在Golang中使用移位运算符<<遇到了一个奇怪的问题。在我的最终代码中,移位值将是两个整数的绝对值。但是,Go包只为Abs值定义float64函数,因此我需要转换参数以使用它,然后将结果转换回uint

最后,此值将用作float64参数,因此我将其转换回float64

问题是返回值的转换似乎不像我预期的那样工作......

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)))

我收到的错误是:

invalid operation: 1 << uint(math.Abs(10)) (shift of type float64)

然而,似乎只有施法操作才有效:

var test = uint(math.Abs(10))
fmt.Println(reflect.Kind(test))
// uint32

这是一个Golang问题吗?我没有在规格中找到的行为?我根本不理解的正常行为?

这是一个游乐场:http://play.golang.org/p/36a8r8CCYL

2 个答案:

答案 0 :(得分:10)

来自spec

  

shift表达式中的右操作数必须具有无符号整数类型,或者是可以转换为无符号整数类型的无类型常量。 如果非常量移位表达式的左操作数是无类型常量,则常量的类型是单独使用左操作数替换移位表达式时的类型。

所以float64(1 << uint(math.Abs(10)))float64(1) << uint(math.Abs(10))基本相同,这会产生错误,因为不会简单地移动浮点数。

答案 1 :(得分:0)

你不应该使用math.Abs。在To中,用一个小而简单的功能解决问题。例如,

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