Invalid operation: float64 type shift

I ran into a strange problem using the shift operator << in the 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 use the parameters to use it, and then return the result back to uint .

Finally, this value will be used as the float64 parameter, so after that I will return it back to float64 .

The problem is that casting the return value does not 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 am getting is:

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

However, it seems that only casting works:

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

Is this a Golang problem? Behavior that I did not find in the specs? Normal behavior I just do not understand?

Here is the playground: http://play.golang.org/p/36a8r8CCYL

+6
source share
2 answers

From spec :

The correct operand in the shift expression must be an unsigned integer type or be an untyped constant that can be converted to an unsigned integer type. If the left operand of a variable shift expression is an untyped constant, the type of constant is what it would be if the shift expression were replaced only with its left operand.

So, float64(1 << uint(math.Abs(10))) basically coincides with float64(1) << uint(math.Abs(10)) , which leads to an error, since it does not just shift the float.

+9
source

You cannot use math.Abs . In Go, solve the problem with a little simple function. For instance,

 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 
0
source

Source: https://habr.com/ru/post/972578/


All Articles