Benzi
Benzi

Reputation: 2459

Confused about behaviour of remainder operator in Swift

I am trying to calculate two random numbers constrained to a particular range using arc4random and the % operator.

Issue with % operator

I am not able to figure out why the compiler is complaining when calculating (x1,y1) when almost the same thing is done for x2,y2 except for using an int literal directly.

Any ideas?

The code sample is:

import Darwin

let w1:Int = 223

// error: Could not find an overload for '%' that accepts the supplied arguments
let (x1,y1) =
(
  arc4random() % w1,
  arc4random() % 345
)




let (x2,y2) =
(
  arc4random() % 223,
  arc4random() % 345
)

Upvotes: 0

Views: 557

Answers (2)

Cezar
Cezar

Reputation: 56362

That's due to Swift's enforcement of type safety.

arc4random() returns a UInt32, while you've declared w as an Int, so a compiler error is thrown. That'd also happen if you had tried to sum or divide w and the result of calling arc4random(), so the behaviour is not exclusive to the remainder operator.

You have a few options, depending on how you intend to use the resulting value of the operation.

You can declare w1 as an UInt32 in the first place:

var w1: UInt32 = 223

Or, you can cast it to an UInt32 before performing the remainder operation:

arc4random() % UInt32(w1)

Finally, you can initialize an Int from the result of the arc4random() call and use it with the Int version of w1

Int(arc4random()) % w1 

Note that this behaviour does not apply to literals.

From the Apple provided iBook:

The rules for combining numeric constants and variables are different from the rules for numeric literals. The literal value 3 can be added directly to the literal value 0.14159, because number literals do not have an explicit type in and of themselves. Their type is inferred only at the point that they are evaluated by the compiler.

That's why you don't see the same problem occur when doing arc4random() % 345.

Upvotes: 2

gaige
gaige

Reputation: 17481

You need to use the same type for both variables, to wit:

let w1:UInt32 = 223

Should solve the problem

The error is because you are trying to use an Int and a UInt32

Upvotes: 0

Related Questions