英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论