如何将正有符号的int32值转换为其负值?

I have try to write one logic is to convert an int32 positive value to a corresponding negative one, i.e., abs(negativeInt32) == positiveInt32.

I have tried with both:

  • First:

    fmt.Printf("%v
    ", int32(^uint32(int32(2) -1)))
    

    This results in an error : prog.go:8: constant 4294967294 overflows int32

  • Second:

    var b int32 = 2
    fmt.Printf("%v
    ", int32(^uint32(int32(b)-1)))
    

    This results in -2.

How can both result in different results. I think they are equal.
play.golang.org

EDIT

Edit for replacing uint32 with int32 for the first situation.

ANSWERED

For those who come to this problem, I have answered the question myself. :)

The two results are different because the first value is typecast to an unsigned int32 (a uint32).

This occurs here: uint32(^uint32(int32(2) -1))
Or more simply: uint32(-2)

An int32 can store any integer between -2147483648 and 2147483647.
That's a total of 4294967296 different integer values (2^32... i.e. 32 bits).

An unsigned int32 can store the same amount of different integer values, but drops the signage (+/-). In other words, an unsigned int32 can store any value from 0 to 4294967295.

But what happens when we typecast a signed int32 (with a value of -2) to an unsigned int32, which cannot possibly store the value of -2?

Well as you have found, we get the value of 4294967294. Which in a number system where one integer less than 0 is 4294967295; 4294967294 happens to be the sum of 0 - 2.

Occasionally, i have learned that why we can not do

fmt.Printf("%v
", int32(^uint32(int32(2) -1)))

at compile time. It is that ^uint32(int32(2)-1) is treated as a constant value with uint32 type. It's value is 4294967294. This exceeds the maximum value of int32 for 2147483647. So when you run go build on the source code file. Compile error is shown.

The right answer to this should be:

fmt.Printf("%v
, ^(int32(2) - 1))

i.e., we should first get the corresponding value of 1 in int32 type and, then convert it to the two's complementary form as value of -1.

However, according to this golang blog's An exercise: The largest unsigned int section, this is legal in runtime. So the code

var b int32 = 2
fmt.Printf("%v
", int32(^uint32(int32(b)-1)))

is alright.

And, finally it comes to that this is related to constants in Golang. :)