从两个值生成唯一数字(例如,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上的位操作。
答案 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位无符号整数。