简体   繁体   中英

Invalid operation: shift of type float64

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

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM