How to safely floor or ceil a CGFloat to int?

Proud Member picture Proud Member · Aug 16, 2012 · Viewed 34.7k times · Source

I often need to floor or ceil a CGFloat to an int, for calculation of an array index.

The problem I permanently see with floorf(theCGFloat) or ceilf(theCGFloat) is that there can be troubles with floating point inaccuracies.

So what if my CGFloat is 2.0f but internally it is represented as 1.999999999999f or something like that. I do floorf and get 1.0f, which is a float again. And yet I must cast this beast to int which may introduce another problem.

Is there a best practice how to floor or ceil a float to an int such that something like 2.0 would never accidentally get floored to 1 and something like 2.0 would never accidentally get ceiled to 2?

Answer

Suragch picture Suragch · Dec 15, 2015

Swift supplemental answer

I am adding this as a supplemental answer for those who come here looking how to use floor and ceil with a CGFloat (like I did).

var myCGFloat: CGFloat = 3.001
floor(myCGFloat) // 3.0
ceil(myCGFloat) // 4.0

And if an Int is needed, then it can be cast to one.

var myCGFloat: CGFloat = 3.001
Int(floor(myCGFloat)) // 3
Int(ceil(myCGFloat)) // 4

Update

There is no need to use the C floor and ceil functions anymore. You can use the Swift round() with rounding rules.

var myCGFloat: CGFloat = 3.001
myCGFloat.round(.down) // 3.0
myCGFloat.round(.up) // 4.0

If you don't wish to modify the original variables, then use rounded().

Notes

  • Works with both 32 and 64 bit architectures.

See also