Reputation: 145
I'm trying to convert a piece of C code to Swift 3 both using pointers. Here is relevant part in C code.
Float32 sampleArray[256] = { // Array is 256 Float values
0.00000, 0.00000, -0.00060, 0.00000, -0.00237, 0.00000, -0.00528 etc.etc}
float *p1, *p2, temp;
long i, bitm, j;
for (i = 2; i < 128-2; i += 2) {
for (bitm = 2, j = 0; bitm < 256; bitm <<= 1) {
if (i & bitm){j++;}
j <<= 1;
}
if (i < j ) {
p1 = sampleArray+i;
p2 = sampleArray+j;
temp = *p1;
*(p1++) = *p2; //Stuck from this point onwards
*(p2++) = temp;
temp = *p1;
*p1 = *p2;
*p2 = temp;
}
}//eo for
And here is my swift attempt. Obviously using the same type of array but in swift
var bitm:CLong
var j:CLong
var temp:Float
var p1:UnsafeMutablePointer<Float>
var p2:UnsafeMutablePointer<Float>
for i in stride(from: 2, to: 128-2, by: 2){
j = 0
bitm = 2;
while bitm < 256 {
if (i & bitm != 0){ j = j + 1}
j = j<<1
bitm<<=1
}
if (i < j){
p1 = UnsafeMutablePointer(mutating: sampleArray)+i
p2 = UnsafeMutablePointer(mutating: sampleArray)+j
temp = p1.pointee
/* looks ok up to this point*/
}
}//eo stride
As you can tell i have got as far as
*(p1++) = *p2;
I thought this might be a case of shifting the pointers using
p1.advanced(by: 1)
any help with the last four lines would be appreciated i notice that
p2.pointee = somevalue
describes the points in the array that need working on. And if i replace everything as
sampleArray[j] = sampleArray[i]
gets me closer to work in few lines of code. But i would like to keep it as pointers. So i can get my head round how they works in swift.Thank you..
for clarity here is the sampleArray
var sampleArray:[Float] = [
0.00000, 0.00000, -0.00060, 0.00000, -0.00237, 0.00000, -0.00528, 0.00000, -0.00931, 0.00000, -0.01440, 0.00000, -0.02052, 0.00000, -0.02762, 0.00000, -0.03566, 0.00000, -0.04460, 0.00000, -0.05443, 0.00000, -0.06502, 0.00000, -0.07634, 0.00000, -0.08836, 0.00000, -0.10101, 0.00000, -0.11424, 0.00000, -0.12799, 0.00000, -0.14238, 0.00000, -0.15703, 0.00000, -0.17203, 0.00000, -0.18733, 0.00000, -0.20286, 0.00000, -0.21858, 0.00000, -0.23470, 0.00000, -0.25063, 0.00000, -0.26657, 0.00000, -0.28247, 0.00000, -0.29827, 0.00000, -0.31392, 0.00000, -0.32979, 0.00000, -0.34501, 0.00000, -0.35993, 0.00000, -0.37450, 0.00000, -0.38868, 0.00000, -0.40242, 0.00000, -0.41569, 0.00000, -0.42904, 0.00000, -0.44126, 0.00000, -0.45289, 0.00000, -0.46390, 0.00000, -0.47426, 0.00000, -0.48394, 0.00000, -0.49365, 0.00000, -0.50193, 0.00000, -0.50945, 0.00000, -0.51621, 0.00000, -0.52219, 0.00000, -0.52738, 0.00000, -0.53176, 0.00000, -0.53621, 0.00000, -0.53900, 0.00000, -0.54096, 0.00000, -0.54212, 0.00000, -0.54246, 0.00000, -0.54199, 0.00000, -0.54169, 0.00000, -0.53965, 0.00000, -0.53684, 0.00000, -0.53327, 0.00000, -0.52895, 0.00000, -0.52392, 0.00000, -0.51918, 0.00000, -0.51276, 0.00000, -0.50570, 0.00000, -0.49800, 0.00000, -0.48971, 0.00000, -0.48084, 0.00000, -0.47144, 0.00000, -0.46251, 0.00000, -0.45212, 0.00000, -0.44129, 0.00000, -0.43005, 0.00000, -0.41844, 0.00000, -0.40650, 0.00000, -0.39520, 0.00000, -0.38269, 0.00000, -0.36996, 0.00000, -0.35704, 0.00000, -0.34396, 0.00000, -0.33078, 0.00000, -0.31752, 0.00000, -0.30506, 0.00000, -0.29174, 0.00000, -0.27845, 0.00000, -0.26523, 0.00000, -0.25210, 0.00000, -0.23910, 0.00000, -0.22698, 0.00000, -0.21432, 0.00000, -0.20187, 0.00000, -0.18967, 0.00000, -0.17775, 0.00000, -0.16612, 0.00000, -0.15538, 0.00000, -0.14439, 0.00000, -0.13376, 0.00000, -0.12350, 0.00000, -0.11364, 0.00000, -0.10418, 0.00000, -0.09514, 0.00000, -0.08693, 0.00000, -0.07873, 0.00000, -0.07097, 0.00000, -0.06366, 0.00000, -0.05679, 0.00000, -0.05038, 0.00000, -0.04467, 0.00000, -0.03911, 0.00000, -0.03400, 0.00000, -0.02931, 0.00000, -0.02504, 0.00000, -0.02118, 0.00000, -0.01772, 0.00000, -0.01477, 0.00000, -0.01203, 0.00000, -0.00964, 0.00000, -0.00758, 0.00000, -0.00583, 0.00000, -0.00437, 0.00000, -0.00322, 0.00000, -0.00225, 0.00000, -0.00149, 0.00000, -0.00093, 0.00000, -0.00052, 0.00000, -0.00026, 0.00000, -0.00011, 0.00000, -0.00003, 0.00000, 0.00000, 0.00000,]
And this is what the output should be according to the c code
0.0000, 0.0000, -0.4980, 0.0000, -0.3745, 0.0000, -0.1235, 0.0000, -0.1280, 0.0000, -0.3175, 0.0000, -0.5318, 0.0000, -0.0177, 0.0000, -0.0357, 0.0000, -0.4184, 0.0000, -0.4743, 0.0000, -0.0568, 0.0000, -0.2506, 0.0000, -0.2143, 0.0000, -0.5396, 0.0000, -0.0022, 0.0000, -0.0093, 0.0000, -0.4625, 0.0000, -0.4290, 0.0000, -0.0869, 0.0000, -0.1873, 0.0000, -0.2652, 0.0000, -0.5421, 0.0000, -0.0076, 0.0000, -0.0763, 0.0000, -0.3700, 0.0000, -0.5094, 0.0000, -0.0340, 0.0000, -0.3139, 0.0000, -0.1661, 0.0000, -0.5239, 0.0000, -0.0003, 0.0000, -0.0024, 0.0000, -0.4808, 0.0000, -0.4024, 0.0000, -0.1042, 0.0000, -0.1570, 0.0000, -0.2917, 0.0000, -0.5390, 0.0000, -0.0120, 0.0000, -0.0544, 0.0000, -0.3952, 0.0000, -0.4937, 0.0000, -0.0447, 0.0000, -0.2825, 0.0000, -0.1897, 0.0000, -0.5333, 0.0000, -0.0009, 0.0000, -0.0205, 0.0000, -0.4413, 0.0000, -0.4529, 0.0000, -0.0710, 0.0000, -0.2186, 0.0000, -0.2391, 0.0000, -0.5420, 0.0000, -0.0044, 0.0000, -0.1010, 0.0000, -0.3440, 0.0000, -0.5222, 0.0000, -0.0250, 0.0000, -0.3450, 0.0000, -0.1444, 0.0000, -0.5128, 0.0000, -0.5057, 0.0000, -0.0006, 0.0000, -0.4897, 0.0000, -0.3887, 0.0000, -0.4714, 0.0000, -0.1424, 0.0000, -0.4521, 0.0000, -0.5362, 0.0000, -0.4301, 0.0000, -0.0446, 0.0000, -0.4065, 0.0000, -0.4839, 0.0000, -0.3827, 0.0000, -0.2666, 0.0000, -0.3570, 0.0000, -0.5368, 0.0000, -0.3308, 0.0000, -0.0144, 0.0000, -0.3051, 0.0000, -0.4413, 0.0000, -0.2785, 0.0000, -0.2029, 0.0000, -0.2521, 0.0000, -0.5425, 0.0000, -0.2270, 0.0000, -0.0884, 0.0000, -0.2019, 0.0000, -0.5162, 0.0000, -0.1777, 0.0000, -0.3298, 0.0000, -0.1554, 0.0000, -0.5192, 0.0000, -0.1338, 0.0000, -0.0053, 0.0000, -0.1136, 0.0000, -0.4157, 0.0000, -0.0951, 0.0000, -0.1720, 0.0000, -0.0787, 0.0000, -0.5410, 0.0000, -0.0637, 0.0000, -0.0650, 0.0000, -0.0504, 0.0000, -0.5019, 0.0000, -0.0391, 0.0000, -0.2983, 0.0000, -0.0293, 0.0000, -0.5290, 0.0000, -0.0212, 0.0000, -0.0276, 0.0000, -0.0148, 0.0000, -0.4639, 0.0000, -0.0096, 0.0000, -0.2347, 0.0000, -0.0058, 0.0000, -0.5417, 0.0000, -0.0032, 0.0000, -0.1142, 0.0000, -0.0015, 0.0000, -0.5274, 0.0000, -0.0005, 0.0000, -0.3599, 0.0000, -0.0001, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000,
Upvotes: 3
Views: 224
Reputation: 78825
Your C code simply uses pointers to access array elements. There is no need to use pointers, neither in C nor in Swift. This style of C code might have been faster 30 years ago. But today it prevents the compiler from effectively using registers.
The good news is: we don't need pointers and can convert it to Swift easily. The code you're stuck at really just swaps the elements at i / j and at i + 1 / j + 1.
var sampleArray: [Float] = [
0.00000, 0.00000, -0.00060, 0.00000, -0.00237, 0.00000, -0.00528, 0.00000, -0.00931, 0.00000, -0.01440, 0.00000, -0.02052, 0.00000, -0.02762, 0.00000, -0.03566, 0.00000, -0.04460, 0.00000, -0.05443, 0.00000, -0.06502, 0.00000, -0.07634, 0.00000, -0.08836, 0.00000, -0.10101, 0.00000, -0.11424, 0.00000, -0.12799, 0.00000, -0.14238, 0.00000, -0.15703, 0.00000, -0.17203, 0.00000, -0.18733, 0.00000, -0.20286, 0.00000, -0.21858, 0.00000, -0.23470, 0.00000, -0.25063, 0.00000, -0.26657, 0.00000, -0.28247, 0.00000, -0.29827, 0.00000, -0.31392, 0.00000, -0.32979, 0.00000, -0.34501, 0.00000, -0.35993, 0.00000, -0.37450, 0.00000, -0.38868, 0.00000, -0.40242, 0.00000, -0.41569, 0.00000, -0.42904, 0.00000, -0.44126, 0.00000, -0.45289, 0.00000, -0.46390, 0.00000, -0.47426, 0.00000, -0.48394, 0.00000, -0.49365, 0.00000, -0.50193, 0.00000, -0.50945, 0.00000, -0.51621, 0.00000, -0.52219, 0.00000, -0.52738, 0.00000, -0.53176, 0.00000, -0.53621, 0.00000, -0.53900, 0.00000, -0.54096, 0.00000, -0.54212, 0.00000, -0.54246, 0.00000, -0.54199, 0.00000, -0.54169, 0.00000, -0.53965, 0.00000, -0.53684, 0.00000, -0.53327, 0.00000, -0.52895, 0.00000, -0.52392, 0.00000, -0.51918, 0.00000, -0.51276, 0.00000, -0.50570, 0.00000, -0.49800, 0.00000, -0.48971, 0.00000, -0.48084, 0.00000, -0.47144, 0.00000, -0.46251, 0.00000, -0.45212, 0.00000, -0.44129, 0.00000, -0.43005, 0.00000, -0.41844, 0.00000, -0.40650, 0.00000, -0.39520, 0.00000, -0.38269, 0.00000, -0.36996, 0.00000, -0.35704, 0.00000, -0.34396, 0.00000, -0.33078, 0.00000, -0.31752, 0.00000, -0.30506, 0.00000, -0.29174, 0.00000, -0.27845, 0.00000, -0.26523, 0.00000, -0.25210, 0.00000, -0.23910, 0.00000, -0.22698, 0.00000, -0.21432, 0.00000, -0.20187, 0.00000, -0.18967, 0.00000, -0.17775, 0.00000, -0.16612, 0.00000, -0.15538, 0.00000, -0.14439, 0.00000, -0.13376, 0.00000, -0.12350, 0.00000, -0.11364, 0.00000, -0.10418, 0.00000, -0.09514, 0.00000, -0.08693, 0.00000, -0.07873, 0.00000, -0.07097, 0.00000, -0.06366, 0.00000, -0.05679, 0.00000, -0.05038, 0.00000, -0.04467, 0.00000, -0.03911, 0.00000, -0.03400, 0.00000, -0.02931, 0.00000, -0.02504, 0.00000, -0.02118, 0.00000, -0.01772, 0.00000, -0.01477, 0.00000, -0.01203, 0.00000, -0.00964, 0.00000, -0.00758, 0.00000, -0.00583, 0.00000, -0.00437, 0.00000, -0.00322, 0.00000, -0.00225, 0.00000, -0.00149, 0.00000, -0.00093, 0.00000, -0.00052, 0.00000, -0.00026, 0.00000, -0.00011, 0.00000, -0.00003, 0.00000, 0.00000, 0.00000
]
var i = 2
while i < 256 - 2 {
var bitm = 2
var j = 0
while bitm < 256 {
if (i & bitm) != 0 {
j += 1
}
j <<= 1
bitm <<= 1
}
if i < j {
swap(&sampleArray[i], &sampleArray[j])
swap(&sampleArray[i + 1], &sampleArray[j + 1])
}
i += 2
}
Upvotes: 1
Reputation: 47876
One very bad thing in your code:
UnsafeMutablePointer(mutating: sampleArray)
Check the Pointer part of the Using book
Constant Pointers
...
The pointer passed to the function is guaranteed to be valid only for the duration of the function call. Don’t try to persist the pointer and access it after the function has returned.
So, the pointer passed to UnsafeMutablePointer.init(mutating:)
may not be valid after the call of the initializer. Of course the returned pointer may not be valid neither.
You need to declare your sampleArray
as var
and use withUnsafeMutableBufferPointer(_:)
, if you want to use a pointer to Swift Array which is guaranteed to be valid inside the closure:
sampleArray.withUnsafeMutableBufferPointer {bufferPointer in
let sampleArrayPointer = bufferPointer.baseAddress!
for i in stride(from: 2, to: 128-2, by: 2) {
var j: CLong = 0
var bitm: CLong = 2
while bitm < 256 {
if i & bitm != 0 { j += 1 }
j <<= 1
bitm <<= 1
}
if i < j {
// p1 = sampleArray+i;
var p1 = sampleArrayPointer + i
// p2 = sampleArray+j;
var p2 = sampleArrayPointer + j
// temp = *p1;
var temp = p1.pointee
// *(p1++) = *p2;
p1.pointee = p2.pointee
p1 += 1
// *(p2++) = temp;
p2.pointee = temp
p2 += 1
// temp = *p1;
temp = p1.pointee
// *p1 = *p2;
p1.pointee = p2.pointee
// *p2 = temp;
p2.pointee = temp
}
}//eo stride}
}
But as suggested in Codo's answer, you have no need to use pointers in this case.
Upvotes: 2
Reputation: 18998
p1++
in C corresponds to
p1.successor()
or p1.advanced(by: 1)
in Swift
*(p1++)
in C means get the value from the pointer which corresponds to
p1.successor().pointee
in Swift
So rest of the code will be like
if (i < j){
p1 = UnsafeMutablePointer(mutating: sampleArray)+i
p2 = UnsafeMutablePointer(mutating: sampleArray)+j
temp = p1.pointee
/* looks ok up to this point*/
p1.successor().pointee = p2.pointee
p2.successor().pointee = temp
temp = p1.pointee
p1.pointee = p2.pointee
p2.pointee = temp
}
Upvotes: 1