Wykonuję operacje bitowe w stylu Swift, które to kody są pierwotnie napisane w Objective-C/C. Używam UnsafeMutablePointer
do określenia początkowego indeksu adresu pamięci i użycia UnsafeMutableBufferPointer
do uzyskiwania dostępu do elementu w zasięgu.Testowanie nie powiodło się po konwersji kodów z Objective-C na Swift
Można uzyskać dostęp do oryginalnego pliku Objective-C Here.
public init(size: Int) {
self.size = size
self.bitsLength = (size + 31)/32
self.startIdx = UnsafeMutablePointer<Int32>.alloc(bitsLength * sizeof(Int32))
self.bits = UnsafeMutableBufferPointer(start: startIdx, count: bitsLength)
}
/**
* @param from first bit to check
* @return index of first bit that is set, starting from the given index, or size if none are set
* at or beyond its given index
*/
public func nextSet(from: Int) -> Int {
if from >= size { return size }
var bitsOffset = from/32
var currentBits: Int32 = bits[bitsOffset]
currentBits &= ~((1 << (from & 0x1F)) - 1).to32
while currentBits == 0 {
if ++bitsOffset == bitsLength {
return size
}
currentBits = bits[bitsOffset]
}
let result: Int = bitsOffset * 32 + numberOfTrailingZeros(currentBits).toInt
return result > size ? size : result
}
func numberOfTrailingZeros(i: Int32) -> Int {
var i = i
guard i != 0 else { return 32 }
var n = 31
var y: Int32
y = i << 16
if y != 0 { n = n - 16; i = y }
y = i << 8
if y != 0 { n = n - 8; i = y }
y = i << 4
if y != 0 { n = n - 4; i = y }
y = i << 2
if y != 0 { n = n - 2; i = y }
return n - Int((UInt((i << 1)) >> 31))
}
TESTCASE:
func testGetNextSet1() {
// Passed
var bits = BitArray(size: 32)
for i in 0..<bits.size {
XCTAssertEqual(32, bits.nextSet(i), "\(i)")
}
// Failed
bits = BitArray(size: 34)
for i in 0..<bits.size {
XCTAssertEqual(34, bits.nextSet(i), "\(i)")
}
}
Może ktoś poprowadzi mnie dlaczego drugi testcase nie ale wersja objective-c Pass?
Edytuj: Jak wspomniała @vacawama: Jeśli złamiesz testGetNextSet na 2 testy, obydwa przekaż.
Edit2: Kiedy uruchomić testy z xctool
i testy, które wzywające BitArray
„s nextSet()
padnie podczas biegu.
Jak '' .to32' .toInt' i wdrażane? – vacawama
@vacawama Jest to rozszerzenie Int # public var to32: Int32 {return Int32 (truncatingBitPattern: self)} ' –
Ta instrukcja jest kłopotliwa:' return n - Int ((UInt ((i << 1)) >> 31)). "Jeśli" i' jest ujemny, to się zawiesi. – vacawama