英文:
How to convert a positive signed int32 value to its negative one?
问题
我尝试编写一段逻辑,将一个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
。
###已回答
对于那些遇到这个问题的人,我已经自己回答了这个问题。
英文:
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\n", 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\n", 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.
答案1
得分: 1
两个结果不同是因为第一个值被强制转换为无符号的int32(即uint32
)。
这发生在这里:uint32(^uint32(int32(2) -1))
或者更简单地说:uint32(-2)
一个int32可以存储-2147483648到2147483647之间的任何整数。
总共有4294967296个不同的整数值(2^32...即32位)。
一个无符号的int32可以存储相同数量的不同整数值,但是丢弃了符号(+/-)。换句话说,一个无符号的int32可以存储从0到4294967295的任何值。
但是,当我们将一个有符号的int32(值为-2)强制转换为一个无符号的int32时,它无法存储值为-2的情况会发生什么呢?
嗯,正如你发现的那样,我们得到的值是4294967294。在一个整数小于0的数字系统中,4294967294恰好是0-2的和。
英文:
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.
答案2
得分: 1
你好,你可以尝试以下代码:
var z int32 = 5
a := -(z)
这段代码的作用是将变量 z
的值取负,并将结果赋给变量 a
。
英文:
Hello You can simply try below code
var z int32 =5
a:=-(z)
答案3
得分: 0
有时候,我了解到为什么我们不能在编译时执行以下代码:
fmt.Printf("%v\n", int32(^uint32(int32(2)-1)))
原因是^uint32(int32(2)-1)
被视为具有uint32
类型的常量
值。它的值是4294967294
,超过了int32
的最大值2147483647
。所以当你在源代码文件上运行go build
时,会显示编译错误
。
正确的写法应该是:
fmt.Printf("%v\n", ^(int32(2)-1))
也就是说,我们应该先将int32
类型的1
转换为二进制补码形式
,得到-1
的值。
然而,根据golang博客中的一个练习:最大的无符号整数
部分,这在运行时是合法的。所以下面的代码是正确的:
var b int32 = 2
fmt.Printf("%v\n", int32(^uint32(int32(b)-1)))
最后,这与Golang中的常量有关。
英文:
Occasionally, i have learned that why we can not do
fmt.Printf("%v\n", 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\n, ^(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\n", int32(^uint32(int32(b)-1)))
is alright.
And, finally it comes to that this is related to constants in Golang.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论