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

时间:2016-01-25 12:12:09

标签: go

我尝试写一个逻辑是将int32正值转换为相应的负值,即abs(negativeInt32) == positiveInt32

我试过两个:

  • 首先:

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

    这会导致错误:prog.go:8: constant 4294967294 overflows int32

  • 第二

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

    这会产生-2

两者如何导致不同的结果。我认为他们是平等的 play.golang.org

修改

编辑以便在第一种情况下用uint32替换int32

ANSWERED

对于那些遇到这个问题的人,我自己已经回答了这个问题。 :)

2 个答案:

答案 0 :(得分:1)

两个结果不同,因为第一个值是 unsigned int32(一个uint32)的类型转换。

这发生在这里:uint32(^uint32(int32(2) -1))
或者更简单:uint32(-2)

int32可以存储-2147483648和2147483647之间的任何整数 这总共有4294967296个不同的整数值(2 ^ 32 ...即32位)。

unsigned int32可以存储相同数量的不同整数值,但会丢弃标牌(+/-)。换句话说, unsigned int32可以存储0到4294967295之间的任何值。

但是当我们将签名的 int32(值为-2)强制转换为 unsigned int32时,会发生什么呢?它不可能存储-2的值?< / p>

正如您所发现的那样,我们得到值4294967294.在一个数字系统中,一个小于0的整数是4294967295; 4294967294恰好是0 - 2的总和。

答案 1 :(得分:0)

偶尔,我已经知道为什么我们不能做

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

在编译时。 ^uint32(int32(2)-1)被视为具有constant类型的uint32值。它的值是4294967294。这超出了int32的{​​{1}}的最大值。因此,当您在源代码文件上运行2147483647时。显示go build

对此的正确答案应该是:

Compile error

即,我们应首先在fmt.Printf("%v\n, ^(int32(2) - 1)) 类型中获取1的相应值,然后将其转换为int32作为-1的值。

但是,根据two's complementary formAn exercise: The largest unsigned int部分,这在运行时是合法的。所以代码

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

没关系。

最后,它与Golang中的常量有关。 :)