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
function, but not quite sure the best way to get it working using generics.
Here's what my mod
function looks like:
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
declaration for decimal and integer type numbers:
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 { }
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With