Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CGFloat: call rintf() when Float and rint() when Double

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?

like image 236
neoneye Avatar asked Dec 18 '25 01:12

neoneye


1 Answers

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.


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!