3

When architecture is 32 bit then CGFloat is Float. In this case I would like to invoke rintf()

When architecture is 64 bit then CGFloat is Double. In this case I would like to invoke rint()

I currently do a cast to Double and then invoke rint()

func roundToNearestCell(coordinate: CGFloat) -> CGFloat {
    let cellSize = 10.0
    return cellSize * CGFloat(rint(Double(coordinate / cellSize)))
}

Perhaps generics can handle both cases nicely?

neoneye
  • 50,398
  • 25
  • 166
  • 151

1 Answers1

2

This works, although having to switch on the parameter type and provide a default case is grody.

func round<T: FloatingPointNumber>(value: T) -> T {
  switch value {
  case let value as Float:
    return rintf(value) as T
  case let value as Double:
    return rint(value) as T
  default:
    return 0.0 as T
  }
}

I don't think generics work well when you need to take a different action depending on the type of item that's passed in. In this case, I would use extensions and let polymorphism do its thing:

protocol Roundable {
  typealias NumberType
  func Round() -> NumberType
}

extension Float: Roundable {
  func Round() -> Float {
    return rintf(self)
  }
}

extension Double: Roundable {
  func Round() -> Double {
    return rint(self)
  }
}

The protocol definition is optional, but it seems to be Swiftian.

jatoben
  • 3,079
  • 15
  • 12