shiftR
对Integers
执行算术移位。是否有标准的方法来进行逻辑转换?
我可以想到两个方法来做到这一点。取2 ^ n的商:
unsignedShiftR i n = i `quot` (2 ^ n)
另一种方法是在算术移位后屏蔽上n位(尽管我不确定你能获得掩码的位置)。
答案 0 :(得分:3)
就Int
而言,标准的做法是将其转换为无符号类型并将其转移到那里:
import Data.Word
ushiftR :: Int -> Int -> Int
ushiftR n k = fromIntegral (fromIntegral n `shiftR` k :: Word)
答案 1 :(得分:2)
由于某些原因,它不包含在Data.Bits
中,但有GHC primop:uncheckedIShiftRL#
。此外,GHC.Base
会将更安全的版本导出为iShiftRL#
:
iShiftRL# :: Int# -> Int# -> Int#
a `iShiftRL#` b | isTrue# (b >=# WORD_SIZE_IN_BITS#) = 0#
| otherwise = a `uncheckedIShiftRL#` b
我们可以使用不同数量的检查来包装GHC.Base
版本或primop:
{-# LANGUAGE MagicHash #-}
import GHC.Base
import GHC.Prim
uncheckedIShiftRL :: Int -> Int -> Int
uncheckedIShiftRL (I# n) (I# i) = I# (uncheckedIShiftRL# n i)
unsafeIShiftRL :: Int -> Int -> Int
unsafeIShiftRL (I# n) (I# i) = I# (iShiftRL# n i)
iShiftRL :: Int -> Int -> Int
iShiftRL (I# n) (I# i)
| isTrue# (i >=# 0#) = I# (iShiftRL# n i)
| otherwise = error "shift by negative amount"