TheMortiestMorty
TheMortiestMorty

Reputation: 705

Swift: Why can't I add 2 integers here?

I'm new to Swift. I'm using Swift 3.x in Xcode. After struggling to take input from an outlet, I finally managed to work through most of the errors and now I've come to the strangest thing ever. How can I not sum 2 integers??

The goal: Monte Carlo Integration with Swift/XCode. Pseudocode: I = (interval) * (1/SampleSize) * Sum[f(x)] (from n=1 to n=SampleSize)

The code:

@IBOutlet weak var interval_a: NSNumber!
@IBOutlet weak var interval_b: NSNumber!
@IBOutlet weak var sample_size: NSNumber!


@IBAction func calcMCIntegration(_ sender: Any) {

    let interval_a_int: Int = interval_a.intValue
    let interval_b_int: Int = interval_b.intValue
    let sample_size_int: Int = sample_size.intValue
    var c: Int = 0
    var mc_int: Double = 0.0
    var rand_numb: Int = 0
    var func_sum: Int = 0       

    c = interval_b_int - interval_a_int

    for i in 1...sample_size_int {

        rand_numb = arc4random_uniform(UInt32(c)) + UInt32(interval_a_int)

        function_val = exp(rand_numb)

        func_sum += function_val

    }

    mc_int = c*func_sum/sample_size

    return mc_int

}

Upvotes: 0

Views: 229

Answers (3)

user7014451
user7014451

Reputation:

This is a bit late, and giving attribution to Ted van Gaalen's elegant answer to this question, I converted his Int extension to Swift 3:

extension Int {
    static func random(_ range: Range<Int> ) -> Int
    {
        var offset = 0

        if range.lowerBound < 0   // allow negative ranges
        {
            offset = abs(range.lowerBound)
        }

        let mini = UInt32(range.lowerBound + offset)
        let maxi = UInt32(range.upperBound   + offset)

        return Int(mini + arc4random_uniform(maxi - mini)) - offset
    }
}

The usage changes more than the extension actually, but in this case it would be:

@IBAction func calcMCIntegration(_ sender: Any) {
    let interval_a_int: Int = interval_a.intValue
    let interval_b_int: Int = interval_b.intValue
    let sample_size_int: Int = sample_size.intValue
    var c: Int = 0
    var mc_int: Double = 0.0
    var rand_numb: Int = 0
    var func_sum: Int = 0

    c = interval_b_int - interval_a_int
    for i in 1...sample_size_int {
        rand_numb = Int.random(Range(c...interval_a_int))
        function_val = exp(rand_numb)
        func_sum += function_val
    }
    mc_int = c*func_sum/sample_size
    return mc_int
}

Upvotes: 0

jlasierra
jlasierra

Reputation: 1106

How others are saying, the message is a bit tricky.

The sum of two UInt32 will genearate another UInt32. You can't assign it to an Int variable.

Change the type of the variable, or cast the sum result.

In your case:

 rand_numb = Int(arc4random_uniform(UInt32(c))) + interval_a_int

Upvotes: 2

Duncan C
Duncan C

Reputation: 131418

I've found that Swift error messages can be worthless, or even actively misleading. Ignore the specific message. You have to figure out what's wrong yourself.

If c, rand_numb, and interval_a_int are all type Int then your code should compile. I tried various permutations of those values being different types and could not get the error message you are showing, but when all of them are type Int, it compiles. Check the type of all 3 of those variables/constants carefully.

Upvotes: 2

Related Questions