【发布时间】:2023-02-06 23:52:48
【问题描述】:
我有无符号的 64 位数字,代表尾数或分数(代表范围从 [0..1),其中 0.0 映射到 0 和 0xffffff.. 映射到数字“就在 1.0 之前”)
现在我想把这个范围分成相等的buckets - 并回答 - 给定随机数key,它会落到范围的哪一部分?
从以下代码中更容易获得:
func BucketIndex(key, buckets uint64) uint64 {
return uint64(float64(key) / ((math.Pow(2, 64) / float64(buckets)))
}
我试图“解决这个问题”——将 2^64 分成两个,就像我将范围缩小到 32 位,并在 64 位中运行以进行数学运算一样:
// ~=key / ((1 << 64) / buckets)
return ((key >> 32) * buckets) >> 32
但范围停止相等..
例如,三分之一 (buckets==3) 将在0x5555555600000000,而不是在0x5555555555555556
那是个悲伤的故事,所以我问你知道找到(1 << 64) / buckets 的更好方法吗?
【问题讨论】:
-
使用
max / buckets的桶大小,四舍五入,桶索引将为key / bucketSize。这还不够吗? -
@icza 这是我的问题,你怎么能找到 max (在 uint64 范围之外)
-
换句话说,我对 (Maxint64+1) / buckets 感兴趣
-
想一想
key / (max / buckets)如果你会做key * buckets / max- 你会立即得到 0,因为它就像将 uint64 的所有位移动 64 个位置到 lsb,从 uint64 存储中清除它的所有位......
标签: go fixed-point