how to do unsigned right shift in Go?

1,678 views
Skip to first unread message

Ganesh

unread,
Dec 24, 2009, 5:44:51 AM12/24/09
to golang-nuts
As I understand, the >> for negative values is signed right shift. How
to do unsigned right shift (as in >>> in Java, for example)?

If I explicitly cast the left operand (a negative value) to uint32,
for example, I get a compiler error that it overflows. The same
problem if I try to cast the result to uint.

-ganesh

peterGo

unread,
Dec 24, 2009, 9:31:06 PM12/24/09
to golang-nuts
Ganesh

What code gives you a compiler error.

Here's some code that works.

package main
import "fmt"
func main() {
var i int32 = -1
var u uint32 = uint32(i)
var s uint32 = u >> 31
var t uint32 = uint32(i) >> 31
fmt.Println(i,u,s,t)
}

Result: -1 4294967295 1 1

Peter

Ganesh

unread,
Dec 26, 2009, 2:17:42 AM12/26/09
to golang-nuts
Thanks Peter.

> var i int32 = -1
> var u uint32 = uint32(i)

Instead of this, I used the constant directly:

var u uint32 = uint32(-1)

and I get:

unsigned.go:5: constant -1 overflows uint32

So I thought Go does not allow a conversion from negative values to
unsigned int.

I am not sure: A compiler warning would be better instead of an error
here?

-Ganesh

Rob 'Commander' Pike

unread,
Dec 26, 2009, 4:06:28 PM12/26/09
to Ganesh, golang-nuts

On 26/12/2009, at 6:17 PM, Ganesh wrote:

> Thanks Peter.
>
>> var i int32 = -1
>> var u uint32 = uint32(i)
>
> Instead of this, I used the constant directly:
>
> var u uint32 = uint32(-1)
>
> and I get:
>
> unsigned.go:5: constant -1 overflows uint32
>
> So I thought Go does not allow a conversion from negative values to
> unsigned int.
>
> I am not sure: A compiler warning would be better instead of an error
> here?


There was a long and difficult period where we tried to understand
what it meant to overflow when creating typed constants. Many subtle
issues arose. We settled the matter, at least temporarily, by
forbidding overflow in these cases. The issue may be revisited, but
for now it is simply illegal for even an intermediate value to
overflow a typed constant. For typed constants, all values must be
representable in the type, even during conversions. Thus uint32(-1)
is illegal: there is no representation of -1 in uint32.

It may not look like it, but uint32(-1) is still a constant; it hasn't
made it to a var yet.

To create this value, complement a uint32 representation of zero. That
flips the bits of a uint32 and stays representable.

var u = ^uint32(0)

Note you only need to say uint32 once.

-rob

Reply all
Reply to author
Forward
0 new messages