3

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,

3 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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
    }

3 Comments

i had never heard of successor your code although great doesn't get exactly what i want as every other value should be zero. But it certainly gives me a fighting chance. I will report back thanks
I feel that swap function could be used there somehow
@Sulthan The OP just wanted to convert C pointer to Swift Pointer..If you would go and check the question history
1

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
}

7 Comments

it's preferable to use swap(_:_:)
I have added the input array and what i believe the output should be to the original post. I'm not sure they are matching yet.
I've fixed the compile errors and used swap (as proposed by @AlexanderMomchliov). I've only compared the first about 30 values and they seem to match.
@oldman: The output of my code differs from the one you show in your questions. But so does the output of your C code, which I also run. Interestingly, the output of my Swift code seems to match the output of the C code.
The reference output shown may be generated with for (i = 2; i < 256-2; i += 2) {, not 128-2. Try changing your 128 - 2 to 256 - 2.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.