如何从Swift中的Integer中获取特定位?

时间:2015-09-17 01:28:26

标签: c++ swift bit-manipulation

尝试将我的应用程序从C ++转换为Swift

C ++:

static QWORD load64(const OCTET *x)
{
char i;
QWORD u=0;
    for(i=7; i>=0; --i) {
        u <<= 8;
        u |= x[i];
    }
    return u;
}

夫特:

func load64(x: UInt8) -> UInt64 {
    var u: UInt64 = 0;
    for var i=7; i>=0; --i {
        u <<= 8;
        u |= x[i];
    }
    return u;
}

但是这条线在Swift中不起作用:

u |= x[i];

我似乎无法找到从整数中选择特定位的任何参考...任何人都知道如何?

3 个答案:

答案 0 :(得分:2)

可以在Swift中使用| =运算符,它的工作原理与C / C ++相同。

问题是C ++代码中的load64()实际上是将一个OCTET数组作为参数,并使用下标访问该数组。 Swift版本将UInt8作为参数,你不能在Swift中下标一个整数,就像你在C或C ++中那样做。

据我所知,C ++代码的要点是从作为参数传入的数组中提供的8字节数组构建一个64位无符号整数。为了在Swift中使用它,load64()需要将一个字节数组作为参数,而不仅仅是一个字节。

顺便说一句,如果你想在Swift中使用C ++或C中的大型代码库,那么你就不必在Swift中重写它。您可以编写带有简化接口的C / C ++包装器并从Swift调用它。我有一个关于如何在此处执行此操作的基本概念验证教程:http://www.swiftprogrammer.info/swift_call_cpp.html

顺便说一下,这是一个版本的load64()版本,对我有用:

func load64(x: [UInt8]) -> UInt64 {
    var u: UInt64 = 0;
    for var i=7; i>=0; --i {
        u <<= 8;
        u |= UInt64(x[i]);
    }
    return u;
} 

答案 1 :(得分:1)

更多位通常会在C / C ++中使用struct

struct MyBitsAndPieces
{
    unsigned char bit0 :1;
    unsigned char bit1 :1;
    ...
};

然后您可以访问各个位:

struct MyBitsAndPieces baps = 2;
if (baps.bit1 == 1)
{
}

类似的事情可以在Swift中完成:

struct MyBitsAndPieces: OptionSet
{
    let rawValue: UInt8

    static let bit0 = MyBitsAndPieces(rawValue: 1 << 0)
    static let bit1 = MyBitsAndPieces(rawValue: 1 << 1)
    ...
}

您可以使用以下方法进行初始化和检查:

let baps = MyBitsAndPieces(rawValue: 2)
if baps.contains(.bit1)
{
}

答案 2 :(得分:0)

我不知道swift是否支持|=,但是根据the docs(谷歌上的“swift bitwise-or”的首次匹配),它应该支持:

let u = u | x[i]

他们的例子:

let someBits: UInt8 = 0b10110010
let moreBits: UInt8 = 0b01011110
let combinedbits = someBits | moreBits // equals 11111110

另外,您的C ++代码将在任何具有无符号字符的系统上陷入无限循环。