【问题标题】:C to Swift bitwise operationsC 到 Swift 的按位运算
【发布时间】:2015-08-30 01:45:55
【问题描述】:

我在 C 语言中有这些函数(来自 Cactus Kev 的扑克评估器):

unsigned find_fast(unsigned u)
{
    unsigned a, b, r;
    u += 0xe91aaa35;
    u ^= u >> 16;
    u += u << 8;
    u ^= u >> 4;
    b  = (u >> 8) & 0x1ff;
    a  = (u + (u << 2)) >> 19;
    r  = a ^ hash_adjust[b];
    return r;
}

int eval_5hand_fast(int c1, int c2, int c3, int c4, int c5)
{
    int q = (c1 | c2 | c3 | c4 | c5) >> 16;
    short s;
    if (c1 & c2 & c3 & c4 & c5 & 0xf000)
        return flushes[q]; 
    if ((s = unique5[q]))
        return s;          
    return hash_values[find_fast((c1 & 0xff) * (c2 & 0xff) * (c3 & 0xff) * (c4 & 0xff) * (c5 & 0xff))];
}

并希望将它们转换为 Swift:

func eval_5hand_fast(c1: Int, c2: Int, c3: Int, c4: Int, c5: Int) -> Int {

    var q: Int = (c1 | c2 | c3 | c4 | c5) >> 16
    var s: Int8
    if c1 & c2 & c3 & c4 & c5 & 0xf000 {
        return flushes[q]
    }
    if (s = unique5[q]) {
        return s
    }
    return hash_values[find_fast((c1 & 0xff) * (c2 & 0xff) * (c3 & 0xff) * (c4 & 0xff) * (c5 & 0xff))]
}

func find_fast(u: UInt) -> UInt {
    var a, b, r: UInt
    u += 0xe91aaa35
    u ^= u >> 16
    u += u << 8
    u ^= u >> 4
    b  = (u >> 8) & 0x1ff
    a  = (u + (u << 2)) >> 19
    r  = a ^ hash_adjust[b]
    return r;
}

我只是在学习 Swift,并没有真正做太多的按位运算,所以请多多包涵。我试图自己解决这些问题,但无济于事。我在使用 Swift 时遇到的错误包括:

  1. if c1 & c2 & c3 & c4 & c5 & 0xf000
    // ERROR: Type 'Int' does not conform to protocol 'BooleanType'
  2. if (s = unique5[q])
    // ERROR: Type '()' does not conform to protocol 'BooleanType'
  3. return hash_values[find_fast((c1 & 0xff) * (c2 & 0xff) * (c3 & 0xff) * (c4 & 0xff) * (c5 & 0xff))]
    // ERROR: Cannot find an overload for '*' that accepts the supplied arguments
  4. u += 0xe91aaa35
    // ERROR: Cannot invoke '+=' with an argument list of type '(UInt, IntegerLiteralConvertible)'
  5. u ^= u >> 16
    // ERROR: Cannot invoke '>>' with an argument list of type '(UInt, $T5)'
  6. u += u << 8
    // ERROR: Cannot invoke '+=' with an argument list of type '(UInt, $T5)'
    
  7. u ^= u >> 4
    // ERROR: Cannot invoke '>>' with an argument list of type '(UInt, $T5)'

我收到第一个错误(它不是布尔值),但是我不确定如何解决它,因为我不完全确定 C 版本的要求是什么,因为我不太熟悉使用位和掩码。其他错误我真的不知道该怎么办。

【问题讨论】:

    标签: c swift bitwise-operators


    【解决方案1】:

    当涉及到整数时,C 中任何非 0 都被视为 true。Swift 需要一个布尔值,因此您必须添加 != 0。例如:

    C:     if c1 & c2 & c3 & c4 & c5 & 0xf000
    Swift: if c1 & c2 & c3 & c4 & c5 & 0xf000 != 0
    
    C:     if (s = unique5[q])
    Swift: if let s = unique5[q] where s != 0
    

    试试这个:

    func eval_5hand_fast(c1: Int, c2: Int, c3: Int, c4: Int, c5: Int) -> Int {
    
        var q: Int = (c1 | c2 | c3 | c4 | c5) >> 16
        var s: Int8
        if c1 & c2 & c3 & c4 & c5 & 0xf000 != 0 {
            return flushes[q]
        }
        if let s = unique5[q] where s != 0 {
            return s
        }
        return hash_values[find_fast((c1 & 0xff) * (c2 & 0xff) * (c3 & 0xff) * (c4 & 0xff) * (c5 & 0xff))]
    }
    
    func find_fast(var u: UInt) -> UInt {
        var a, b, r: UInt
        u += 0xe91aaa35
        u ^= u >> 16
        u += u << 8
        u ^= u >> 4
        b  = (u >> 8) & 0x1ff
        a  = (u + (u << 2)) >> 19
        r  = a ^ hash_adjust[b]
        return r;
    }
    

    【讨论】:

    • 第一个很好,感谢您的解释。第二个我只是在 if 语句之前设置 s = unique5[q],然后检查 if s != 0。
    • 我也解决了“过载”错误,但我似乎对 find_fast 函数中的按位运算错误无能为力。我猜某种类型转换是必要的?
    • 似乎 'u' 是一个常数,改变它会使错误消失。
    猜你喜欢
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-28
    相关资源
    最近更新 更多