gpt4 book ai didi

f# - 与 OCaml 的 'lsr' 和 'asr' 等效的 F# 按位运算符是什么?

转载 作者:行者123 更新时间:2023-12-04 22:59:52 33 4
gpt4 key购买 nike

我一直在查看 Hash Array Mapped Tries 的 OCaml 实现并注意到使用了三个不同的位级运算符:

  • lsl : 左移
  • lsr : 右移
  • asr : 无符号右移

  • 我想将其移植到 F#,但不确定 F# 按位运算符的确切行为。

    F# 语言引用提供了两个按位运算符:
  • <<< : 左移
  • >>> : 右移

  • 我将如何使用这些运算符来复制 OCaml 原件?

    问候,

    迈克尔

    最佳答案

    检查运算符 <<< 的实现和 >>>提示解决方案 ( https://github.com/Microsoft/visualfsharp/blob/fsharp4/src/fsharp/FSharp.Core/prim-types.fs )

    let inline mask (n:int) (m:int) = (# "and" n m : int #)

    [<NoDynamicInvocation>]
    let inline (<<<) (x: ^T) (n:int) : ^T =
    (^T: (static member (<<<) : ^T * int -> ^T) (x,n))
    when ^T : int32 = (# "shl" x (mask n 31) : int #)
    when ^T : uint32 = (# "shl" x (mask n 31) : uint32 #)
    when ^T : int64 = (# "shl" x (mask n 63) : int64 #)
    when ^T : uint64 = (# "shl" x (mask n 63) : uint64 #)
    when ^T : nativeint = (# "shl" x n : nativeint #)
    when ^T : unativeint = (# "shl" x n : unativeint #)
    when ^T : int16 = (# "conv.i2" (# "shl" x (mask n 15) : int32 #) : int16 #)
    when ^T : uint16 = (# "conv.u2" (# "shl" x (mask n 15) : uint32 #) : uint16 #)
    when ^T : sbyte = (# "conv.i1" (# "shl" x (mask n 7 ) : int32 #) : sbyte #)
    when ^T : byte = (# "conv.u1" (# "shl" x (mask n 7 ) : uint32 #) : byte #)

    [<NoDynamicInvocation>]
    let inline (>>>) (x: ^T) (n:int) : ^T =
    (^T: (static member (>>>) : ^T * int -> ^T) (x,n))
    when ^T : int32 = (# "shr" x (mask n 31) : int32 #)
    when ^T : uint32 = (# "shr.un" x (mask n 31) : uint32 #)
    when ^T : int64 = (# "shr" x (mask n 63) : int64 #)
    when ^T : uint64 = (# "shr.un" x (mask n 63) : uint64 #)
    when ^T : nativeint = (# "shr" x n : nativeint #)
    when ^T : unativeint = (# "shr.un" x n : unativeint #)
    when ^T : int16 = (# "conv.i2" (# "shr" x (mask n 15) : int32 #) : int16 #)
    when ^T : uint16 = (# "conv.u2" (# "shr.un" x (mask n 15) : uint32 #) : uint16 #)
    when ^T : sbyte = (# "conv.i1" (# "shr" x (mask n 7 ) : int32 #) : sbyte #)
    when ^T : byte = (# "conv.u1" (# "shr.un" x (mask n 7 ) : uint32 #) : byte #)

    此代码使用内联 IL 以及仅适用于 F# 开发人员的类型重载,但有趣的行似乎是:
    when ^T : int32      = (# "shr"    x (mask n 31) : int32 #)
    when ^T : uint32 = (# "shr.un" x (mask n 31) : uint32 #)

    右移 int32版本然后使用 shr (有符号右移)对应于 asr , uint32用途 shr.un (无符号右移)对应于 lsr .

    左移版本都使用 shl .

    所以对于 int32一个潜在的解决方案可能是:
    module ShiftOps =
    let inline ( lsl ) (x: int32) (n:int) : int32 = x <<< n
    let inline ( lsr ) (x: int32) (n:int) : int32 = int32 (uint32 x >>> n)
    let inline ( asr ) (x: int32) (n:int) : int32 = x >>> n

    open ShiftOps

    [<EntryPoint>]
    let main argv =
    printfn "0x%x" <| -1 lsr 4
    printfn "0x%x" <| -1 asr 4
    printfn "0x%x" <| -1 lsl 4

    0

    关于f# - 与 OCaml 的 'lsr' 和 'asr' 等效的 F# 按位运算符是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29196383/

    33 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com