将uint64转换为int64而不丢失信息。

huangapple go评论78阅读模式
英文:

Convert uint64 to int64 without loss of information

问题

以下是要翻译的内容:

以下代码存在问题:

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

问题在于 y 的值是 -1。在不丢失信息的情况下,将这两种数字类型进行转换的唯一方法是使用编码器和解码器吗?

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

请注意,我并不是在尝试进行典型情况下的简单数值转换。我更关注于保持随机数生成器的统计特性。

英文:

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

得分: 16

你的转换在转换过程中不会丢失任何信息。所有的位都将保持不变。只是:

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

尝试一下:

var x uint64 = 18446744073709551615 - 3

你会得到 y = -4

例如:playground

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

输出:

1111111111111111111111111111111111111111111111111111111111111100
-100 or -4
英文:

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

答案2

得分: 6

看到-1与作为32位运行的进程是一致的。

例如,参见Go1.1发布说明(引入了uint64

x := ^uint32(0) // x是0xffffffff
i := int(x)     // 在32位系统上,i为-1,在64位系统上为0xffffffff
fmt.Println(i)

使用fmt.Printf("%b\n", y)可以帮助查看发生了什么(参见ANisus答案

事实证明,OP wheaties在评论中确认(在评论中),它最初是以32位运行的(因此是这个答案),但后来意识到18446744073709551615无论如何都是0xffffffffffffffff(-1):参见ANisus答案

英文:

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;

答案3

得分: 0

类型uint64和int64都可以表示2^64个离散整数值。

两者之间的区别在于,uint64只能表示正整数(0到2^64-1),而int64可以使用1位来表示符号,从而表示负数和正数(-2^63到2^63-1)。

正如其他人所说,如果你的生成器产生了0xffffffffffffffff,uint64将将其表示为原始整数(18,446,744,073,709,551,615),而int64将解释为二进制补码的值,并返回-1。

英文:

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.

huangapple
  • 本文由 发表于 2014年11月13日 22:03:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/26910696.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定