keegan3d - 1 year ago 87

Swift Question

I'm trying to wrap my head around the ins and outs of Swift generics and make some common math functions. I'm trying to implement a

`mod`

Here's what my

`mod`

`func mod<N: NumericType, I: IntegerType>(_ x: N, _ y: I) -> N {`

return x - y * floor(x/y)

}

But I'm getting this error:

`error: binary operator '/' cannot be applied to operands of type 'N' and 'I'`

return x - y * floor(x/y)

And here's my

`NumericType`

`protocol NumericType: Comparable {`

static func +(lhs: Self, rhs: Self) -> Self

static func -(lhs: Self, rhs: Self) -> Self

static func *(lhs: Self, rhs: Self) -> Self

static func /(lhs: Self, rhs: Self) -> Self

static func %(lhs: Self, rhs: Self) -> Self

}

protocol DecimalType: NumericType {

init(_ v: Double)

}

protocol IntegerType: NumericType {

init(_ v: Int)

}

extension CGFloat : DecimalType { }

extension Double : DecimalType { }

extension Float : DecimalType { }

extension Int : IntegerType { }

extension Int8 : IntegerType { }

extension Int16 : IntegerType { }

extension Int32 : IntegerType { }

extension Int64 : IntegerType { }

extension UInt : IntegerType { }

extension UInt8 : IntegerType { }

extension UInt16 : IntegerType { }

extension UInt32 : IntegerType { }

extension UInt64 : IntegerType { }

Answer Source

As of Swift 3, all floating point types conform to `FloatingPoint`

,
and all integer types conform to `Integer`

.
Both protocols define the basic arithmetic operations like +,-,*,/.
Also the `floor()`

function is defined for `FloatingPoint`

arguments.

Therefore in your case I would define *two* implementations, one for
integers and one for floating point values:

```
func mod<N: Integer>(_ x: N, _ y: N) -> N {
return x - y * (x/y) // or just: return x % y
}
func mod<N: FloatingPoint>(_ x: N, _ y: N) -> N {
return x - y * floor(x/y)
}
```

`FloatingPoint`

has also a `truncatingRemainder`

method,
`a.truncatingRemainder(b)`

is the "floating point equivalent"
to `a % b`

for integers. It gives the
gives the same result as your `mod`

function if both
operands have the same sign.