Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net F#位反转置换_.net_F#_Bit Manipulation_Bit - Fatal编程技术网

.net F#位反转置换

.net F#位反转置换,.net,f#,bit-manipulation,bit,.net,F#,Bit Manipulation,Bit,我想在F#中做一点反转排列 我知道如何在Python中执行此操作: def bitrev(x, bits): y = 0 for i in range(bits): y = (y << 1) | (x & 1) x >>= 1 return y def比特版本(x,比特): y=0 对于范围内的i(位): y=(y>=1 返回y 如果给定0-15范围内的值的位=4,则应返回以下列表: 084122106

我想在F#中做一点反转排列

我知道如何在Python中执行此操作:

def bitrev(x, bits):
    y = 0
    for i in range(bits):
        y = (y << 1) | (x & 1)
        x >>= 1
    return y
def比特版本(x,比特):
y=0
对于范围内的i(位):
y=(y>=1
返回y
如果给定0-15范围内的值的位=4,则应返回以下列表:
0841221061419513111715


在没有可变值的情况下如何实现这一点?

您可以始终按照命令式的方式,直接从Python进行翻译:

let bitrev x bits =
    let mutable x = x
    let mutable y = 0
    for i in 1..bits do
        y <- (y <<< 1) ||| (x &&& 1)
        x <- x >>> 1
    y
具有不变性的功能方式如下所示:

let bitrev x bits =
    let rec bitrevR x bits y =
        match bits with
        | 0 -> y
        | _ ->
        bitrevR (x >>> 1) (bits - 1)  ((y <<< 1) ||| (x &&& 1))
    bitrevR x bits 0 
binary  decimal
0000  =  0   <->   0000 =  0
0001  =  1   <->   1000 =  8
0010  =  2   <->   0100 =  4
0011  =  3   <->   1100 = 12
0100  =  4   <->   0010 =  2
0101  =  5   <->   1010 = 10
0110  =  6   <->   0110 =  6
0111  =  7   <->   1110 = 14
1000  =  8   <->   0001 =  1
1001  =  9   <->   1001 =  9
1010  = 10   <->   0101 =  5
1011  = 11   <->   1101 = 13
1100  = 12   <->   0011 =  3
1101  = 13   <->   1011 = 11
1110  = 14   <->   0111 =  7
1111  = 15   <->   1111 = 15
看起来是这样的:

let bitrev x bits =
    let rec bitrevR x bits y =
        match bits with
        | 0 -> y
        | _ ->
        bitrevR (x >>> 1) (bits - 1)  ((y <<< 1) ||| (x &&& 1))
    bitrevR x bits 0 
binary  decimal
0000  =  0   <->   0000 =  0
0001  =  1   <->   1000 =  8
0010  =  2   <->   0100 =  4
0011  =  3   <->   1100 = 12
0100  =  4   <->   0010 =  2
0101  =  5   <->   1010 = 10
0110  =  6   <->   0110 =  6
0111  =  7   <->   1110 = 14
1000  =  8   <->   0001 =  1
1001  =  9   <->   1001 =  9
1010  = 10   <->   0101 =  5
1011  = 11   <->   1101 = 13
1100  = 12   <->   0011 =  3
1101  = 13   <->   1011 = 11
1110  = 14   <->   0111 =  7
1111  = 15   <->   1111 = 15
二进制十进制 0000 = 0 0000 = 0 0001 = 1 1000 = 8 0010 = 2 0100 = 4 0011 = 3 1100 = 12 0100 = 4 0010 = 2 0101 = 5 1010 = 10 0110 = 6 0110 = 6 0111 = 7 1110 = 14 1000 = 8 0001 = 1 1001 = 9 1001 = 9 1010 = 10 0101 = 5 1011 = 11 1101 = 13 1100 = 12 0011 = 3 1101 = 13 1011 = 11 1110 = 14 0111 = 7 1111 = 15 1111 = 15
如果您不仅对单个元素
a(m,k)
感兴趣,其中
m<2^k
k=0,1,2,…
,而且对作为序列中较大块的对合感兴趣:很容易为其编写生成器

let a030109 =
    seq[0] |> Seq.unfold (fun xs ->
        let ys = Seq.map ((*) 2) xs
        let zs = Seq.map ((+) 1) ys
        Some(xs, Seq.append ys zs) )
    |> Seq.concat

a030109
|> Seq.skip (pown 2 4 - 1)
|> Seq.take (pown 2 4)
|> Seq.toList
// val it : int list = [0; 8; 4; 12; 2; 10; 6; 14; 1; 9; 5; 13; 3; 11; 7; 15]

所以我实际上做了一个命令式翻译,和你的完全一样,但不管出于什么原因,它只在位=3的情况下对我有效…你能想出一个原因吗?我最终从
1..bits-1
进行了迭代。也感谢函数式翻译!你为我节省了大量的压力-我希望我能多投票。我只是更改了位r从0..3到1..4的范围,关键是要对位进行4次内部移位。我明白了!所以迭代器值不重要,只要你进行4次迭代。