从两个值生成唯一ID

时间:2013-12-03 09:49:32

标签: algorithm haskell numbers

从两个值生成唯一数字(例如,64位无符号整数)的惯用方法是什么,这样可以从输出值(也是相同类型的数字)重新生成number,作为Haskell函数?

在C / C ++上我可能会使用像

这样的东西
result = (((value1) << BITS) + ((value2) & ((1 << BITS) - 1)))

,因此,

value1 = (result >> BITS)

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

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

经过考虑后,我简单地放弃了使用按位运算的想法,并采用了Cantor's pairing function

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上的位操作。

1 个答案:

答案 0 :(得分:4)

您可以在Haskell中使用完全相同的方式。可以在Data.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位无符号整数。