Go: convert uint64 to int64 without loss of information

会有一股神秘感。 提交于 2019-12-30 09:34:48

问题


The problem with the following code:

var x uint64 = 18446744073709551615
var y int64 = int64(x)

is that y is -1. Without loss of information, is the only way to convert between these two number types to use an encoder and decoder?

buff bytes.Buffer
Encoder(buff).encode(x)
Decoder(buff).decode(y)

Note, I am not attempting a straight numeric conversion in your typical case. I am more concerned with maintaining the statistical properties of a random number generator.


回答1:


Seeing -1 would be consistent with a process running as 32bits.

See for instance the Go1.1 release notes (which introduced uint64)

x := ^uint32(0) // x is 0xffffffff
i := int(x)     // i is -1 on 32-bit systems, 0xffffffff on 64-bit
fmt.Println(i)

Using fmt.Printf("%b\n", y) can help to see what is going on (see ANisus' answer)

As it turned out, the OP wheaties confirms (in the comments) it was run initially in 32 bits (hence this answer), but then realize 18446744073709551615 is 0xffffffffffffffff (-1) anyway: see ANisusanswer;




回答2:


Your conversion does not lose any information in the conversion. All the bits will be untouched. It is just that:

uint64(18446744073709551615) = 0xFFFFFFFFFFFFFFFF
int64(-1)                    = 0xFFFFFFFFFFFFFFFF

Try:

var x uint64 = 18446744073709551615 - 3

and you will have y = -4.


For instance: playground

var x uint64 = 18446744073709551615 - 3
var y int64 = int64(x)
fmt.Printf("%b\n", x)
fmt.Printf("%b or %d\n", y, y)

Output:

1111111111111111111111111111111111111111111111111111111111111100
-100 or -4



回答3:


The types uint64 and int64 can both represent 2^64 discrete integer values.

The difference between the two is that uint64 holds only positive integers (0 thru 2^64-1), where as int64 holds both negative and positive integers using 1 bit to hold the sign (-2^63 thru 2^63-1).

As others have said, if your generator is producing 0xffffffffffffffff, uint64 will represent this as the raw integer (18,446,744,073,709,551,615) whereas int64 will interpret the two's complement value and return -1.



来源:https://stackoverflow.com/questions/26910696/go-convert-uint64-to-int64-without-loss-of-information

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!