Round up a CGFloat in Swift Round up a CGFloat in Swift swift swift

Round up a CGFloat in Swift


Update: Apple have now defined some CGFloat-specific versions of common functions like ceil:

func ceil(x: CGFloat) -> CGFloat

...specifically to cope with the 32/64-bit difference. If you simply use ceil with a CGFloat argument it should now work on all architectures.

My original answer:

This is pretty horrible, I think, but can anyone think of a better way? #if doesn't seem to work for CGFLOAT_IS_DOUBLE; I think you're limited to build configurations, from what I can see in the documentation for conditional compilation.

var x = CGFloat(0.5)#if arch(x86_64) || arch(arm64)var test = ceil(x)#elsevar test = ceilf(x)#endif


With Swift 5, you can choose one of the 3 following paths in order to round up a CGFloat.


#1. Using CGFloat's rounded(_:) method

FloatingPoint protocol gives types that conform to it a rounded(_:) method. CGFloat's rounded(_:) has the following declaration:

func rounded(_ rule: FloatingPointRoundingRule) -> CGFloat

Returns this value rounded to an integral value using the specified rounding rule.

The Playground sample code below shows how to use rounded(_:) in order to round up a CGFloat value:

import CoreGraphicslet value1: CGFloat = -0.4let value2: CGFloat = -0.5let value3: CGFloat = -1let value4: CGFloat = 0.4let value5: CGFloat = 0.5let value6: CGFloat = 1let roundedValue1 = value1.rounded(.up)let roundedValue2 = value2.rounded(.up)let roundedValue3 = value3.rounded(.up)let roundedValue4 = value4.rounded(.up)let roundedValue5 = value5.rounded(.up)let roundedValue6 = value6.rounded(.up)print(roundedValue1) // prints -0.0print(roundedValue2) // prints -0.0print(roundedValue3) // prints -1.0print(roundedValue4) // prints 1.0print(roundedValue5) // prints 1.0print(roundedValue6) // prints 1.0

#2. Using ceil(_:) function

Darwin provides a ceil(_:) function that has the following declaration:

func ceil<T>(_ x: T) -> T where T : FloatingPoint

The Playground code below shows how to use ceil(_:) in order to round up a CGFloat value:

import CoreGraphicslet value1: CGFloat = -0.4let value2: CGFloat = -0.5let value3: CGFloat = -1let value4: CGFloat = 0.4let value5: CGFloat = 0.5let value6: CGFloat = 1let roundedValue1 = ceil(value1)let roundedValue2 = ceil(value2)let roundedValue3 = ceil(value3)let roundedValue4 = ceil(value4)let roundedValue5 = ceil(value5)let roundedValue6 = ceil(value6)print(roundedValue1) // prints -0.0print(roundedValue2) // prints -0.0print(roundedValue3) // prints -1.0print(roundedValue4) // prints 1.0print(roundedValue5) // prints 1.0print(roundedValue6) // prints 1.0

#3. Using NumberFormatter

If you want to round up a CGFloat and format it with style in the same operation, you may use NumberFormatter.

import Foundationimport CoreGraphicslet value1: CGFloat = -0.4let value2: CGFloat = -0.5let value3: CGFloat = -1let value4: CGFloat = 0.4let value5: CGFloat = 0.5let value6: CGFloat = 1let formatter = NumberFormatter()formatter.numberStyle = NumberFormatter.Style.decimalformatter.roundingMode = NumberFormatter.RoundingMode.ceilingformatter.maximumFractionDigits = 0let roundedValue1 = formatter.string(for: value1)let roundedValue2 = formatter.string(for: value2)let roundedValue3 = formatter.string(for: value3)let roundedValue4 = formatter.string(for: value4)let roundedValue5 = formatter.string(for: value5)let roundedValue6 = formatter.string(for: value6)print(String(describing: roundedValue1)) // prints Optional("-0")print(String(describing: roundedValue2)) // prints Optional("-0")print(String(describing: roundedValue3)) // prints Optional("-1")print(String(describing: roundedValue4)) // prints Optional("1")print(String(describing: roundedValue5)) // prints Optional("1")print(String(describing: roundedValue6)) // prints Optional("1")


The most correct syntax would probably be:

var f: CGFloat = 2.5var roundedF = CGFloat(ceil(Double(f)))

To use ceil I will first make the CGFloat a Double and after ceiling, I convert it back to CGFloat.

That works when CGFloat is defined either as CFloat or CDouble.

You could also define a ceil for floats (This has been actually implemented in Swift 2):

func ceil(f: CFloat) -> CFloat {   return ceilf(f)}

Then you will be able to call directly

var roundedF: CGFloat = ceil(f)

while preserving type safety.

I actually believe this should be the solution chosen by Apple, instead of having separate ceil and ceilf functions because they don't make sense in Swift.