Simulate left and right shift operators as in JavaScript


(Vitalii) #1

Hi.
I need the results of the shift in Go as in JavaScript. How can this be done?

In JavaScript now:

console.log(20192019 << 10);   // -798209024
console.log(201920192019 >> 2) // 14182276

In Go now:

fmt.Println(20192019 << 10)    // 20676627456
fmt.Println(201920192019 >> 2) // 50480048004

I need in Go after:

fmt.Println(20192019 << 10)    // -798209024
fmt.Println(201920192019 >> 2) // 14182276

Thank you!


(Norbert Melzer) #2

Well, this is what I see:

./prog.go:8:23: constant 20676627456 overflows int
./prog.go:9:27: constant 50480048004 overflows int

So can you perhaps show code that actually produces the result you are seeing?

PS: Forcing int32 might already be enough, 201920192019 does already overflow then though…


(Vitalii) #3

My output:

20676627456
50480048004

(Norbert Melzer) #4

Yes, you already said that, but can you please share the exact code that produces the output? Taking your snippets from above and throwing them into main on the playground produces the cited compilation errors.

https://play.golang.org/p/240I3ZjBMle


(Vitalii) #5

On the playground, you need to explicitly cast the type to int64:

package main

import (
	"fmt"
)

func main() {
	fmt.Println(int64(20192019) << 10)
	fmt.Println(int64(201920192019) >> 2)
}

(Norbert Melzer) #6

With an int64 you won’t get int32 rollover behaviour, thats exactly what I meant when I said " PS: Forcing int32 might already be enough, 201920192019 does already overflow then though…".


(Vitalii) #7

I understand, but is it possible to simulate a 32-bit number from a 64-bit one? I tried to take away a 32 bit number with distinct coefficients and sometimes it worked, but for a specific value.


(Norbert Melzer) #8

What do you mean by “sometimes”?

If you need 64 bit precission, then stick with it, if you need 32 bits, then don’t use 64.


(Vitalii) #9

It worked for a specific value, and if I changed the value, it no longer worked.
It was something like 1 << 32, (1 << 32) * 5 (these are the coefficients that I mentioned above).


(Sean Killian) #10

@enzovitaliy Does this work for you: https://play.golang.org/p/3caJWUs5IjG


(Luke Hamilton) #11

Now, what I want to know why does wrapping this in a function change the behaviour?


(Sean Killian) #12

It’s because when you use constants and bit shifts on constants, the compiler folds them into constants and knows they’re out of range. By putting the conversion from int64 to int32 into a function, the overflow is deferred until runtime where overflow is unchecked.


(system) closed #13

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.