从两个值生成唯一的ID

从两个值中产生一个唯一的数字(比如说一个64位无符号整数)是一种惯用的方式,以这种方式可以从数字中重新生成输入值(也是同一类型的数字),如Haskell函数?

在C / C ++上,我可能会使用类似的东西

result = (((value1) << BITS) + ((value2) & ((1 << BITS) - 1)))

并因此,

value1 = (result >> BITS)

value2 = (result & ((1 << BITS) - 1))

重新生成值,但我不认为我应该尝试在Haskell中使用按位运算。

经过考虑,我简单地放弃了使用按位操作的想法,并采用了Cantor的配对功能:

pair :: (Fractional a) => a -> a -> a
pair x y = (1 / 2) * (x + y) * (x + y + 1) + y

unpair :: (RealFrac a, Floating a) => a -> (a, a)
unpair z = (x, y) where
    q = (-1 / 2) + sqrt (1 / 4 + 2 * z)
    j = fromInteger (truncate q)
    y = z - ((1 / 2) * j * (j + 1))
    x = j - y

这可能是我从一开始就应该考虑的方式。 不过,非常感谢您帮助我更好地理解Haskell的一些操作。


你可以在Haskell中使用完全相同的方式。 按位操作可以在Data.BitsData.Bits无符号,固定大小的整数类型中Data.Word 。 例如:

import Data.Bits
import Data.Word

combine :: Word32 -> Word32 -> Word64
combine a b = (fromIntegral a `shiftL` 32) + fromIntegral b

separate :: Word64 -> (Word32, Word32)
separate w = (fromIntegral $ w `shiftR` 32, fromIntegral $ w .&. 0xffff)

与C相比,可能会让你感觉不舒服的是Haskell不会隐式地在不同的数字类型之间进行转换,因此您需要使用fromIntegral来在例如32位和64位无符号整数之间进行转换。

链接地址: http://www.djcxy.com/p/6365.html

上一篇: Generating an unique ID from two values

下一篇: Algorithm to represent a sequence of numbers