How do I get a specific bit from an Integer in Swift?

泄露秘密 提交于 2019-12-23 16:28:17

问题


Trying to convert my app to Swift from C++

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;
}

Swift:

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

But this line doesnt work in Swift:

u |= x[i];

And I can't seem to find any reference to selecting a specific bit from an integer... anyone know how?


回答1:


It is possible to use the |= operator in Swift, and it works the same as in C/C++.

The problem is that load64() in the C++ code essentially takes an array of OCTETs as an argument and accesses the array using a subscript. The Swift version takes a UInt8 as an argument, and you can't subscript an integer in Swift, just as you can't do that in C or C++.

As far as I can tell, the point of the C++ code is to build a 64-bit unsigned int from an array of 8 bytes provided in the array passed in as an argument. To get this to work in Swift, load64() will need to take an array of bytes as an argument, not just a single byte.

As an aside, if you have a large code base in C++ or C that you want to use in Swift, you don't have to re-write it in Swift. You may be able to write a C/C++ wrapper with a simplified interface and invoke it from Swift. I have a basic proof-of-concept tutorial on how to do that here: http://www.swiftprogrammer.info/swift_call_cpp.html

BTW, here is a Swift version of load64(), worked for me:

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



回答2:


With more bits you'd typically use a struct in C/C++:

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

You can then access individual bits:

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

A similar thing can be done in Swift:

struct MyBitsAndPieces: OptionSet
{
    let rawValue: UInt8

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

You can initialise and check a bit using:

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



回答3:


I don't know if swift supports |= as you've attempted, but according to the docs (first match for "swift bitwise-or" on google), it should supports:

let u = u | x[i]

Their example:

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

Separately, your C++ code will get stuck in an infinite loop on any system with unsigned chars.



来源:https://stackoverflow.com/questions/32621240/how-do-i-get-a-specific-bit-from-an-integer-in-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!