代码之家  ›  专栏  ›  技术社区  ›  Margus

如何用J写这个C表达式?

j c
  •  6
  • Margus  · 技术社区  · 15 年前

    我该怎么写这个C表达式呢 J ? (其中 x a 是临时变量)

    ((a= ~x & (~x >> 1)) ^= a ? 0 : (a ^ (a & (a - 1))) | (a ^ (a & (a - 1))) << 1);
    

    .

    编辑:

    以更易读的形式:

        int a = (~x) & ((~x) >> 1);
        if (a == 0) return 0;
        int b = a ^ (a & (a - 1));
        return b | (b << 1);
    
    2 回复  |  直到 15 年前
        1
  •  5
  •   MPelletier    15 年前

    如果没有测试,基本的转录会是这样的:

    Shift =: (33 b.)
    And   =: (17 b.)
    Not   =: (26 b.)
    Xor   =: (22 b.)
    Or    =: (23 b.)
    
    BastardFunction =: 3 : 0
      a =. (Not y) And (_1 Shift (Not y))
      if. a do.
        b =. a  Xor (a And a - 1)
        (1 Shift b) Or b
      else.
        0
      end.
    )
    

        2
  •  3
  •   ruslik    15 年前

    下面是一个小分析(即“可读形式”版本):

    usnigned int nx = ~x;   // I suppose it's unsigned 
    int a = nx & (nx >> 1); 
    // a will be 0 if there are no 2 consecutive "1" bits.
    // or it will contain "1" in position N1 if nx had "1" in positions N1 and N1 + 1
    if (a == 0) return 0;   // we don't have set bits for the following algorithm
    int b = a ^ (a & (a - 1));  
    // a - 1 : will reset the least 1 bit and will set all zero bits (say, NZ) that were on smaller positions
    // a & (a - 1) : will leave zeroes in all (NZ + 1) LSB bits (because they're only bits that has changed
    // a ^ (a & (a - 1)) : will cancel the high part, leaving only the smallest bit that was set in a
    // so, for a = 0b0100100 we'll obtain a power of two: b = 0000100
    return b | (b << 1);    
    // knowing that b is a power of 2, the result is b + b*2 => b*3
    

    似乎算法在寻找前2个(从LSB开始)连续的 0 x 如果没有,那么结果是0。 如果他们被发现了,说在位置上 PZ ,则结果将包含两个设置位: PZ公司 PZ+1 .