英文:
On-purpose int overflow
问题
我正在使用哈希函数murmur2
,它返回一个uint64
类型的值。
然后我想将其存储在只支持BIGINT
(有符号64位)的PostgreSQL中。
由于我对数字本身不感兴趣,只对二进制值感兴趣(因为我将其用作检测唯一性的标识符,我的值集合大约有1000个值,64位哈希对我来说足够了),我想通过“仅仅”更改类型将其转换为int64
。
如何以一种让编译器满意的方式做到这一点?
英文:
I'm using the hash function murmur2
which returns me an uint64
.
I want then to store it in PostgreSQL, which only support BIGINT
(signed 64 bits).
As I'm not interested in the number itself, but just the binary value (as I use it as an id for detecting uniqueness (my set of values being of ~1000 values, a 64bit hash is enough for me) I would like to convert it into int64
by "just" changing the type.
How does one do that in a way that pleases the compiler?
答案1
得分: 7
你可以简单地使用类型转换:
i := uint64(0xffffffffffffffff)
i2 := int64(i)
fmt.Println(i, i2)
输出:
18446744073709551615 -1
将 uint64
转换为 int64
总是成功的:它不会改变内存表示,只是改变了类型。可能会让你困惑的是,如果你尝试将无类型整数常量值转换为 int64
:
i3 := int64(0xffffffffffffffff) // 编译时错误!
这是一个编译时错误,因为常量值 0xffffffffffffffff
(使用任意精度表示)无法适应 int64
,因为适应 int64
的最大值是 0x7fffffffffffffff
:
constant 18446744073709551615 overflows int64
英文:
You can simply use a type conversion:
i := uint64(0xffffffffffffffff)
i2 := int64(i)
fmt.Println(i, i2)
Output:
18446744073709551615 -1
Converting uint64
to int64
always succeeds: it doesn't change the memory representation just the type. What may confuse you is if you try to convert an untyped integer constant value to int64
:
i3 := int64(0xffffffffffffffff) // Compile time error!
This is a compile time error as the constant value 0xffffffffffffffff
(which is represented with arbitrary precision) does not fit into int64
because the max value that fits into int64
is 0x7fffffffffffffff
:
constant 18446744073709551615 overflows int64
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论